首页 > 解决方案 > 使用 downloadHandler 时如何修复“找不到文件”?

问题描述

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

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

应用程序.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

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

标签: rshiny

解决方案


下载处理程序不知道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
  }
)

推荐阅读