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?
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.")
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")
se Display confidence interval around smooth (TRUE by default, see level to control.)
geom_smooth does not plot line of best fit.
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_smooth
s 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:
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)
# }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With