Sni
Sni

Reputation: 25

assign output ID to renderdataTable() objects in lapply in shiny

I have a list which contains several data.frames in same format, with these data.frames I would like to make a tablist to show each of the data.frame as a DT::datatable and a plot out of it in below, the following code works fine:

createTabs <- function(df) {
    tabPanel(
             renderDataTable(df),
             renderPlotly(volcano_plot(df))
    )}

myTabs <- lapply(myList, createTabs)
return(do.call(tabsetPanel,myTabs))

However, this way I did not assign output ID to each of the renderDataTable object, later if I would like to get the user selected rows to do some statistics in the datatable like in this one

How do I get the data from the selected rows of a filtered datatable (DT)?

It will not be possible because I can't get the output id of those datatables, I wonder if there's a way to assign an output ID to each of the datatables when I create then with renderDataTable() already, or is there any other way round?

Upvotes: 1

Views: 687

Answers (1)

Florian
Florian

Reputation: 25415

You could first construct the output objects (so you can name them), and then call them in the creation of your tabsetPanel. Working example:

library(shiny)
library(plotly)

ui <- fluidPage(
  uiOutput('my_tabsetpanel')  

)

server <- function(input, output, session) {

  myList = list('dt_1'= head(mtcars,5), 'dt_2' = head(mtcars,5), 'dt_3'= head(mtcars,5))

  # create the tables
  lapply(seq_along(myList),function(x) {
    output[[names(myList)[x]]] = renderDataTable({myList[[x]]})
  })

  # create the plots
  lapply(seq_along(myList),function(x) {
    output[[paste0(names(myList)[x],'_plot')]] = renderPlotly({plot_ly(myList[[x]],x=~mpg,y=~cyl)})
  })  

  # create tabsetPanel 
  output$my_tabsetpanel <- renderUI({
    myTabs = lapply(seq_along(myList), function(x)
    {
      tabPanel(paste0('mytab',x),
               dataTableOutput(names(myList)[x]),
               plotlyOutput(paste0(names(myList)[x],'_plot')))}
    )
    do.call(tabsetPanel, myTabs)
  })
}

shinyApp(ui, server)

Now you can also call their selected rows, since the datatables are named. If MyList is in fact reactive, you should wrap an observer around the two lapply statements. Hope this helps!

Upvotes: 1

Related Questions