Dynamic number of Plots with reactive data in R Shiny

I am trying to make an RShiny app that you can pick a gene from a list, and it will display different graphs using that gene's transcripts. However, each gene has a different number of transcripts, so a different number of graphs must be displayed every time a different gene is chosen. How I have it set right now is that when a person chooses a gene, a new table is created with the transcript numbers (data to be plotted) along with a new list of all the transcript names (length of this list is the amount of plots that I need). These are reactive values.

Below, in the server, I made a function that creates the graph that I want, and then I iterate through the creation of the function by indexing into the reactive list of names, so it creates a graph for each name (as each name is a different transcript). Right now, the code iterates through all the names correctly but only displays the last plot. Is there a way to have every plot displayed? I have tried a lot of different things, from renderUI to using local calls, but cannot figure it out.

ui <- fluidPage(
    sidebarLayout(
        sidebarPanel(
    selectInput("var", label = "Choose a gene to display", names),
        mainPanel(
       plotOutput("tdot"))
))


server <- function(input, output) {
genename <- reactive({
    input$var
})

transTable2 <- reactive ({
    cbind(biofluids, select(transTable, starts_with(input$var)))
})

names <- reactive ({
    tableBF <- cbind(biofluids, select(transTable, starts_with(input$var)))
    n <- colnames(tableBF)
    final <- n[-1]
})



createUI <- function(name, table) {
    ggplot(table, aes_string(x = "biofluids", y = name))+geom_boxplot(aes(color = biofluids))+
        geom_boxplot(aes(fill = biofluids)) + scale_y_log10()+ylab( 'log10 normalized counts')+
        ggtitle(name)}

output$tdot <- renderPlot({
        lapply(1:length(names()), function(i) 
        createUI(names()[i], transTable2()))
})

}

# Run the application 
shinyApp(ui = ui, server = server)

I use tagList to contain the multiplot renderPlots, I house them inside of a larger uiOutput/renderUI
I also prefer purrr::map to lapply

library(shiny)
library(tidyverse)
ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      selectInput("var", label = "Choose a cut to display", unique(diamonds$cut))
    ),
    mainPanel(
      uiOutput("tdot")
    )
  )
)

server <- function(input, output) {
  prepped_data <- reactive({
    diamonds %>%
      as_tibble() %>%
      filter(cut == req(input$var)) %>%
      select(color, depth, price) %>%
      group_split(color)
  })

  createUI <- function(table) {
    p <- ggplot(table, aes(x = depth, 
                           y = price)) +
      geom_point() +
      ggtitle(paste0(unique(table$color)))
    renderPlot(p)
  }

  output$tdot <- renderUI({
    pd <- req(prepped_data())
    tagList(map(
      pd,
      ~ createUI(.)
    ))
  })
}

# Run the application
shinyApp(ui = ui, server = server)
2 Likes

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

If you have a query related to it or one of the replies, start a new topic and refer back with a link.