Записать checkBoxGroup в файл и прочитать из него - PullRequest
0 голосов
/ 10 мая 2018

Я создал блестящее приложение, которое включает 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() кажется сложным, так как оно возвращается в

Ошибка сканирования (файл = файл, что = что, sep = sep, цитата = цитата, 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
    }
  }
)

Когда вы запустите его и отметите несколько полей в checkBoxGroup, CSV, который будет сохранен, выглядит следующим образом:

 "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 на несколько столбцов. Но тогда как это сделать?

1 Ответ

0 голосов
/ 12 мая 2018

Звучит так, как будто вы пытаетесь избежать отдельного столбца для каждого возможного ввода 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
})

Это дает вам таблицу из двух столбцов, где второй является разделенным запятыми набором входов флажков. (Здесь я разбил этот процесс на два шага для ясности, но нет причины, по которой вы не можете поместить их в одну строку кода, если хотите.)

Однако мне все еще неясно, как вы собираетесь использовать свои данные, и, следовательно, будет ли строка символов полезна для вас и решит вашу конечную проблему ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...