首页 > 解决方案 > 将 checkBoxGroup 写入文件并从中读取

问题描述

我创建了一个闪亮的应用程序,其中包括一个checkBoxGroup. 调用时,此元素返回一个带有所选选项的向量。我可以将其写入文件write.table(),它会创建一个 CSV 文件,其中一行如下所示:

Jota 5 5 nature3 5 5 FALSE c("choice1", "choice2", "choice4") property c("choiceA", "choiceB", "ChoiceD", "choiceE", "choiceK") 5 5

但是使用回读这个文件read.table()似乎很棘手,因为它返回

扫描错误(file = file,what = what,sep = sep,quote = quote,dec = dec,:第 9 行没有 12 个参数

我认为read.table()解析 CSV 文件中的向量有困难。除了展平结构并将每个选择变成具有唯一列的单独的 TRUE/FALSE 值之外,还有其他解决方法吗?

编辑:示例应用程序

正如建议的那样,我组装了一个复制问题的虚拟应用程序。它基于 Shiny 的这篇文章。与上面描述的不同,它write.csv()为每个表单提交使用并创建一个新文件,但问题是相同的。

library(shiny)

fields <- c("name", "groupInput")

shinyApp(
  ui = fluidPage(
    textInput("name", "Name", ""),
    checkboxGroupInput("groupInput", "Select from list", choices = c('abc', 'def', 'ghi')),
    actionButton("submit", "Submit"),
    DT::dataTableOutput("responses", width = 300)
  ),
  server = function(input, output, session) {

    formData <- reactive({
      data <- sapply(fields, function(x) input[[x]])
      data
    })

    observeEvent(input$submit, {
      saveData(formData())
    })

    output$responses <- DT::renderDataTable({
      input$submit
      loadData()
    })   

    outputDir <- "responses"

    saveData <- function(data) {
      data <- t(data)
      # Create a unique file name
      fileName <- sprintf("%s_%s.csv", as.integer(Sys.time()), digest::digest(data))
      # Write the file to the local system
      write.csv(
        x = data,
        file = file.path(outputDir, fileName),
        row.names = FALSE, quote = TRUE
      )
    }

    loadData <- function() {
      # Read all the files into a list
      files <- list.files(outputDir, full.names = TRUE)
      data <- lapply(files, read.csv, stringsAsFactors = FALSE) 
      # Concatenate all data together into one data.frame
      data <- do.call(rbind, data)
      data
    }
  }
)

当您运行它并在将存储的 CSV 中选中多个框时,checkBoxGroup如下所示:

 "name","groupInput"
 somename,c("abc", "def", "ghi")

CSV 中向量的存在似乎会导致 中的错误read.csv,即:

Warning: Error in read.table: more columns than column names
Stack trace (innermost first):
    87: read.table
    86: FUN
    85: lapply
    84: loadData [/Users/alexanderjulmer/Code/test-storage/app.R#45]
    83: exprFunc [/Users/alexanderjulmer/Code/test-storage/app.R#25]
    82: widgetFunc
    81: func
    80: origRenderFunc
    79: renderFunc
    78: origRenderFunc
    77: output$responses
     1: runApp

我认为这是因为在 data.frame 中没有正确解析向量,我怀疑这是可能的。所以我认为最好将数据checkBoxGroup分成几列。但是,如何做到这一点?

标签: rshiny

解决方案


听起来您要避免的是为每个可能的checkBoxGroup输入设置一个单独的列-我看到的替代方法是将它们的任何组合视为长度为 1 的元素,以便可以这样读取read.csv。在您的示例应用程序中,如果检查了多个,则检查是一个长度为 3 的列表,并且 read.csv 可以理解地并不真正知道如何处理它。

为了解决这个问题,我的方法是首先取消列出元素,checkBoxGroup然后将元素折叠成字符向量,并将其粘贴到“名称”文本输入中。所有这些都在您的任务中完成formData

formData <- reactive({
  data <- sapply(fields, function(x) input[[x]])
  chks <- unlist(data[[2]])
  data <- c(data[[1]], paste0(chks, collapse=", "))
  data
})

这为您提供了一个包含两列的表格,其中第二列是以逗号分隔的一组复选框输入。(在这里,为了清楚起见,我将该过程分为两个步骤,但是如果您愿意,没有理由不能将它们放入一行代码中。)

但是,我仍然不清楚您打算如何使用您的数据,因此字符串是否对您有用并解决您的最终问题......


推荐阅读