drmariod drmariod - 17 days ago 7
R Question

keep selected rows when changing dataset in shiny DT datatable

I am using the

DT
package to display a data table in my
shiny
app. Since I provide different data sets, I have radio buttons to select them and the data table updates automatically.

What I would like to do is to preselect the available rows from
df1
in
df2
when switching the datasets. At the moment, my selection always get erased. When I try to save the selected rows (uncomment the two rows), my table get reset directly.

library(shiny)
library(DT)

df1 <- data.frame(names=letters,
values=1:26)
df2 <- data.frame(names=letters,
values=(1:26)*2)[seq(1,26,2),]

ui <- shinyUI(
fluidPage(
sidebarLayout(
sidebarPanel(
radioButtons("dataset", label=h5("Select dataset"),
choices=list("df1"='df1',
"df2"='df2'),
selected='df1', inline=TRUE)
),
mainPanel(
DT::dataTableOutput("name_table")
)
)
)
)


Server side...

server <- function(input, output, session) {
getDataset <- reactive({
result <- list()
result[['dataset']] <- switch(input$dataset,
'df1'=df1,
'df2'=df2)
# result[['selection']] <-
# as.numeric(input$name_table_rows_selected)
return(result)
})
output$name_table <- DT::renderDataTable({
DT::datatable(getDataset()[['dataset']],
options=list(pageLength=5))

})
name_proxy = DT::dataTableProxy('name_table')
}

shinyApp(ui, server)


I used the
DT
table, since I need the proxy and some interaction with the data table.

Answer

You can save selected rows only when going to change df like

server <- function(input, output, session) {
  dd=reactiveValues(select=NULL)

  observeEvent(input$dataset,{
    dd$select=as.numeric(isolate(input$name_table_rows_selected))
   })

  getDataset <- reactive({
    result <- list()
    result[['dataset']] <- switch(input$dataset,
                                  'df1'=df1,
                                  'df2'=df2)

    return(result)
  })
  output$name_table <- DT::renderDataTable({
    DT::datatable(getDataset()[['dataset']],
                  options=list(pageLength=5),
                  selection = list(mode = 'multiple', selected =dd$select  )
    )

  })
  name_proxy = DT::dataTableProxy('name_table')
}

shinyApp(ui, server)

Or a bit modification of @drmariod variant: use eventReactive instead of reactive

server <- function(input, output, session) {
  getDataset <- eventReactive(input$dataset,{
    result <- list()
    result[['dataset']] <- switch(input$dataset,
                                  'df1'=df1,
                                  'df2'=df2)
    result[['selection']] <- testing()
    return(result)
  })
  testing <- function() {
    list(selected=as.numeric(input$name_table_rows_selected))
  } 
  output$name_table <- DT::renderDataTable({
    DT::datatable(getDataset()[['dataset']],
                  options=list(pageLength=5),
                  selection=getDataset()[['selection']])

  })
  name_proxy = DT::dataTableProxy('name_table')
}