8

If I have a set of points in R that are linear I can do the following to plot the points, fit a line to them, then display the line:

x=c(61,610,1037,2074,3050,4087,5002,6100,7015)
y=c(0.401244, 0.844381, 1.18922, 1.93864, 2.76673, 3.52449, 4.21855, 5.04368, 5.80071)

plot(x,y)    
Estimate = lm(y ~ x)    
abline(Estimate)

Now, if I have a set of points that looks like a logarithmic curve fit is more appropriate such as the following:

x=c(61,610,1037,2074,3050,4087,5002,6100,7015)        
y=c(0.974206,1.16716,1.19879,1.28192,1.30739,1.32019,1.35494,1.36941,1.37505)

I know I can get the standard regression fit against the log of the x values with the following:

logEstimate = lm(y ~ log(x))

But then how do I transform that logEstimate back to normal scaling and plot the curve against my linear curve from earlier?

Andre Silva
  • 4,782
  • 9
  • 52
  • 65
user52291
  • 161
  • 2
  • 2
  • 4

2 Answers2

13

Hmmm, I'm not quite sure what you mean by "plot the curve against my linear curve from earlier".

d <- data.frame(x,y)  ## need to use data in a data.frame for predict()
logEstimate <- lm(y~log(x),data=d)

Here are three ways to get predicted values:

(1) Use predict:

plot(x,y)
xvec <- seq(0,7000,length=101)
logpred <- predict(logEstimate,newdata=data.frame(x=xvec))
lines(xvec,logpred)

(2) Extract the numeric coefficient values:

coef(logEstimate)
## (Intercept)      log(x) 
##  0.6183839   0.0856404 
curve(0.61838+0.08564*log(x),add=TRUE,col=2)

(3) Use with() magic (you need back-quotes around the parameter estimate names because they contain parentheses)

with(as.list(coef(logEstimate)),
      curve(`(Intercept)`+`log(x)`*log(x),add=TRUE,col=4))

Maybe what you want is

est1 <- predict(lm(y~x,data=d),newdata=data.frame(x=xvec))
plot(est1,logpred)

... although I'm not sure why ...

Ben Bolker
  • 211,554
  • 25
  • 370
  • 453
  • Thank you very much. Your second way, with the curve function, is exactly what I wanted. What exactly does framing the data do and what does predict do? I didn't get much out of what the help() function told me. – user52291 Jul 19 '12 at 22:36
  • 2
    putting the data in a data frame makes future work with the fitted object (predictions, etc.) more straightforward because it makes it easier for R to locate the input variables. `predict()` predicts ... – Ben Bolker Jul 20 '12 at 03:18
10

I'm not exactly sure what you mean either... but I guessed a little different. I think you want to fit two models to those points, one linear, and one logged. Then, you want to plot the points, and the functional form of both models. Here is the code for that:

x=c(61,610,1037,2074,3050,4087,5002,6100,7015)
y=c(0.974206,1.16716,1.19879,1.28192,1.30739,1.32019,1.35494,1.36941,1.37505)

Estimate = lm(y ~ x)
logEstimate = lm(y ~ log(x))

plot(x,predict(Estimate),type='l',col='blue')
lines(x,predict(logEstimate),col='red')
points(x,y)

enter image description here


In response to your second question in the comment, linear regression does always return a linear combination of your predictors, but that doesn't necessarily mean that it is a straight line. Think about what your log transformation really means: If you fit,

y = log(x)

that is the same as fitting

exp(y) = x

Which means that as x increases linearly, then y will change exponentially, which is clearly not a 'straight line'. However, if you transformed your x-axis on the log scale, then the displayed line would be straight.

nograpes
  • 18,623
  • 1
  • 44
  • 67
  • 1
    just note that if you want a smooth logarithmic curve you need to use the `newdata` form of predict ... and the results will be weird if your data don't happen to be in increasing `x` order ... (but the basic idea is sound) – Ben Bolker Jul 19 '12 at 21:24
  • Agreed. I thought I would go for simplicity over correctness, but you are completely correct. – nograpes Jul 19 '12 at 21:28
  • Thanks. This gives me what I wanted as well (although not smooth like with the curve function). I am a little confused because I thought lm always returns a line. What is it about your code that made a curve and not line show up? – user52291 Jul 19 '12 at 22:41