Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Problem with reactive geom_boxplot in shiny

I am trying to create a simple Shiny app that creates a mutable boxplot using ggplot. The original plot shown will include all groups, sorted by ascending mean of the variable chosen, with the first variable originally chosen as default. Sample code that simply replicates issue with similar data:
library(tidyverse)
library(shiny)

## sample data ----
sample_df <- data.frame(var_1 = sample(1:20, 100, replace = TRUE), 
                        var_2 = sample(5:25, 100, replace = TRUE), 
                        var_3 = sample(1:15, 100, replace = TRUE), 
                        var_4 = sample(25:40, 100, replace = TRUE), 
                        group_name = rep(c('A', 'B', 'C', 'D'), 25))

## defined ui layout ----
ui <- fluidPage(titlePanel("Title"),
                sidebarLayout(
                  sidebarPanel(
                    checkboxGroupInput('group_choice', 'Choose Group', choices = list('Group A' = 'A', 
                                                                                      'Group B' = 'B', 
                                                                                      'Group C' = 'C', 
                                                                                      'Group D' = 'D'), 
                                       selected = c('A', 'B', 'C', 'D')), 
                    radioButtons('variable_choice', 'Variable for Boxplot', choiceNames = c('var_1', 'var_2', 'var_3', 'var_4'), 
                                 inline = TRUE, choiceValues = c('var_1', 'var_2', 'var_3', 'var_4'), selected = 'var_1')
                  ),
                  mainPanel(
                    tabsetPanel(type = 'tabs', 
                                tabPanel('Explore Variables', plotOutput('variable_boxplot')))
                    
                  )
                )
)

# Defined server logic ----
server <- function(input, output) {
  output$variable_boxplot <- renderPlot({
    sample_sub <- sample_df %>% dplyr::select(c(group_name, input$variable_choice)) %>% filter(group_name %in% input$group_choice)
    
    ggplot(sample_sub, aes(reorder(group_name, input$variable_choice), input$variable_choice, color = group_name)) +
      geom_boxplot() + geom_jitter(width = 0.2) + 
      theme(legend.position = 'none') + labs(x = 'Group Name', y = 'Variable')
  })
}

shinyApp(ui, server)

I get the following error:

Input to asJSON(keep_vec_names=TRUE) is a named vector. In a future version of jsonlite, this option will not be supported, and named vectors will be translated into arrays instead of objects. If you want JSON object output, please use a named list instead. See ?toJSON.
Warning: Error in geom_boxplot: Problem while computing aesthetics.
ℹ Error occurred in the 1st layer.
Caused by error in `tapply()`:
! arguments must have same length

How can I fix this?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I created a plot outside of shiny that works (obviously with no interactivity) but it fails inside the structure

>Solution :

The issue is that input$variable_choice is a character string. To tell ggplot2 this character string is a column in your data you have to use e.g. the .data pronou, i.e. use .data[[input$variable_choice]]. See e.g. Mastering Shiny.

library(tidyverse)
library(shiny)

## sample data ----
sample_df <- data.frame(
  var_1 = sample(1:20, 100, replace = TRUE),
  var_2 = sample(5:25, 100, replace = TRUE),
  var_3 = sample(1:15, 100, replace = TRUE),
  var_4 = sample(25:40, 100, replace = TRUE),
  group_name = rep(c("A", "B", "C", "D"), 25)
)

## defined ui layout ----
ui <- fluidPage(
  titlePanel("Title"),
  sidebarLayout(
    sidebarPanel(
      checkboxGroupInput("group_choice", "Choose Group",
        choices = list(
          "Group A" = "A",
          "Group B" = "B",
          "Group C" = "C",
          "Group D" = "D"
        ),
        selected = c("A", "B", "C", "D")
      ),
      radioButtons("variable_choice", "Variable for Boxplot",
        choiceNames = c("var_1", "var_2", "var_3", "var_4"),
        inline = TRUE,
        choiceValues = c("var_1", "var_2", "var_3", "var_4"),
        selected = "var_1"
      )
    ),
    mainPanel(
      tabsetPanel(
        type = "tabs",
        tabPanel("Explore Variables", plotOutput("variable_boxplot"))
      )
    )
  )
)

# Defined server logic ----
server <- function(input, output) {
  output$variable_boxplot <- renderPlot({
    sample_sub <- sample_df %>%
      dplyr::select(c(group_name, input$variable_choice)) %>%
      filter(group_name %in% input$group_choice)

    ggplot(sample_sub, aes(
      reorder(group_name, .data[[input$variable_choice]]),
      .data[[input$variable_choice]],
      color = group_name
    )) +
      geom_boxplot() +
      geom_jitter(width = 0.2) +
      theme(legend.position = "none") +
      labs(x = "Group Name", y = "Variable")
  })
}

shinyApp(ui, server)
#> 
#> Listening on http://127.0.0.1:8540

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading