1

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()
      }
      
})
}

highclef
  • 169
  • 7
  • It would be easier to help you if you provide [a minimal reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) including a code that others can run and a snippet of your data or some fake data. – stefan Dec 17 '22 at 03:22

1 Answers1

1

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.

Michael Dewar
  • 2,553
  • 1
  • 6
  • 22