Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fitting logarithmic curve in R

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?

like image 990
user52291 Avatar asked Jul 19 '12 20:07

user52291


2 Answers

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 ...

like image 95
Ben Bolker Avatar answered Sep 22 '22 23:09

Ben Bolker


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.

like image 25
nograpes Avatar answered Sep 22 '22 23:09

nograpes