闪亮的 downloadHandler 问题 - 不会下载屏幕上显示的过滤数据

Problem with Shiny downloadHandler - Won't Download Filtered Data as Displayed on Screen

我正在尝试将如下所示的相同基本(可重现)代码应用于我的应用程序,正如在这个测试示例中提供的(并使用提供的解决方案)在这个问题上找到的:

我对其进行了一些自定义,以便 table 在呈现时使用 selectInput() 过滤器,而不是显示在数据顶部 table 的过滤器。

问题在于,在引用的 link 中的示例代码以及我的例子中,过滤器都按应有的方式应用于屏幕上的数据 table,但是当通过时通过downloadHandler()它不导出过滤后的数据。它过滤出正确的过滤行,但它不是正确的数据。

我正在努力想出一个解决方案,以便在下载文件时将我打算成为“反应式”应用程序的应用程序应用到 table,以便期望的结果是导出的数据是在应用程序中过滤的实际数据。

library(shiny)
library(DT)
library(ggplot2)


## === LOAD EXAMPLE DATA =====

cars = mtcars


# do I make the data frame reactive?

reactiveDF = reactive(cars)

## ==== UI ====

ui <- fluidPage(
  titlePanel("Basic DataTable"),
  
  # Create a new Row in the UI for selectInputs
  fluidRow(
    column(4,
           selectInput("cyl",
                       "Cylinders:",
                       c("All",
                         unique(sort(as.character(cars$cyl)))))
    ),
    column(4,
           selectInput("gear",
                       "Gears:",
                       c("All",
                         unique(as.character(cars$gear))))
    ),
    column(4,
           selectInput("carb",
                       "Carburators:",
                       c("All",
                         unique(as.character(cars$carb))))
    )
  ),
  # Create a new row for the table.
  
  DT::dataTableOutput("dt"),
  
  p("Notice that the 'rows_all' attribute grabs the row indices of the data."),
  verbatimTextOutput("filtered_row"),
  
  # Create a new row for the download button
  p("The table responds to the filters perfectly, yet it will not download the data. Test it out."),
  p("Evaluate the csv file and you will see that while it extracts the filtered rows,"),
  p("it is not displaying the actual filtered data in the table!"),
  
  downloadButton(outputId = "download_filtered",
                 label = "Download Filtered Data")
)


## ==== END UI ====

## ==== SERVER ====

server = function(input, output){
  
  output$filtered_row <- 
    renderPrint({
      input[["dt_rows_all"]]
    })
  
  # Filter data based on selections
  
  # This controls the 3 filters displayed on top of the datatable
  output$dt <- DT::renderDataTable(datatable({
    cardata <- cars
    # conditionals 
    
    if (input$cyl != "All") {
      cardata <- cardata[cardata$cyl == input$cyl, ]
    }
    if (input$gear != "All") {
      cardata <- cardata[cardata$gear == input$gear, ]
    }
    if (input$carb != "All") {
      cardata <- cardata[cardata$carb == input$carb, ]
    }
    
    # display the filtered data
    cardata
  }))
  
  
  
# Download handler for exporting the data to csv -this won't work as intended -----
  
  output$download_filtered <- 
    downloadHandler(
      filename = "filtered_report.csv",
      content = function(file){
        write.csv(cardata[input[["dt_rows_all"]], ],file)
      }
    )
}

shinyApp(ui,server)

您没有以正确的方式使用反应对象。在 shiny 中,这类对象背后的想法是避免重复自己。在这里您可以创建一个反应对象 reactiveDF 并使用该对象生成 dataTableOutput 和下载 table.

library(shiny)
library(DT)
library(ggplot2)


## === LOAD EXAMPLE DATA =====

cars = mtcars


# do I make the data frame reactive?



## ==== UI ====

ui <- fluidPage(
  titlePanel("Basic DataTable"),
  
  # Create a new Row in the UI for selectInputs
  fluidRow(
    column(4,
           selectInput("cyl",
                       "Cylinders:",
                       c("All",
                         unique(sort(as.character(cars$cyl)))))
    ),
    column(4,
           selectInput("gear",
                       "Gears:",
                       c("All",
                         unique(as.character(cars$gear))))
    ),
    column(4,
           selectInput("carb",
                       "Carburators:",
                       c("All",
                         unique(as.character(cars$carb))))
    )
  ),
  # Create a new row for the table.
  
  DT::dataTableOutput("dt"),
  
  p("Notice that the 'rows_all' attribute grabs the row indices of the data."),
  verbatimTextOutput("filtered_row"),
  
  # Create a new row for the download button
  p("The table responds to the filters perfectly, yet it will not download the data. Test it out."),
  p("Evaluate the csv file and you will see that while it extracts the filtered rows,"),
  p("it is not displaying the actual filtered data in the table!"),
  
  downloadButton(outputId = "download_filtered",
                 label = "Download Filtered Data")
)


## ==== END UI ====

## ==== SERVER ====

server = function(input, output){
  
  
  reactiveDF = reactive({
    cardata <- cars
    # conditionals 
    
    if (input$cyl != "All") {
      cardata <- cardata[cardata$cyl == input$cyl, ]
    }
    if (input$gear != "All") {
      cardata <- cardata[cardata$gear == input$gear, ]
    }
    if (input$carb != "All") {
      cardata <- cardata[cardata$carb == input$carb, ]
    }
    
    # display the filtered data
    cardata
    
    
  })
  
  output$filtered_row <- 
    renderPrint({
      input[["dt_rows_all"]]
    })
  
  # Filter data based on selections
  
  # This controls the 3 filters displayed on top of the datatable
  output$dt <- DT::renderDataTable(datatable({
    reactiveDF()
  }))
  
  
  
  # Download handler for exporting the data to csv -this won't work as intended -----
  
  output$download_filtered <- 
    downloadHandler(
      filename = "filtered_report.csv",
      content = function(file){
        write.csv(reactiveDF(),file)
      }
    )
}

shinyApp(ui,server)