我找到了一个非常有用的答案here,这几乎就是我所需要的。
这种在DataTable中嵌入selectInput
的解决方案效果很好,但对于那些有很多行的解决方案却不行。
问题是函数shinyInput()
使用的for
循环无法跟上行数大于1000的表。这会使表运行得太慢。
生成这么多输入对象需要时间。我需要在之后触发SQL UPDATE
语句,但这是另一个问题。
有没有办法让这个运行更快,可能是在用户点击页面时动态生成输入对象?
另一个问题是,当表最终加载所有嵌入对象时,如果您尝试更改其中一个selectInput
,您会注意到该表需要很长时间才能赶上。 / p>
请参阅此示例应用:
library(shiny)
library(DT)
DF = matrix(round(rnorm(1000000, mean = 0, sd = 1), 2), ncol = 50)
runApp(list(
ui = basicPage(
h2('A large dataset'),
DT::dataTableOutput('mytable'),
h2("Selected"),
tableOutput("checked")
),
server = function(input, output) {
# Helper function for making checkbox
shinyInput = function(FUN, len, id, ...) {
inputs = character(len)
for (i in seq_len(len)) {
inputs[i] = as.character(FUN(paste0(id, i), label = NULL, ...))
print(i)
}
inputs
}
# Helper function for reading checkbox
shinyValue = function(id, len) {
unlist(lapply(seq_len(len), function(i) {
value = input[[paste0(id, i)]]
if (is.null(value)) NA else value
}))
}
# Create select input objects to embed in table
Rating = shinyInput(selectInput,
nrow(DF),
"selecter_",
choices=1:5,
width="60px")
# Data frame to display
DF_display = data.frame(DF, Rating)
# Datatable with selectInput
output$mytable = DT::renderDataTable(
DF_display,
selection = 'none',
server = FALSE,
escape = FALSE,
options = list(
paging = TRUE,
pageLength = 20,
lengthMenu = c(5, 10, 20, 100, 1000, 10000),
preDrawCallback = JS('function() {
Shiny.unbindAll(this.api().table().node()); }'),
drawCallback = JS('function() {
Shiny.bindAll(this.api().table().node()); } '))
)
# Read select inputs
output$checked <- renderTable({
data.frame(selected = shinyValue("selecter_", nrow(DF)))
})
}
))