[英]Shiny - renderDataTable - bSearchable vs checkboxInput
I´m having problems combining two features while building a data table: 建立数据表时,我在合并两个功能时遇到问题:
Both work separately, but not together. 两者都是分开工作的,但不能一起工作。 If I uncheck a column in my menu input, the data disappears - like applying a filter and no data was found. 如果取消选中菜单输入中的一列,数据将消失-就像应用过滤器一样,未找到任何数据。 How can I fix this? 我怎样才能解决这个问题?
library(shiny)
runApp(list(ui=(fluidPage(
pageWithSidebar(
headerPanel('Title'),
sidebarPanel(
helpText('Text about the table'),
checkboxInput('columns','I want to select the columns' , value = FALSE),
conditionalPanel(
condition= "input.columns == true",
checkboxGroupInput('show_vars', 'Select the columns that you want to see:', names(iris[1:4]),
selected = names(iris[1:4]))
),
downloadButton('downloadData', 'Download'),width = 3
),
mainPanel(
tags$head(tags$style("tfoot {display: table-header-group;}")),
dataTableOutput("mytable1"),width = 9
)
))
)
,
server=(function(input, output) {
library(ggplot2)
library(XLConnect)
#DATA
tabel<- reactive({
iris[,c(input$show_vars,"Species"), drop = FALSE]
})
# OUTPUT
output$mytable1 = renderDataTable({
tabel()},
options = list(
aoColumns = list(list(bSearchable = FALSE), list(bSearchable = FALSE),list(bSearchable = FALSE),
list(bSearchable = FALSE),list(bSearchable = TRUE)),
bFilter=1, bSortClasses = 1,aLengthMenu = list(c(10,25,50, -1), list('10','25', '50', 'Todas')),iDisplayLength = 10
)
)
output$downloadData <- downloadHandler(
filename = function() { paste('tabela_PSU','.xlsx', sep='') },
content = function(file){
fname <- paste(file,"xlsx",sep=".")
wb <- loadWorkbook(fname, create = TRUE)
createSheet(wb, name = "Sheet1")
writeWorksheet(wb, tabel(), sheet = "Sheet1")
saveWorkbook(wb)
file.rename(fname,file)
},
)
})
))
The problem is by filtering the data iris
based on input$show_vars
, you are changing the number of columns of the DataTable. 问题是通过更改基于input$show_vars
的数据iris
,您正在更改DataTable的列数。 However, you have defined a fixed aoColumns
option, which implies your DataTable has five columns (four non-searchable, one searchable). 但是,您已经定义了一个固定的 aoColumns
选项,这意味着您的DataTable具有五列(四列不可搜索,一列可搜索)。
Therefore, when you deselect any checkbox inputs, the filtered data doesn't match the specified options. 因此,当取消选择任何复选框输入时,过滤的数据与指定的选项不匹配。 As a result, nothing is displayed. 结果,什么也不显示。
That is, although your data in the DataTable is reactive , the options, however, are NOT reactive . 也就是说,尽管您在DataTable中的数据是反应性的,但是选项不是反应性的 。
If you read the renderDataTable
's document carefully, you will see that you can pass two types of variables to the options
argument: 如果您仔细阅读renderDataTable
的文档 ,将会看到可以将两种类型的变量传递给options
参数:
options A list of initialization options to be passed to DataTables, or a function to return such a list. options传递给DataTables的初始化选项的列表,或者返回该列表的函数。
The differences are: 不同之处在于:
options
as a list, Shiny assumes that the options
are fixed; 如果您将options
指定为列表,Shiny会假定options
是固定的; But since you are dynamically filtering the data based on input$show_vars
, you should dynamically change the options for aoColumns
as well. 但是,由于要基于input$show_vars
动态过滤数据,因此也应该动态更改aoColumns
的选项。 options
, Shiny will know that the options
are also reactive. 如果将函数作为options
的参数传递,Shiny将知道这些options
也是反应性的。 Hence Shiny will also update the options
when the data (in your case, the data.frame
encapsulated in the reactive variable named tabel
) updates. 因此闪亮还将更新options
时的数据(在你的情况下, data.frame
中的反应变量命名封装tabel
更新)。 You may already know that reactive variables are themselves functions . 您可能已经知道, 反应变量本身就是函数 。 They are evaluated in a reactive environment and when evaluated, they return the current state/value of the data. 在反应性环境中对它们进行评估,并在评估时返回数据的当前状态/值。 This is why you pass tabel()
instead of tabel
to renderDataTable
. 这就是为什么您将tabel()
而不是tabel
给renderDataTable
。
The solution then, is to wrap the entire options
list into a reactive variable (hence a function as well). 然后,解决方案是将整个options
列表包装到一个反应变量中(因此也有一个函数)。 Specifically, we want to dynmaically set the aoColumns
option so that the number of bSearchable
toggles matches the number of columns shown in the DataTable. 具体来说,我们要动态设置aoColumns
选项,以便bSearchable
切换次数与DataTable中显示的列数匹配。
Below I only show the updated server
part, since there's nothing needs to be changed in the UI part. 下面,我仅显示更新的server
部分,因为在UI部分中无需更改任何内容。
shinyServer(function(input, output) {
library(ggplot2)
library(XLConnect)
#DATA
tabel<- reactive({
iris[,c(input$show_vars,"Species"), drop = FALSE]
})
# wrap the `options` into a reactive variable (hence a function) so that it will
# be evaluated dynamically when the data changes as well.
# `dt_options` is reactive in the sense that it will reflect the number of rows
# visible based on the checkboxInput selections.
dt_options <- reactive({
# dynamically create options for `aoColumns` depending on how many columns are selected.
toggles <- lapply(1:length(input$show_vars), function(x) list(bSearchable = F))
# for `species` columns
toggles[[length(toggles) + 1]] <- list(bSearchable = T)
list(
aoColumns = toggles,
bFilter = 1, bSortClasses = 1,
aLengthMenu = list(c(10,25,50, -1), list('10','25', '50', 'Todas')),
iDisplayLength = 10
)
})
# OUTPUT
output$mytable1 = renderDataTable({
tabel()},
options = dt_options
)
output$downloadData <- downloadHandler(
filename = function() { paste('tabela_PSU','.xlsx', sep='') },
content = function(file){
fname <- paste(file,"xlsx",sep=".")
wb <- loadWorkbook(fname, create = TRUE)
createSheet(wb, name = "Sheet1")
writeWorksheet(wb, tabel(), sheet = "Sheet1")
saveWorkbook(wb)
file.rename(fname,file)
},
)
})
(Note that I separate the UI part and server part into ui.R
and server.R
.) (请注意,我将UI部分和服务器部分分为ui.R
和server.R
。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.