Search code examples
rggplot2user-input

Group geom_vline for a conditional


I believe I'm going about this incorrectly. I have a ggplot that has several lines graphed into it. Each line is categorized under a 'group.' (ie. predator lines include lines for bear frequency, lion_frequency; prey lines include lines for fish frequency, rabbit_frequency; etc.)

Here's a reproducible example using dummy data

p <- function(black_lines, green_lines){
  ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() +
  geom_vline(xintercept = 5) +
  geom_vline(xintercept = 10) +
  geom_vline(xintercept = 1:5,
             colour = "green",
             linetype = "longdash")
}

p()

Ideally, it would work like:

p <- function(black_lines, green_lines){
  ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() +
  
  if (black_lines){
    geom_vline(xintercept = 5) +
    geom_vline(xintercept = 10) +
  }
  
  if(green_lines){
  geom_vline(xintercept = 1:5,
             colour = "green",
             linetype = "longdash")
  }
}

p(T, T)

This method won't work, of course since R doesn't like -> Error in ggplot_add(): ! Cannot add ggproto objects together. Did you forget to add this object to a ggplot object?

But I'm wondering if this is possible? I couldn't find any similar questions so I feel like I'm going about wrongly.

For those who believe more context is needed. This is for a reactive Shiny app and I want the user to be able to select how the graph will be generated (as such with specific lines or not).

Thank you for your guidance in advance!


Solution

  • You could create your conditional layers using an if and assign them to a variable which could then be added to your ggplot like any other layer:

    Note: In case you want to include multiple layers then you could put them in a list, e.g. list(geom_vline(...), geom_vline(...)).

    library(ggplot2)
    
    p <- function(black_lines, green_lines){
      vline_black <- if (black_lines) geom_vline(xintercept = c(5, 10))
      vline_green <- if (green_lines) geom_vline(xintercept = 1:5,
                                                 colour = "green",
                                                 linetype = "longdash")
      
      ggplot(mtcars, aes(x = wt, y = mpg)) + 
        geom_point() +
        vline_black +
        vline_green
    }
    
    p(T, T)
    

    
    p(T, F)