Hi In R, using plot(x,y) followed by abline(lm(y~x)) produces a graph with a regression line spanning the whole plot . This means that the line extends beyond the swarm of data points to the defined of default plot region. With par(xpd=T) it will span the entire figure region. But how can I limit a regression line to the data range, i.e between (xmin,ymin) and (xmax,ymax)? Sorry for not knowing the lingo here. If you don't understand the question, please run the following script: x1<-c(1,2,3,4) x2<-c(5,6,7,8) y1<-c(2,4,5,8) y2<-c(10,11,12,16) plot(x1,y1,xlim=c(0,10),ylim=c(0,20),col="blue") points(x2,y2,col="red") abline(lm(y1~x1),col="blue") abline(lm(y2~x2),col="red") The resulting plot isn't very informative. There is no overlap in the two groups of data, yet the two ablines overlap. I instead want the blue line to go from (1,2) to (4,8) and the red line from (5,10) to (8,16). So, how can I constrain the abline to the relevant region, i.e stop abline from extrapolating beyond the actual range of data. Or should I use a function line 'lines' to do this? Cheers Andres
Marc Schwartz (via MN)
2006-May-24 17:04 UTC
[R] Regression line limited by the rage of values
On Wed, 2006-05-24 at 18:51 +0200, Andreas Svensson wrote:> Hi > > In R, using plot(x,y) followed by abline(lm(y~x)) produces a graph > with a regression line spanning the whole plot . This means that the > line extends beyond the swarm of data points to the defined of default > plot region. With par(xpd=T) it will span the entire figure region. But > how can I limit a regression line to the data range, i.e between > (xmin,ymin) and (xmax,ymax)? > > Sorry for not knowing the lingo here. If you don't understand the > question, please run the following script: > > x1<-c(1,2,3,4) > x2<-c(5,6,7,8) > y1<-c(2,4,5,8) > y2<-c(10,11,12,16) > plot(x1,y1,xlim=c(0,10),ylim=c(0,20),col="blue") > points(x2,y2,col="red") > abline(lm(y1~x1),col="blue") > abline(lm(y2~x2),col="red") > > The resulting plot isn't very informative. There is no overlap in the > two groups of data, yet the two ablines overlap. > I instead want the blue line to go from (1,2) to (4,8) and the red line > from (5,10) to (8,16). > > So, how can I constrain the abline to the relevant region, i.e stop > abline from extrapolating beyond the actual range of data. > Or should I use a function line 'lines' to do this? > > Cheers > AndresTry this instead of the two abline()'s: lines(x1, fitted(lm(y1 ~ x1)), col = "blue") lines(x2, fitted(lm(y2 ~ x2)), col = "red") The function fitted() will extract the model fitted y values from the lm() model object. See ?lines and ?fitted HTH, Marc Schwartz
For single lines the usual method is to just use the lines or segments function, however I have been thinking that there may be some other uses for clipping within a plot region when adding info (abline, but others as well). So here is a first stab at a function to clip within the region, it needs the TeachingDemos package to work. I'll probably put in some more error checking, document it and include it in a future TeachingDemos release, but you are welcome to use it in the meantime. For your case you would create your scatterplot the same as you already did, then add the lines like:> clipplot( abline(lm(y1~x1),col="blue"), xlim=c(1,4) ) > clipplot( abline(lm(y2~x2),col="red"), xlim=c(5,8) )Here is the function definition: clipplot <- function(fun, xlim=par('usr')[1:2], ylim=par('usr')[3:4] ){ old.par <- par(c('plt','xpd')) if( length(xlim) < 2 ) stop('xlim must be a vector with at least 2 elements') if( length(ylim) < 2 ) stop('ylim must be a vector with at least 2 elements') if( !require(TeachingDemos) ) stop('TeachingDemos package needed') xl <- range(xlim) yl <- range(ylim) pc <- cnvrt.coords(xl,yl)$fig par(plt=c(pc$x,pc$y),xpd=FALSE) fun par(old.par) box() # need to plot something to reset } Hope this helps, -- Gregory (Greg) L. Snow Ph.D. Statistical Data Center Intermountain Healthcare greg.snow at intermountainmail.org (801) 408-8111 -----Original Message----- From: r-help-bounces at stat.math.ethz.ch [mailto:r-help-bounces at stat.math.ethz.ch] On Behalf Of Andreas Svensson Sent: Wednesday, May 24, 2006 10:52 AM To: r-help at stat.math.ethz.ch Subject: [R] Regression line limited by the rage of values Hi In R, using plot(x,y) followed by abline(lm(y~x)) produces a graph with a regression line spanning the whole plot . This means that the line extends beyond the swarm of data points to the defined of default plot region. With par(xpd=T) it will span the entire figure region. But how can I limit a regression line to the data range, i.e between (xmin,ymin) and (xmax,ymax)? Sorry for not knowing the lingo here. If you don't understand the question, please run the following script: x1<-c(1,2,3,4) x2<-c(5,6,7,8) y1<-c(2,4,5,8) y2<-c(10,11,12,16) plot(x1,y1,xlim=c(0,10),ylim=c(0,20),col="blue") points(x2,y2,col="red") abline(lm(y1~x1),col="blue") abline(lm(y2~x2),col="red") The resulting plot isn't very informative. There is no overlap in the two groups of data, yet the two ablines overlap. I instead want the blue line to go from (1,2) to (4,8) and the red line from (5,10) to (8,16). So, how can I constrain the abline to the relevant region, i.e stop abline from extrapolating beyond the actual range of data. Or should I use a function line 'lines' to do this? Cheers Andres ______________________________________________ R-help at stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
Karl Ove Hufthammer
2006-May-25 08:57 UTC
[R] Regression line limited by the rage of values
Andreas Svensson wrote:> So, how can I constrain the abline to the relevant region, i.e stop > abline from extrapolating beyond the actual range of data. > Or should I use a function line 'lines' to do this?One elegant way of doing this is using 'xyplot' from 'lattice' and adding a loess line with a large value of 'span' (which basically makes is equal to the ordinary least-squares regression line). Here's a simple example: library(lattice) data(iris) xyplot(Petal.Length~Petal.Width, groups=Species, type=c("p","smooth"), span=100, data=iris) -- Karl Ove Hufthammer