2

I am looking to wrap the following formula into a function for easier end use:

df %>% 
  group_by(a, b) %>%
  summarize(avg=mean(c)) %>%
  ggline(x="a", y="avg", color='b')

however the following returns the error "Error in is.factor(x) : object 'b' not found" even though is.factor(df$b) == TRUE

graph_var <- function(data_source, var) {
  var2 <- enquo(var)
  
  data_source %>% 
    group_by(a, !!var2 )%>% 
    summarize(avg=mean(c)) %>% 
    ggline(x="a", y="avg", color=shQuote(var) )+ grids(linetype = 'dashed')
}

graph_var(df, b)

I'm sure the issue lies somewhere around ggpubr using quotes in its arguments, but I can't track down exactly what I need to do get this to work.

For reproducibility:

library(tidyverse)
library(ggpubr)

set.seed(13)
df <- data.frame(
  a = rep(1:10),
  b = as.factor(rep(LETTERS[24:26], each = 10)),
  c = rnorm(30)
)

#explicit declatation - this works
df %>% 
  group_by(a, b )%>% 
  summarize(avg=mean(c)) %>% 
  ggline(x="a", y="avg", color="b" )+ grids(linetype = 'dashed') #works

#declaired via variable, this also works
test_var <- "b"

df %>% 
  group_by(a, b )%>% 
  summarize(avg=mean(c)) %>% 
  ggline(x="a", y="avg", color=test_var )+ grids(linetype = 'dashed') #also works

#declaited via f(x) - yeilds error "Error in is.factor(x) : object 'b' not found"
graph_var_ex <- function(data_source, var) {
  var2 <- enquo(var)
  
  data_source %>% 
    group_by(a, !!var2 )%>% 
    summarize(avg=mean(c)) %>% 
    ggline(x="a", y="avg", color=shQuote(var) )+ grids(linetype = 'dashed')
}

graph_var_ex(df, b)
  • 1
    Could you provide a sample of your data `df` so we can test approaches? – jpsmith Dec 30 '22 at 16:25
  • 4
    Generally gg-functions need an aes-object which then allows one to drop those annoying quotes from column names. You shuld [edit] your question to include all needed `library` calls as well as data to create a [MCVE] – IRTFM Dec 30 '22 at 16:25

1 Answers1

4

Try as.character(ensym(var)).

Other notes:

  1. Your function included y="c" in the ggline() call, but this should be y="avg" since "c" no longer exists after your summarize().
  2. You can use the {{ embracing operator as a shortcut for !!enquo() when passing var to group_by().
library(dplyr)
library(ggpubr)

# example data
set.seed(13)
df <- data.frame(
  a = rep(1:10),
  b = rep(LETTERS[24:26], each = 10),
  c = rnorm(30)
)

graph_var <- function(data_source, var) {
  var2 <- as.character(ensym(var))
  
  data_source %>% 
    group_by(a, {{var}})%>% 
    summarize(avg = mean(c)) %>% 
    ggline(x = "a", y = "avg", color = var2) + 
    grids(linetype = "dashed")
}

graph_var(df, b)

zephryl
  • 14,633
  • 3
  • 11
  • 30
  • 1
    You can also leave the `enquo()` and use `as_label()` on the quosure to get a string representation. This works even with complex calls. Or (my favourite option) you could use `{{ var }}` in the `group_by()` call and `englue("{{ var }}"` to get a string. – Lionel Henry Jan 02 '23 at 08:07