R Shiny error - как загрузить загруженный файл после преобразования - PullRequest
1 голос
/ 09 февраля 2020

Я хотел бы иметь возможность загрузить набор данных, выбрать набор столбцов, преобразовать выбранные столбцы (т.е. применить функцию), а затем загрузить измененный файл. Я пытался сделать это с помощью следующего кода:

library(shiny)
library(DT)
library(shinyWidgets)
library(plyr)
library(dplyr)
library(RecordLinkage)
library(readxl)

cleanup <- function(x){
  x <- as.character(x) # convert to character
  x <- tolower(x) # make all lowercase
  x <- trimws(x, "both") # trim white space
  return(x)
}

ui <- fluidPage(
  h2("Record Linkage Data"),
  fileInput("file1", "Upload file for cleaning", accept = c("xls", "csv"), multiple = F),
  actionButton(inputId = "clean", label = "Clean Data"),
  downloadButton("download1", "Download file1"),
  pickerInput(width = "75%",
              inputId = "pick_col1",
              label = "Select columns to display",
              choices = colnames(file1),
              selected = colnames(file1),
              options = list(
                `actions-box` = T,
                `selected-text-format` = paste("count > ", length(colnames(file1)) - 1),
                `count-selected-text` = "Alle",
                liveSearch = T,
                liveSearchPlaceholder = T
              ),

              multiple = T),
  DT::dataTableOutput("mytable")
)

load_path <- function(path) {
    req(input$file)
    ext <- tools::file_ext(path)

    if (ext == "csv"){
      read.csv(path, header = T)
    } else if (ext == "xls" || ext == "xlsx"){
      read_excel(path)
    } else{
      stop("Unknown extension: '.", ext, "'")
    }
}

server <- function(input, output, session){

file1 <- reactive(load_path(input$selection$datapath[[1]]))

#file2 <- reactive(load_path(input$selection$datapath[[2]]))
  eventReactive(input$clean, {
    output$mytable <- DT::renderDataTable({
      data.frame(lapply(select(file1, input$pick_col1), cleanup))
    })


  })

  output$download <- downloadhandler(
    filename = function(){
      paste0(tools::file_path_sans_ext(input$filename), ".csv")

    },

    content = function(file){
      write.csv(data(), file)
    }
  )

}  

shinyApp(ui, server)

Когда я запускаю вышеуказанный код, я получаю сообщение об ошибке: Error in is.data.frame(x) : object 'file1' not found. Я не уверен, почему это так, но я изо всех сил пытался понять, как называть вещи в shiny. Например: я хочу загрузить file1, а затем преобразовать его. Продолжаю ли я ссылаться на file1, когда хочу его скачать? Это может показаться глупым вопросом, но я спрашиваю, потому что я не знаю, и я пытаюсь учиться. Кажется, есть много разных подходов.

Я хотел бы: 1. Загрузить файл 2. Выбрать столбцы (pickerInput - это то, что я пробовал, но selectInput было бы достаточно, я полагаю) 3 с помощью кнопки действия применить предварительно заданную функцию к выбранным столбцам 4. загрузить преобразованный набор данных в виде .csv

1 Ответ

4 голосов
/ 09 февраля 2020

Я столкнулся с некоторыми проблемами

  1. Это очень глупо (это случается со всеми нами). Вы должны написать downloadHandler вместо downloadhandler.
  2. Основная проблема: ваш pickerInput пытается выбрать имена столбцов фрейма данных file1, когда он не существует. Когда вы запускаете приложение, код пытается найти фрейм данных file1 и просмотреть имена его столбцов, но с тех пор вы еще ничего не загрузили, он выдает ошибку.
  3. О том, как вы читать файлы: я не знаком с тем, как вы читаете файлы, я предлагаю вам сделать нечто подобное, чем то, что делается в этом примере. https://shiny.rstudio.com/gallery/file-upload.html. Обратите внимание, что вам нужно использовать функцию read.* и указать результат на другое имя, df в примере.

Как мне решить эту проблему: 1. Установите choices и selected параметры по умолчанию NULL. Должно работать что-то вроде следующего:

  pickerInput(width = "75%",
              inputId = "pick_col1",
              label = "Select columns to display",
              choices = NULL,
              selected = NULL,
              options = list(
                `actions-box` = T,
                # `selected-text-format` = paste("count > ", length(colnames(file1)) - 1),
                `count-selected-text` = "Alle",
                liveSearch = T,
                liveSearchPlaceholder = T
              ),
              multiple = T)
Добавьте updatePickerInput на стороне сервера в observeEvent. Нечто подобное должно работать.
observeEvent(input$file1, {

  req(input$file1) # ensure the value is available before proceeding

  df <- read.csv(input$file1$datapath)

  updatePickerInput(session = session, 
                    inputId = "pick_col1", 
                    choices = colnames(df), 
                    # ... other options) 
})

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

Если это не сработает, дайте мне знать, и я могу попытаться выяснить это

Удачи!

...