闪亮的 DT 无法添加按钮以下载为 csv/excel

Shiny DT unable to add buttons to download as csv/excel

将“下载为 csv/excel”按钮添加到我的 Shiny 应用数据表部分时遇到问题。 看来我的“数据”是从 redshift 查询的,它没有将其识别为数据框。

抛出错误: 'data' 必须是二维的(例如数据框或矩阵)

从该文档看来 return 它是一个与错误消息相矛盾的数据框。知道如何解决这个问题并让按钮正常工作吗?

server <- function(input, output) {
  
  observeEvent(input$executeSQL, {
    if (input$selection == "CL7D") {
      output$mytable = DT::renderDataTable({ 
        dbGetQuery(conn, "select * from dummy")
        extensions = "Buttons" 
        options = list(paging = TRUE,
                       scrollX=TRUE, 
                       searching = TRUE,
                       ordering = TRUE,
                       dom = 'Bfrtip',
                       buttons = c('copy', 'csv', 'excel', 'pdf'),
                       pageLength=5, 
                       lengthMenu=c(3,5,10) )
      })
    }
    
  })
}

你对 renderDataTable 的第一个参数确实是一个表达式,它应该是,但是......你的表达式没有做太多。

  1. 首先,它从 dbGetQuery 检索一些数据,但由于它没有存储在任何地方,因此立即丢失。
  2. 然后创建一个名为extensions的局部变量并赋值为"Buttons".
  3. 最后,它创建了一个名为 options 的局部变量,即 list(..)

由于 R 中的默认行为是针对带有 { ... } 的表达式是将它“return”作为其中的最后一个表达式,这意味着它不会 return来自 dbGetQuery 的值,它不是 return extensions,而是 return options 的值,它不是二维的。

也许你的意思是:

  observeEvent(input$executeSQL, {
    if (input$selection == "CL7D") {
      output$mytable = DT::renderDataTable(        # remove the '{'
        dbGetQuery(conn, "select * from dummy"),   # add a ','
        extensions = "Buttons",                   # add a ','
        options = list(paging = TRUE,
                       scrollX=TRUE, 
                       searching = TRUE,
                       ordering = TRUE,
                       dom = 'Bfrtip',
                       buttons = c('copy', 'csv', 'excel', 'pdf'),
                       pageLength=5, 
                       lengthMenu=c(3,5,10) )
      )                                            # remove the '}'
    }
    
  })

旁注:

  1. 我倾向于将 data-creating/querying 操作保持为简单的 reactive 组件,然后可以在其他地方使用。例如,假设您想要在闪亮的应用程序顶部显示横幅以显示行数 returned。使用您当前的代码,您需要 运行 dbGetQuery 两次 .

    相反,让它成为反应式的,然后再使用它;这样,如果您需要将数据用于您闪亮的应用程序中的任何其他组件,您可以单独使用它。

      mydata <- eventReactive(input$executeSQL, {
        dbGetQuery(conn, "select * from dummy")
      })
      observeEvent(mydata(), {
        if (input$selection == "CL7D") {
          output$mytable = DT::renderDataTable(
            mydata(),
            extensions = "Buttons",
            options = list(paging = TRUE,
                           scrollX=TRUE, 
                           searching = TRUE,
                           ordering = TRUE,
                           dom = 'Bfrtip',
                           buttons = c('copy', 'csv', 'excel', 'pdf'),
                           pageLength=5, 
                           lengthMenu=c(3,5,10) )
          )
        }
    
      })
    
  2. 我还没有看到一个 shiny 的工作示例,其中将反应组件嵌套在另一个组件中是有意义的。我没有在这里测试你的代码(缺少数据和 ui 等),但我怀疑你的代码会运行得更好,more-cleanly as

      mydata <- eventReactive(input$executeSQL, {
        dbGetQuery(conn, "select * from dummy")
      })
      output$mytable <- DT::renderDataTable(
        if (input$selection == "CL7D") mydata(),
        extensions = "Buttons",
        options = list(paging = TRUE,
                           scrollX=TRUE, 
                           searching = TRUE,
                           ordering = TRUE,
                           dom = 'Bfrtip',
                           buttons = c('copy', 'csv', 'excel', 'pdf'),
                           pageLength=5, 
                           lengthMenu=c(3,5,10) )
          )
    

    如果这不起作用,请将 if 条件移出,

      mydata <- eventReactive(input$executeSQL, {
        dbGetQuery(conn, "select * from dummy")
      })
      data_CL7D <- reactive({
        if (input$selection == "CL7D") mydata()
      })
      output$mytable <- DT::renderDataTable(
        data_CL7D(),
        extensions = "Buttons",
        options = list(paging = TRUE,
                           scrollX=TRUE, 
                           searching = TRUE,
                           ordering = TRUE,
                           dom = 'Bfrtip',
                           buttons = c('copy', 'csv', 'excel', 'pdf'),
                           pageLength=5, 
                           lengthMenu=c(3,5,10) )
          )