You can extend a regression line in ggplot2 pretty easily:
c <- ggplot(mtcars, aes(y=wt, x=mpg)) + xlim(0,50)
c + stat_smooth(method=lm, fullrange=TRUE) + geom_point()
My question is, is it possible to extend in one direction only?
Before you ask, I have a good reason to do this, I promise!
The geom smooth function is a function for the ggplot2 visualization package in R. Essentially, geom_smooth () adds a trend line over an existing plot. By default, the trend line that’s added is a LOESS smooth line. But there are a few options that allow you to change the nature of the line too.
Use stat_smooth () if you want to display the results with a non-standard geom. Set of aesthetic mappings created by aes () or aes_ (). If specified and inherit.aes = TRUE (the default), it is combined with the default mapping at the top level of the plot.
Aids the eye in seeing patterns in the presence of overplotting. geom_smooth () and stat_smooth () are effectively aliases: they both use the same arguments. Use stat_smooth () if you want to display the results with a non-standard geom.
This geom treats each axis differently and, thus, can thus have two orientations. Often the orientation is easy to deduce from a combination of the given mappings and the types of positional scales in use.
In the internal workings of stat_smooth
, predictdf
is called to create the smoothed line. The difficulty here is : This is an S3 method not exported. It also don't take ... parameters so it is really difficult to extend it.
Here the idea is to create a new dummy classes lm_right
and lm_left
where we call the default lm
method.
## decorate lm object with a new class lm_right
lm_right <- function(formula,data,...){
mod <- lm(formula,data)
class(mod) <- c('lm_right',class(mod))
mod
}
## decorate lm object with a new class lm_left
lm_left <- function(formula,data,...){
mod <- lm(formula,data)
class(mod) <- c('lm_left',class(mod))
mod
}
Then for each method we create a predict_df
specialization where we truncate the x values in the opposite side.
predictdf.lm_right <-
function(model, xseq, se, level){
## here the main code: truncate to x values at the right
init_range = range(model$model$x)
xseq <- xseq[xseq >=init_range[1]]
ggplot2:::predictdf.default(model, xseq[-length(xseq)], se, level)
}
Same thing for the left extension :
predictdf.lm_left <-
function(model, xseq, se, level){
init_range = range(model$model$x)
## here the main code: truncate to x values at the left
xseq <- xseq[xseq <=init_range[2]]
ggplot2:::predictdf.default(model, xseq[-length(xseq)], se, level)
}
Finally a using example:
library(ggplot2)
library(gridExtra)
## you should set the fullrange option to a true
p1 <- ggplot(mtcars, aes(y=wt, x=mpg)) + xlim(0,50) + geom_point() +
stat_smooth(method="lm_left", fullrange=TRUE,col='green')
p2 <- ggplot(mtcars, aes(y=wt, x=mpg)) + xlim(0,50) + geom_point() +
stat_smooth(method="lm_right", fullrange=TRUE,col='red')
grid.arrange(p1,p2)
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