Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

extend geom_smooth in a single direction

Tags:

r

ggplot2

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!

like image 288
Alex Coppock Avatar asked Nov 02 '14 23:11

Alex Coppock


People also ask

What is the use of Geom_smooth in R?

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.

How to display the results with a non-standard Geom?

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.

What is the difference between Geom_smooth () and stat_smooth ()?

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.

How many orientations can a Geom have?

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.


1 Answers

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)

enter image description here

like image 68
agstudy Avatar answered Sep 24 '22 08:09

agstudy