4

I have this data set:

Area <- c("Mexico", "USA", "USA", "Canada").

Type_of_participants <- c("Doctor", "Doctor", "Engineer", "Dancer".

Salary <- c("4000", "6000", "8000", "5000").

and I am trying to plot the salary base on the user input of Area(level1) and Type_of_participants(level2), but nothing appears. I modified aes to aes_string as I looked up here. Please help me find the error

My Code

`ui <- fluidPage(
   titlePanel("Survey Results"),
   sidebarLayout(
   sidebarPanel(strong("Overview Plot"),
             br(),
             ###1a.Area input
             selectInput("selection","Var",
                          choices = c("Area","Type_of_participants"),
                          selected = "Area"),
            uiOutput("choice_selection")      
),
mainPanel(    
  plotOutput("Overview"))

`server <- function(input, output) {
   output$choice_selection <- renderUI({
   checkboxGroupInput("baseinput","Detail",
                   unique(df[,input$selection])
                  )`
   })
    dt1 <- reactive({
   df %>%
    group_by(input$selection,Type) %>%
     filter (input$selection %in% input$baseinput) %>%
     summarise(avg_salary_by_area = mean(Salary, na.rm = TRUE)) %>%
     select(input$selection, Type, avg_Salary_by_area)
      })

    output$Overview <- renderPlot({
    ggplot(data= dt1())+
     aes(fill = Type)+
      geom_bar(x=input$selection, y = avg_salary_by_area,stat="identity", 
           position = position_dodge())

The result is I can select the input but can not visualize the plot. The error "unknown column Area or unknow Type of participants

Please help me find the mistake

Thank you

*** Update

Thanks to Mr Flick, I have fixed my code but it still informs error "Object area not found". Please help to advise. Thank you so much

  `dt1 <- reactive({
  df[df[,input$selection] %in% input$baseinput,] %>%
  group_by(input$selection,Type) %>%
  summarise(avg_score_by_area = mean(Score, na.rm = TRUE))
  })

 output$Overview <- renderPlot({

 ggplot(data= dt1(),aes_string(x= input$selection, 
                              y = "avg_score_by_area",fill = "Type"))+
 geom_bar(stat="identity", 
           position = position_dodge())`
4
  • 1
    Your server function doesn't seem to be complete. Maybe this will help: Shiny: Change column used in ggplot2 dynamically Commented Mar 10, 2020 at 20:27
  • And also R Shiny - Using Selectinput as column selection to subset data frame Commented Mar 10, 2020 at 20:29
  • Hi, Thank very much for your help. I tried to modify my code as below. It still have error "object 'Area' not found". Please advise dt1 <- reactive({ df[df[,input$selection] %in% input$baseinput,] %>% group_by(input$selection,Type) %>% summarise(avg_salary_by_area = mean(Score, na.rm = TRUE)) }) output$Overview <- renderPlot({ ggplot(data= dt1(),aes_string(x= input$selection, y = "avg_salary_by_area",fill = "Type"))+ geom_bar(stat="identity", position = position_dodge()) Commented Mar 10, 2020 at 21:19
  • Hi @Suzie - please do not post code in comments. Rather, please edit the question to reflect its new state Commented Mar 10, 2020 at 22:01

1 Answer 1

3

@Suzie - as mentioned above, it would help if you edited your question with your complete code as you currently have it.

A few things that would help:

  • Salary should be numeric in your df (or be converted with as.numeric before trying to take the mean
  • Your reactive expression can use !!as.symbol with input$selection to filter by the string name from df
  • The plot can use aes_string for the variable names.

Edit:

For further explanation of !!as.symbol, first consider what the result of input$selection. If you use browser() in your shiny code, and inspect what input$selection returns, you will see something like "Area" (it returns a string). But a string would not be appropriate in your filter - it is expecting a symbol that represents a column in your data frame. (A symbol is the name of an object like df or mtcars, etc.)

First, you want to convert a string to a symbol. You can do that either by using as.symbol() or rlang::sym(). You can try this out in your console. If you do as.symbol("df") it would return the symbol df. If you entered eval(as.symbol("df")) it would be the same as just entering df itself (and it would show the contents of your data frame).

The other issue is that tidyverse functions evaluate code expressions in a special context (searching for names within a data frame, for example). In this case dplyr knows that the name Area is in the context of df (one of the column names). This is a complicating factor since arguments are quoted. To address this, you need to unquote (replace a name with its value) with the bang-bang !! operator.

Putting both together you get !!as.symbol().

Of note, varSelectInput is a newer shiny alternative to selectInput that can be considered for use in situations like these.

For more information:

shinymeta special topics

advanced R

library(tidyverse)
library(shiny)

Area <- c("Mexico", "USA", "USA", "Canada")
Type_of_participants <- c("Doctor", "Doctor", "Engineer", "Dancer")
Salary <- c(4000, 6000, 8000, 5000)

df <- data.frame(Area, Type_of_participants, Salary)

ui <- fluidPage(
  titlePanel("Survey Results"),
  sidebarLayout(
    sidebarPanel(strong("Overview Plot"),
                 br(),
                 ###1a.Area input
                 selectInput("selection","Var",
                             choices = c("Area","Type_of_participants"),
                             selected = "Area"),
                 uiOutput("choice_selection")      
    ),
    mainPanel(    
      plotOutput("Overview")
    )
  )
)

server <- function(input, output) {

  output$choice_selection <- renderUI({
    checkboxGroupInput("baseinput", "Detail", unique(df[,input$selection]))
  })

  dt1 <- reactive({
    df %>%
      group_by(Area, Type_of_participants) %>%
      filter(!!as.symbol(input$selection) %in% input$baseinput) %>%
      summarise(avg_salary_by_area = mean(Salary, na.rm = TRUE))
  })

  output$Overview <- renderPlot({
    ggplot(data = dt1(), aes_string(x = input$selection, y = "avg_salary_by_area", fill = "Type_of_participants")) +
      geom_bar(stat="identity", position = position_dodge())
  })
}

shinyApp(ui, server)
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you so much for your help. Could you please explain a bit more about the syntax !!as.symbol(input$selection) here as I am still a bit confused about this and not much of documentation on the internet about it :( Appreciate it :)
@Suzie see edited answer for additional explanation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.