Search code examples
rshinyfacet-wrapselectinput

Multiple variables to facet_wrap from selectInput: R Shiny


I am seeking some help for my Shiny App with facet_wrap(). I have some data & I want the app to dynamically facet_wrap with one or more variables selected from a single selectInput. App does it with only one variable but not with multiple. When I select multiple variables from the same selectInput, only first variable is considered for faceting in the plots. I do not want to use facet_grid(). There are two things What I want help on.

  1. When the app begins for the first time, I get the error 'Error: invalid first argument'. How to get rid of this error.
  2. How to facet plots with multiple variables selected from single selectInput. Any suggestion or help is much appreciated.

Repex code:

library(shiny)
library(tidyverse)
library(DT)
# Define UI for data upload app ----
ui <- fluidPage(
    titlePanel("Upload & View Files"),
      sidebarLayout(
        sidebarPanel(width = 2,
          selectInput("facet", "Select Facets", choices = colnames(data), "", multiple = T)
  ),
    
    # Main panel for displaying outputs ----
    mainPanel("Data View",
      plotOutput("heatmap", width = "1050px", height = "800px"),
      DT::dataTableOutput("table")
      
    )
    
  )
)

# Define server logic to read selected file ----
server <- function(session, input, output) {
  data <- diamonds
   output$table  <- DT::renderDataTable(data, options = list(paging = T, pageLength = 20))
   output$heatmap <- renderPlot({
     ggplot(data, aes(x = carat, fill = carat)) + geom_bar() + facet_wrap(~ get(input$facet), scales = "free")
   })
  }
shinyApp(ui, server)

What I looking at is when multiple variables are selected from the selectInput; Ex: cut, clarity, depth etc. It would be like having facet_wrap(~ cut + clarity + depth, scales = "free)

Error Message Multiple Facet required


Solution

  • To remove the error, use req(). For multiple selected variables, one way is shown below. There may be a better way to do it.

    output$heatmap <- renderPlot({
        req(input$facet)
        
        facets <- input$facet %>% 
          str_replace_all(",", "+") %>% 
          rlang::parse_exprs()
        
        ggplot(data, aes(x = carat, fill = carat)) + geom_bar() +
          facet_wrap(vars(!!!facets), scales = "free")
        
      })
    

    output