Возникли проблемы с добавлением кнопок «загрузить как csv/excel» в раздел DataTable моего приложения Shiny. Кажется, что, поскольку мои «данные» запрашиваются из красного смещения, они не распознают их как фрейм данных.
Ошибка: «данные» должны быть двумерными (например, фрейм данных или матрица)
Из этого документа кажется, что он возвращает его как фрейм данных, который противоречит сообщению об ошибке. Любая идея, как я могу исправить это и заставить кнопки работать?
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
действительно является выражением, как и должно быть, но... ваше выражение мало что делает.
dbGetQuery
, но так как они нигде не хранятся, то тут же теряются.extensions
и присваивает ей значение "Buttons"
.options
, то есть list(..)
.Поскольку поведение по умолчанию в R для выражения с { ... }
заключается в том, что оно «возвращает» последнее выражение внутри него, это означает, что оно не возвращает значение из dbGetQuery
, оно не возвращает extensions
, вместо этого оно возвращает значение 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 '}'
}
})
Боковые примечания:
Я предпочитаю, чтобы действия по созданию/запросу данных были простыми reactive
компонентами, которые затем можно было бы использовать в других местах. Например, допустим, вы хотите, чтобы баннер в верхней части вашего блестящего приложения отображал количество возвращенных строк. С вашим текущим кодом вам нужно будет запустить 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) )
)
}
})
Я еще не видел ни одного рабочего примера shiny
, где реактивный компонент, вложенный в другой, имеет смысл. Я не тестировал ваш код здесь (отсутствуют данные, пользовательский интерфейс и т. д.), но я подозреваю, что ваш код будет работать лучше, чище, чем
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) )
)