使用downloadHandler时如何修复“找不到文件”?

时间:2019-08-14 10:59:39

标签: r shiny

我刚刚开始玩转光泽,并制作了一个简单的应用程序,该应用程序读取CSV文件并用标记替换一列的行。我希望用户能够将标记化的数据下载为CSV文件。

为此,我正在使用downloadHandler()函数。我一直在寻找此功能的文档,以及此处的类似问题,但找不到解决方案。我尝试按照其他类似问题的建议从外部运行该应用程序。

app.R

# Only run examples in interactive R sessions
if (interactive()) {

  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),
        textInput(inputId = 'variable', label = 'Name of variable to pseudonymize', placeholder = 'e.g., ID_PA'),
        helpText("Case sensitive!"),
        downloadButton('downloadData', 'Download')
      ),
      mainPanel(
        tableOutput("contents"),
        br(), br(),
        tableOutput('results')
      )
    )
  )

  server <- function(input, output) {
    output$contents <- renderTable({
      # 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.
      inFile <- input$file1

      if (is.null(inFile))
        return(NULL)

      head(read.csv(inFile$datapath, header = input$header))

    })

    output$results <- renderTable({
      # 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.
      inFile <- input$file1

      if (is.null(inFile))
        return(NULL)

      df <- read.csv(inFile$datapath)

      # make sure to use utils::read_csv to read in data

      #  Function generates a lookup table that associates each unique identifier to an PSN. See lillemets
      get_lookup_table <- function(data, id.var, key.length) {
        if (any(duplicated(data[, id.var]))) warning('Duplicate id values in data. For longitudinal dataset, this is expected')
        PSN <- c(1,1) # Allow the while loop to begin
        while (any(duplicated(PSN))) { # Loop until all keys are unique
          PSN <- replicate(length(unique(data[, id.var])),
                           paste(sample(c(LETTERS, 0:9), key.length, replace = T), collapse = ''))
        }
        lookup.table <- data.frame(id = unique(data[, id.var]), key = PSN)
        return(lookup.table)
      }

      # Replace names with PSN
      add_PSN <- function(data, id.var, lookup.table) {
        data[, id.var] <- lookup.table[, 'key'][match(data[, id.var], lookup.table[, 'id'])]
        return(data)
      }

      lookup_table <- get_lookup_table(df, input$variable, 10)

      # Replace names with PSN
      pseudo_df <- add_PSN(df, input$variable, lookup_table)
      head(pseudo_df)


    })


    # Download file
    output$downloadData <- downloadHandler(
      filename = function() {
        paste("data-", Sys.Date(), ".csv", sep="")
      },
      content = function(file) {
        write.csv(pseudo_df, file)
      }
    )
  }

  shinyApp(ui, server)
}

运行该应用程序并单击下载时,出现浏览器错误“找不到文件”。 在R控制台中,我得到警告:Error in is.data.frame: object 'pseudo_df' not found

对此问题发表评论将不胜感激。

1 个答案:

答案 0 :(得分:1)

下载处理程序不知道pseudo_df数据帧已创建。您可能想让一个反应堆构成数据框架,然后将单独的renderdownload处理程序调用创建数据框架的反应堆。例如

make_df <- reactive({})  # code that makes the data frame goes here
output$results <- renderTable({make_df()})
output$downloadData <- downloadHandler(
  filename = function() {
    paste("data-", Sys.Date(), ".csv", sep="")
  },
  content = function(file) {
    write.csv(make_df(), file) # notice the call to the reactive again
  }
)