2

I'm trying to create a simple app that plots the mean of a continuous variable by the levels of a factor. The user chooses one of several factors to group by and chooses the continuous variable to average. The app is supposed to display the plot using ggplot. It is easy to get this function to work outside of shiny, but I am struggling to get it to work within the application. I know the problem is with my lack of understanding of NSE and SE, but after looking at documentation for a few hours and testing various versions this is the best I could come up with. This appears to be a common problem but I see no answers related to my problem on stack-overflow.

I use the Titanic dataset as an example I get the following:

Warning in mean.default(input$ContVar) : argument is not numeric or logical: returning NA In addition to the error, the mean does not vary when the plot renders.

    library(shiny)
    library(dplyr)
    library(ggplot2)
    Titan <- as.data.frame(Titanic)
    Titan <- mutate(Titan, Freq2 = Freq +3)

    shinyApp( ui = basicPage( selectInput("FactVar", "Factor", choices = names(Titan)[1:4]), selectInput("ContVar", "Cont Variable", choices = names(Titan)[5:6]), plotOutput("surv")), server = function(input, output) {
        output$surv <- renderPlot({
            Titan %>%
            group_by_(~input$FactVar) %>%
            summarize_(MeanFreq = ~ mean(input$ContVar))%>%
            ggplot(aes_(x=~ MeanFreq, y = input$FactVar))+geom_point()
        })
    })
aashish tamsya
  • 4,903
  • 3
  • 23
  • 34
Reric
  • 21
  • 2
  • Maybe [this](https://stackoverflow.com/questions/25211916/passing-user-specifications-as-arguments-to-dplyr-within-shiny?rq=1) would help. – SBista Jun 05 '17 at 05:12
  • From the above link I came up with this. `eval(substitute(Titan %>% group_by_(~input$FactVar) %>% summarize_(MeanFreq = ~ mean(col)), list(col = as.symbol(input$ContVar)))) %>% ggplot(aes_(x=~ MeanFreq, y = input$FactVar))+geom_point()` – SBista Jun 05 '17 at 05:38
  • Thanks SBista for the attention to the problem. The solution above did not solve the problem when I ran the code. I will read the link above for clues. – Reric Jun 05 '17 at 10:42
  • Looks like this will be easier with the dplyr version 0.6.0. See this answer: [link] (https://stackoverflow.com/questions/44398831/dynamic-dplyr-column-name-calculation) – Hallie Swan Jun 06 '17 at 22:41

2 Answers2

1

Here's a quick little solution I worked out.

The key here is just to use the the !! operator and sym function from the rlang package. Let me know if you have any questions!

library(shiny)
library(dplyr)
library(ggplot2)
Titan <- as.data.frame(Titanic)
Titan <- mutate(Titan, Freq2 = Freq +3)

shinyApp( 
  ui = basicPage( 
         selectInput("FactVar", "Factor", 
                     choices = names(Titan)[1:4]), 
         selectInput("ContVar", "Cont Variable", 
                     choices = names(Titan)[5:6]), plotOutput("surv")), 

  server = function(input, output) {

output$surv <- renderPlot({
    Titan %>%
      group_by(!!rlang::sym(input$FactVar)) %>%
      summarize(MeanFreq = mean(!!rlang::sym(input$ContVar))) %>%
      ggplot(aes_string(x="MeanFreq", y = input$FactVar)) + geom_point()
  })
})

Non standard evaluation is definitely one of the more tricky aspects of the R language. Good luck!

JBlaz
  • 81
  • 1
  • 4
0

Here's an option, although it doesn't use dplyr.

I'm using aggregate and explicitly naming the resulting columns, so I can later call these names in ggplot.

library(shiny)
library(ggplot2)
Titan <- as.data.frame(Titanic)
Titan <- mutate(Titan, Freq2 = Freq +3)

shinyApp( 

  ui = basicPage( 
    selectInput("FactVar", "Factor", choices = names(Titan)[1:4]), 
    selectInput("ContVar", "Cont Variable", choices = names(Titan)[5:6]), 
    plotOutput("surv")), 

  server = function(input, output) {
   output$surv <- renderPlot({

     MeanFreq <- aggregate(list(ContVar = Titan[, input$ContVar]), 
                           list(FactVar = Titan[, input$FactVar]), 
                           mean)

      ggplot(MeanFreq, aes(x = ContVar, y = FactVar)) +
        geom_point()
  })
})
Hallie Swan
  • 2,714
  • 1
  • 15
  • 23