0

I'm using flexdashboard and shiny to choose which variable to plot:

varSelectInput("button_var_fir"
               , "Select first num variable"
               , data = df_scat,
                multiple = FALSE
               )

ggplot(df_scat, aes(x = !!input$button_var_fir, y = Gen_type, fill = stat(x))) +
  geom_point(size= 3, alpha = .075) 

it works fine, so far. My problem is, that I would like to subset the data e.g via

df$variable > 0
ggplot(df_scat, aes(x = df$!!input$button_var_fir > 0, y = Gen_type, fill = stat(x))) +
      geom_point(size= 3, alpha = .075) 

but this doesn't work due to the $!!. How can I solve this?

NelsonGon
  • 13,015
  • 7
  • 27
  • 57
Ben
  • 1,432
  • 4
  • 20
  • 43
  • Could you add a simple app to run? I personally prefer `.data[[col]]` or `{{col}}` or `aes_string`. Also maybe you need `!!!` or `sym` before? – NelsonGon Mar 16 '22 at 10:51
  • 2
    I think this is not about running an app. It is about the question 'How do you select a column from a dataframe which name you have as a string in a variable?'. (Or maybe I don't understand the question.) – Georgery Mar 16 '22 at 10:55
  • @Georgery No, you're right, I'm testing your advice atm. Tbh, I didn't understand NelsonGon's advice :) – Ben Mar 16 '22 at 10:57
  • NelsonGon is right. Inside a `ggplot()` call, you use one of the two options he gave to dynamically call the variable. Just replace `col` with `input$button_var_fir`. – Dan Adams Mar 16 '22 at 11:58

2 Answers2

2

In {ggplot2}, which uses tidy evaluation, you can use the .data pronoun to dynamically select variables. It's nicely explained outside the {shiny} context in this answer too. This doesn't apply in {plotly} so you can either select with x = data[[input$column]] or x = get(input$column). This is also explained in this question.

Here's a small example to demonstrate how to do this for each plotting function.

library(plotly)
library(tidyverse)
library(shiny)

nbins <- 10

ui <- fluidPage(titlePanel("Dynamic Variable Selection"),
                sidebarLayout(sidebarPanel(
                  selectInput(
                    inputId = "y1",
                    label = "Select variable",
                    choices = names(mtcars))),
                mainPanel(plotOutput(outputId = "ggplot"),
                          plotlyOutput(outputId = "plotly"))))

server <- function(input, output) {
  # dynamically pull variable in ggplot
  output$ggplot <- renderPlot({
    mtcars %>%
      ggplot(aes(x = .data[[input$y1]])) +
      geom_histogram(bins = nbins) +
      ggtitle("ggplot")})
  # dynamically pull variable in plotly
    output$plotly <- renderPlotly({
    mtcars %>%
        plot_ly(x = .[[input$y1]], type = "histogram", nbinsx = nbins) %>% 
        layout(title = list(text = "Plotly"),
               xaxis = list(title = input$y1))
      })
    }

shinyApp(ui = ui, server = server)

screenshot

Dan Adams
  • 4,971
  • 9
  • 28
  • thanks a lot but tbh, I lack a bit understanding. Is this only working for shiny or ggplot? I mean I asked for it but I'm currently trying to use it for plot_ly as well but I can't get it run? – Ben Mar 17 '22 at 07:32
  • 1
    I don't think this would work for plotly. This is unique to tidy-eval. Please edit your question to expand the scope and clarify the use case and we can help further. – Dan Adams Mar 17 '22 at 10:56
0

Maybe what you want is

df[[input$button_var_fir]] > 0

instead of df$!!input$button_var_fir > 0.


Addition:
You want to subset the data that goes into the plot, right? What I would actually do is subsetting the dataframe itself before it goes into the plot function. When you use the tidyverse this could be what you want:

df_scat %>%
    filter(!!input$button_var_fir > 0) %>%
    ggplot(aes(x = !!input$button_var_fir, y = Gen_type, fill = stat(x))) +
    geom_point(size= 3, alpha = .075) 
Georgery
  • 7,643
  • 1
  • 19
  • 52
  • As far as I see this yields logical values (False, True) inside the plot – Ben Mar 16 '22 at 11:00
  • 1
    I think you need to replace `df` with `.data` and then it should work. – Dan Adams Mar 16 '22 at 11:59
  • unfortunately, it doesn't :) you mean "df.data[[input$button_var_fir]]", right? – Ben Mar 16 '22 at 14:50
  • 1
    No, just `.data`. that's the generic way if referring to whatever data you passed to `ggplot()` – Dan Adams Mar 16 '22 at 14:53
  • will try out, thanks! Does this work only for ggplot, then? – Ben Mar 16 '22 at 14:54
  • 1
    Works inside any tidy-eval function including many {dplyr} functions. See [here](https://rlang.r-lib.org/reference/dot-data.html) for more info on the `.data` pronoun. More generally [this](https://www.brodrigues.co/blog/2019-06-20-tidy_eval_saga/) blog post gives a nice overview of how curly-curly (`{{}}`) is replacing the old quote-unquote method (`!!sym("x")`). – Dan Adams Mar 16 '22 at 16:18