Home > Software design >  flip boxplot with conditional statement in Shiny app R
flip boxplot with conditional statement in Shiny app R

Time:12-18

I am generating a boxplot in Shiny app in R based on user input, The user selects one factor variable and one numeric variable then a box blot of these variables is shown. My problem is that; some of the factor variables have more than 10 levels, the x-axis labels overlap, so I would like the boxplot to flip if the variable chosen has more than a certain number of levels so the x-axis label names can be horizontal.

I have tried using the If statement in the server section, I used the nlevels(dataset[[input$varX]])but it's not getting the number of levels for the factor variables. The plot area is blank. The nlevels(dataset[[input$varX]]) fetches the number of levels in the category,

    column1<- c("box","box","box","box","rec","rec","circle","circle","circle","circle","circle","circle","circle")
    column2<- c(1,2,3,6,8,9,10,12,15,18,11,19,20)
    column3<- c("blue","red","yellow","green","black","blue","red","yellow","green","black","red","black","yellow")
    dataset<- data.frame(column1,column2,column3)
ui <- fluidPage(theme = shinytheme("flatly"),
                navbarPage(tabPanel("Boxplot", 
                            
                           sidebarLayout(
                             sidebarPanel(
                             
                               varSelectInput("varX", "Var1:", dataset),
                               varSelectInput("varY", "Var2:", dataset)
                             ),
                             
                             # Show plot 
                             mainPanel(
                               br(),
                               plotOutput("boxPlot")
                             )
                           )
                           ),


server <- function(input, output) {
    output$boxPlot <- renderPlot({
      if(nlevels(dataset[[input$varX]]) < 4){
        plot_a<- ggplot(dataset,aes_string(x=input$varX, y=input$varY)) 
          geom_boxplot() 
          ggtitle(paste("boxplot of ", input$varX, "vs", input$varY)) 
          
        plot_a
      }

      if(nlevels(dataset[[input$varX]]) >= 4){
        plot_box   coord_flip()
      }
      
})
}

CodePudding user response:

One problem you've got is that your columns aren't factors, and so there are no levels. I changed the first and third columns to factors.

The main fix for you missing plots is that you need to create plot_a before the if statements. Then modify as needed based on your logic about the levels. Then you need to return the plot_a by putting it on its own line at the very end of the renderPlot.

library(tidyverse)
library(shiny)

column1<- c("box","box","box","box","rec","rec","circle","circle","circle","circle","circle","circle","circle")
column2<- c(1,2,3,6,8,9,10,12,15,18,11,19,20)
column3<- c("blue","red","yellow","green","black","blue","red","yellow","green","black","red","black","yellow")
dataset<- data.frame(column1 = factor(column1),column2,column3 = factor(column3))

ui <- fluidPage(
  varSelectInput("varX", "Var1:", dataset),
  varSelectInput("varY", "Var2:", dataset),
  br(),
  plotOutput("boxPlot")
)
                
server <- function(input, output) {
  output$boxPlot <- renderPlot({
    
    plot_a<- ggplot(dataset,aes_string(x=input$varX, y=input$varY)) 
      geom_boxplot() 
      ggtitle(paste("boxplot of ", input$varX, "vs", input$varY))
    
    
    if(nlevels(dataset[[input$varX]]) >= 4){
      plot_a <- plot_a   coord_flip()
    }
    plot_a
  })
}

shinyApp(ui, server)

I removed all of your navbars/tabsets because they were irrelevant to the question and squeezing everything.

  • Related