R Shiny:根据输入字段中的值调用文件

RShiny: Call file based on value in input field

我想根据用户的输入在我的应用中使用不同的数据集。

假设我有这些文件:

AA.csv 
AB.csv
AC.csv 

是否可以制定一个条件语句,根据用户在输入栏中的选择改变要调用的文件名?

为了便于说明,我附上了一些我想要的行为代码。

ui<- fluidPage(
  selectInput(inputId="file", label= "File",
              choices = c("AA", "AB", "AC"))
)
server<- function(input, output,session){

datafile<- reactive({read.csv("input$file".csv })

我希望我的问题很清楚。

第一步是您的 read.csv 代码应该类似于

datafile <- reactive({ read.csv(paste0(input$file, ".csv")) })

两种方法可以使它变得更好:

  1. 添加req,这样丢失(错位)的文件不会产生错误,只是缺少数据;和
  2. 使这个 动态 以便您的项目可以包含任意数据文件列表,并且您可以添加文件而不必编辑代码来更改 selectInput.

如果您只关心在应用程序启动时检查可用文件,那么这也许就足够了:

files <- list.files("./data", pattern = "\.csv$", full.names = TRUE)
choices <- setNames(files, tools:::file_path_sans_ext(basename(files)))
shinyApp(
  ui = fluidPage(
    selectInput("file", "File", choices = choices, selectize = FALSE),
    textAreaInput("txtarea", "File top 10 lines:", rows = 10)
  ),
  server = function(input, output, session) {
    somedata <- reactive({
      req(input$file)
      readLines(input$file, n = 10)
    })
    observeEvent(somedata(), {
      updateTextAreaInput(session, "txtarea", value = somedata())
    })
  }
)

(我使用 textAreaInput 只是为了显示文件内容...假设您有不同的需求,那么您可能不需要 observeEvent 来更新该输入字段。)

如果这是一个“long-running”应用程序,需要在不重新启动的情况下对新文件做出反应,那么您可以设置一个“轮询”,它会定期更新可用文件列表以供输入。虽然这是为了针对新文件进行调整,但它也会对已删除的文件做出反应。

shinyApp(
  ui = fluidPage(
    selectInput("file", "File", choices = c(), selectize = FALSE),
    textAreaInput("txtarea", "File top 10 lines:", rows = 10)
  ),
  server = function(input, output, session) {
    observe({
      invalidateLater(30000, session) # 30 seconds
      sel <- input$file
      files <- list.files("./data", pattern = "\.csv$", full.names = TRUE)
      choices <- setNames(files, tools:::file_path_sans_ext(basename(files)))
      if (!sel %in% choices) sel <- choices[1]
      updateSelectInput(session, "file", choices = choices, selected = sel)
    })
    somedata <- reactive({
      req(input$file)
      readLines(input$file, n = 10)
    })
    observeEvent(somedata(), {
      updateTextAreaInput(session, "txtarea", value = somedata())
    })
  }
)

第二个应用程序从零选择 (c()) 开始并立即更新它们。我设置了一个 30 秒的民意调查;你的 use-case 会指示一些更合理的东西,认识到 sub-second 响应可能会危及不必要的文件系统访问,显然需要 file-reactivity.

我做了一个快速测试设置:

# setup
dir.create("data")
writeLines("hello world", "./data/AA.csv")
writeLines("hello world again", "./data/AB.csv")