Hugovanp
Hugovanp

Reputation: 95

Error with facet_grid() when using a function created for plotting

I have created a function for returning a plot in R. There seems to be a issue with facet_grid() that appears when plotting with the created plot function that does not appear when not using the function (even though I use the exact same lines of code).

# function for plotting
barplot_fill <- function(dataset, x, y, fill, jaar) {
  p <- ggplot(dataset, aes(x=x, y=y, fill=fill)) +
    geom_bar(stat = "identity") +
    facet_grid(~ jaar) +
    theme_bw() + 
    scale_y_continuous(labels=comma)

  return(p)
}

I would like to plot variables from the following data frame:

df <- data.frame(V1=c(1,2,3,4), V2=c(20,25,46,13), V3=c('a','a','b','b'), V4=c(2018,2019,2018,2017))

When calling the function, I get the following error:

barplot_fill(df, V1, V2, V3, V4)

Error: At least one layer must contain all faceting variables: dataset$jaar. * Plot is missing dataset$jaar * Layer 1 is missing dataset$jaar

When I don't call the created function and just create the plot using the ggplot lines of code, R creates the plot and the error does not appear.

ggplot(df, aes(x=V1, y=V2, fill=V3)) +
  geom_bar(stat = "identity") +
  theme_bw() + 
  facet_grid(~ V4) +
  scale_y_continuous(labels=comma)

I can't figure out why it gives me an error in the created function and why the error does not appear when run the exact same lines of code when not using the function. Can anyone explain me why the error appears when calling the created function?

Upvotes: 2

Views: 2373

Answers (2)

Fons MA
Fons MA

Reputation: 1282

Apart from a little glitch with scale_y_continuous (you haven't defined comma), the problem is the evaluation of your variables. For aes, you can use aes_string and pass strings, but facet_grid has a different format. See under Variable Facets here.

barplot_fill <- function(dataset, x, y, fill, jaar) {

  jaar <- enquo(jaar)

  p <- ggplot(dataset, aes_string(x=x, y=y, fill=fill)) +
    geom_bar(stat = "identity") +
    facet_grid(cols = vars(!!jaar)) +
    theme_bw()

  return(p)
}

df <- data.frame(V1=c(1,2,3,4), V2=c(20,25,46,13), V3=c('a','a','b','b'), V4=c(2018,2019,2018,2017))


barplot_fill(df, "V1", "V2", "V3", V4)

Upvotes: 4

kath
kath

Reputation: 7724

The problem is that jaar is not evaluated in the facet_grid call, but ggplot is looking for a jaar column in the data set you provide. Actually, something similar happens in the ggplot-call for x, y, and fill if you remove the fact_grid part of the function:

barplot_fill_no_facet <- function(dataset, x, y, fill, jaar) {
  p <- ggplot(dataset, aes(x = x, y = y, fill = fill)) +
    geom_bar(stat = "identity") +
    theme_bw() +
    scale_y_continuous()

  return(p)
}

barplot_fill_no_facet(df, V1, V2, V3, V4)

Error in FUN(X[[i]], ...) : object 'V1' not found

One solution uses aes_string and formula for facet_grid:

barplot_fill <- function(dataset, x, y, fill, jaar) {
  p <- ggplot(dataset, aes_string(x = x, y = y, fill = fill)) +
    geom_bar(stat = "identity") +
    facet_grid(formula(paste("~", jaar))) +
    theme_bw() +
    scale_y_continuous()

  return(p)
}

barplot_fill(df, "V1", "V2", "V3", "V4") 

enter image description here

Upvotes: 4

Related Questions