dracodoc dracodoc - 4 years ago 127
R Question

Pre-select rows of a dynamic DT in shiny

This question is the more dynamic version of this.

I have a DT in shiny app that could be empty at initialization. I'd like to pre-select all rows in DT. My first try is like this:

library(shiny)
library(DT)
shinyApp(
ui = fluidPage(
fluidRow(
radioButtons("select", "", c("none", "iris")),
DT::dataTableOutput('x1')
)
),
server = function(input, output, session) {
data <- reactive({
if (input$select == "none") {
return(NULL)
} else if (input$select == "iris"){
return(iris)
}
})
output$x1 = DT::renderDataTable(
data(), server = FALSE,
selection = list(mode = 'multiple', selected = seq_len(nrow(data())))
)
}
)


It did selection right but there is an error of
Warning: Error in seq_len: argument must be coercible to non-negative integer
in the beginning. I think that's because
seq_len
cannot take an
NULL
input. Interestingly after the initialization, switching back and forth doesn't generate new errors.

I tried this version to use an reactive value for rows vector, with empty result for empty input:

library(shiny)
library(DT)
shinyApp(
ui = fluidPage(
fluidRow(
radioButtons("select", "", c("none", "iris")),
DT::dataTableOutput('x1')
)
),
server = function(input, output, session) {
data <- reactive({
if (input$select == "none") {
return(NULL)
} else if (input$select == "iris"){
return(iris)
}
})
all_rows <- reactive({
df <- data()
if (is.null(df)) {
return(seq_len(0))
} else {
return(seq_len(nrow(df)))
}
})
output$x1 = DT::renderDataTable(
data(), server = FALSE,
selection = list(mode = 'multiple', selected = all_rows()))
}
)


However this doesn't work. I tried another version which used a modified
seq_len
but it also doesn't work.

library(shiny)
library(DT)
seq_len_null_check <- function(len){
if (is.null(len)){
return(integer(0))
} else {
return(seq_len(len))
}
}
shinyApp(
ui = fluidPage(
fluidRow(
radioButtons("select", "", c("none", "iris")),
DT::dataTableOutput('x1')
)
),
server = function(input, output, session) {
data <- reactive({
if (input$select == "none") {
return(NULL)
} else if (input$select == "iris"){
return(iris)
}
})
output$x1 = DT::renderDataTable(
data(), server = FALSE,
selection = list(mode = 'multiple', selected = seq_len_null_check(nrow(data())))
)
}
)


How can I remove the error in first version, or make the 2nd, 3rd version work?

Answer Source

To allow reactive on selected evaluation, you need to call datatable from within renderDataTable:

output$x1 = renderDataTable(
              datatable( data(),
                         selection = list(mode = 'multiple', selected = all_rows())), 
              server = FALSE)
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download