Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom lm formula in geom_smooth

Tags:

r

ggplot2

I'm working with faceted plots, and adding lines using the lm method in geom_smooth()

d<-data.frame(n=c(100, 80, 60, 55, 50, 102, 78, 61, 42, 18),
              year=rep(2000:2004, 2), 
              cat=rep(c("a", "b"), each=5))

ggplot(d, aes(year, n, group=cat))+geom_line()+geom_point()+
  facet_wrap(~cat, ncol=1)+
  geom_smooth(method="lm")

I would like to set up a function to apply a polynomial where appropriate. I've worked up a function:

lm.mod<-function(df){
  m1<-lm(n~year, data=df)
  m2<-lm(n~year+I(year^2), data=df)
  ifelse(AIC(m1)<AIC(m2), "y~x", "y~poly(x, 2)")
}

But I'm having trouble applying it. Any ideas, or better ways to approach this?

like image 603
Ed G Avatar asked Nov 27 '13 10:11

Ed G


People also ask

What is method lm in Geom_smooth?

This is pretty simple. We have our scatterplot, and we're adding a trend line as a new layer with ' + ' and geom_smooth() . But in this case, we're adding a straight-line linear model instead of a LOESS line. To do this, we simply set method = 'lm' . (If you haven't figured it out, ' lm ' means "linear model.")

What does Geom_smooth () using formula YX mean?

The warning geom_smooth() using formula 'y ~ x' is not an error. Since you did not supply a formula for the fit, geom_smooth assumed y ~ x, which is just a linear relationship between x and y. You can avoid this warning by using geom_smooth(formula = y ~ x, method = "lm")

What does the SE argument to Geom_smooth () do?

se Display confidence interval around smooth (TRUE by default, see level to control.)

Is Geom_smooth a line of best fit?

geom_smooth does not plot line of best fit.


2 Answers

It's not possible to apply different smooth functions with a single geom_smooth call. Here is a solution which is based on smoothing subsets of data:

First, create the base plot without geom_smooth:

library(ggplot2)
p <- ggplot(d, aes(year, n, group = cat)) +
       geom_line() +
       geom_point() +
       facet_wrap( ~ cat, ncol = 1)

Second, the function by is used to create a geom_smooth for each level of cat (the variable used for facetting). This function returns a list.

p_smooth <- by(d, d$cat, 
               function(x) geom_smooth(data=x, method = lm, formula = lm.mod(x)))

Now, you can add the list of geom_smooths to your base plot:

p + p_smooth

The plot includes a second-order polynomial for the upper panel and a linear smooth for the lower panel:

enter image description here

like image 65
Sven Hohenstein Avatar answered Sep 18 '22 17:09

Sven Hohenstein


lm.mod<-function(df){
  m1<-lm(n~year, data=df)
  m2<-lm(n~year+I(year^2), data=df)
  p <- ifelse(AIC(m1)<AIC(m2), "y~x", "y~poly(x, 2)")
return(p) 
}
# I only made the return here explicit out of personal preference

ggplot(d, aes(year, n, group=cat)) + geom_line() + geom_point() +
  facet_wrap(~cat, ncol=1)+
  stat_smooth(method=lm, formula=lm.mod(d))
# stat_smooth and move of your function to formula=

# test by reversing the condition and you should get a polynomial.
# lm.mod<-function(df){
#   m1<-lm(n~year, data=df)
#   m2<-lm(n~year+I(year^2), data=df)
#   p <- ifelse(AIC(m1)>AIC(m2), "y~x", "y~poly(x, 2)")
# return(p)
# }
like image 27
user1317221_G Avatar answered Sep 18 '22 17:09

user1317221_G