Search code examples
rggplot2curve-fittingpoisson

How to pass multiple formulae in geom_smooth (facet_wrap) in R ggplot2?


I want to fit three different functions for each of these factors (var.test). I tried the following method but I get an error that reads Warning messages: 1: Computation failed in stat_smooth():invalid formula. Any other way to get multiple formulae to read be passed at once?

set.seed(14)
df <- data.frame(
  var.test = c("T","T","T","T","M","M","M","M","A","A","A","A"),
  val.test = rnorm(12,4,5),
  x = c(1:12)
)

my.formula <- c(y~x + I(x^2), y~x, y~x + I(x^2))

ggplot(df, aes(x = x, y = val.test)) + geom_point() +
  geom_smooth(method="glm", formula = my.formula, 
              method.args = list(family = "poisson"), color = "black" ) + facet_grid(.~var.test)

enter image description here


Solution

  • You can only have one formula per geom_smooth(). You'll need to add three different geom_smooth layers. YOu can do that manually

    ggplot(df, aes(x = x, y = val.test)) + 
      geom_point() +
      geom_smooth(method="glm", formula = my.formula[[1]], method.args = list(family = "poisson"), color = "black" ) + 
      geom_smooth(method="glm", formula = my.formula[[2]], method.args = list(family = "poisson"), color = "black" ) + 
      geom_smooth(method="glm", formula = my.formula[[3]], method.args = list(family = "poisson"), color = "black" ) + 
      facet_grid(.~var.test)
    

    Or you can use lapply to help

    ggplot(df, aes(x = x, y = val.test)) + 
      geom_point() +
      lapply(my.formula, function(x) geom_smooth(method="glm", formula = x, 
                  method.args = list(family = "poisson"), color = "black" )) + 
      facet_grid(.~var.test)
    

    Output

    If you want different lines per panel, then you can filter your data for each panel. Here we use an mapply helper and subset the data for each line.

    ggplot(df, aes(x = x, y = val.test)) + 
      geom_point() +
      mapply(function(x, z) geom_smooth(method="glm", data=function(d) subset(d, var.test==z), formula = x, 
                  method.args = list(family = "poisson"), color = "black" ),
             my.formula, c("A","M","T")) + 
    facet_grid(.~var.test)
    

    Different lines per panel