rendering list of tibbles to multiple tables

Hi everyone,

As a newcomer to Shiny, I'm looking for some guidance for rendering the elements in a list of tibbles.

I followed this thread and was able to render a fixed number of tibbles iteratively with uiOutput.

  • I'm wondering if anyone could point me to an example in which the layout of the tables can be changed so they are not simply stacked on top of each other.

My goal is to to show a title and caption for each one, of which the title would come from the names of the list objects.

here is small reproducible example, with a list of three tibbles rendered as reacttables.

library(shiny)
library(purrr)
library(dplyr)
library(reactable)

ui <- fluidPage(
  mainPanel(
    uiOutput("tables")
  )
)

server <- function(input, output) {
  output$tables <- renderUI({
    data=array(rnorm(150),c(10,5,3))
    data <- array_tree(data,3) %>% map(as_tibble)
    names(data) <- c("site A","site B","unknown site")
    lapply(seq_len(length(data)), function(i) {
      id <- paste0("dtss", i)  
      output[[id]] <- renderReactable(reactable(data[[i]]))})}
  )
}

shinyApp(ui = ui, server = server)

Hopefully this makes sense.
thanks,
Luis

Hi Luis,

I think an option can be generate the html in renderUI, so you can have all your data (table, title, caption) in a tibble, and then with pmap, generate the html part: a div containting the title, the reactable and caption for every table and send that to the uiOutput.

library(shiny)
library(purrr)
library(dplyr)
library(reactable)
library(htmltools)

# input <- list(ntables = 4)

ui <- fluidPage(
  mainPanel(
    sliderInput("ntables", "# tables", min = 1, max = 4, value = 1),
    uiOutput("tables", class = "row")
    )
  )

server <- function(input, output) {
  output$tables <- renderUI({
    
    n <- input$ntables
    
    tablas <- map(1:n, function(i) as_tibble(matrix(rnorm(10 * i), ncol = i)))
    
    titulos <- paste("titulo", 1:n)
    
    captions <- paste("caption", 1:n)
    
    tibble(
      tbl = tablas,
      tle = titulos,
      cap = captions
      ) %>% 
      pmap(function(tbl, tle, cap){
        
        tags$div(
          class = "col-sm-4", # given by bootstrap
          tags$h1(tle),
          reactable(tbl),
          tags$em(cap)
        )
        
      })
    
    })
}

shinyApp(ui = ui, server = server)
2 Likes

Hi @Luis. I would suggest you layout a div in ui and add individual ui for each reactable by insertUI with your layout design (title or caption). And render each table with renderReactable. Hope it can help.

library(shiny)
library(purrr)
library(dplyr)
library(reactable)

ui <- fluidPage(
  mainPanel(
    tags$div(id = "tableContainer")
  )
)

server <- function(input, output) {
  observe({
    data=array(rnorm(150),c(10,5,3))
    data <- array_tree(data,3) %>% map(as_tibble)
    names(data) <- c("site A","site B","unknown site")
    map2(data, names(data), ~{
      insertUI("#tableContainer", "beforeEnd",
               tags$div(
                 h4(.y),
                 reactableOutput(.y)
               ))
      output[[.y]] <- renderReactable(reactable(.x))
    })
  })
}

shinyApp(ui = ui, server = server)
2 Likes

thanks @raytong and @jbkunst!
both of your approaches worked for my data and they are quite similar :mechanical_arm:
now I'm looking into modifying the contents of each div to customize the table layouts and add some space between them.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.