r - 如何在 Shiny 应用程序中将上传的文件转换为 DataFrame
解决方案
只需设置一个反应块即可为您提供数据:
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
fileInput("file1", "Choose CSV File",
accept = c(
"text/csv",
"text/comma-separated-values,text/plain",
".csv")
),
tags$hr(),
checkboxInput("header", "Header", TRUE)
),
mainPanel(
tableOutput("contents")
)
)
)
server <- function(input, output) {
mydata <- reactive({
# input$file1 will be NULL initially. After the user selects
# and uploads a file, it will be a data frame with 'name',
# 'size', 'type', and 'datapath' columns. The 'datapath'
# column will contain the local filenames where the data can
# be found.
req(input$file1, input$header, file.exists(input$file1$datapath))
read.csv(input$file1$datapath, header = input$header)
})
output$contents <- renderTable({
req(mydata())
mydata()
})
}
shinyApp(ui, server)
现在在任何其他地方你需要用新的东西做点什么data.frame
,只需使用mydata()
. (我唯一的改变是将一些行移动到一个新的反应块中,缩短renderTable
块,并使用req(...)
而不是笨拙的is.null
方法。)
一些附加说明:
- 通常在
shiny
应用程序中,反应块做好一件事可能非常有用,例如“获取数据”、“绘制数据”、“调整/更改数据”。正是这样,我将原来的“读取文件然后渲染它”的单个块分解为“读取文件”(向一个或多个消费者提供数据)和“渲染它”两个块。 这需要与反应性相平衡,这意味着依赖于其他块的块越多,我所说的应用程序组件“过度抖动”的可能性就越大。例如,如果块“B”依赖于“A”,而块“C”同时依赖于“A”和“B”,那么您可能会看到以下更新时间表:
- “A”更新(出于某种原因)
- 基于“A”的“C”更新
- “B”基于“A”更新
- 基于“B”的“C”更新(即,一次更改的两次更新;这会产生用户可见的双重更改,并且对于某些绘图可能包括加倍的有限时间延迟)。
结合两个项目符号:将“读取和渲染”分解为“读取”和“渲染”似乎是合理的。如果您需要处理数据(删除/添加列、过滤行等),
- 如果您从不需要原始/原始数据,那么这种突变可能应该在“读取”阶段完成;
- 如果您想在更改数据的同时引用原始数据,那么您可能需要“读取”、“更新”和“渲染”阶段/代码块;
- 即使您从不需要参考原始数据,如果任何突变依赖于用户定义的值(
selectInput
,numericInput
等),那么您可能应该使用“读取”、“更新”、“渲染”阶段,以便您不要每次用户更改其他字段之一时都不必重新读取数据
推荐阅读
- python - pytorch 中 load_state_dict() 的问题
- python - 如何删除模式
- git - 使用多个 ssh 密钥/github 帐户时出现“找不到存储库”
- safari - 操作系统中出现密码模式时 Azure AD 登录弹出窗口未关闭
- css - 可以在 CSS 文件中使用 Jinja 吗?
- javascript - Google Tag Manager - 自定义 javascript 来提取 dataLayer 变量
- makefile - GNU make 重新启动时是否可以保留变量内容?
- kotlin - 在 Fragment 中获取 NavHost
- wget - 使用 wget/curl 下载 Google Drive Link
- pine-script - pine SCRIPT strategy.entry 限制参数未设置