在R中拟合对数曲线

8
如果我有一组在R中呈线性分布的点,我可以按照以下步骤绘制这些点并拟合一条直线,然后将其显示出来:
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)

现在,如果我有一组点看起来更适合于对数曲线拟合,就像下面这样:
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)

我知道可以通过以下方式得到对x值的对数进行标准回归拟合:

logEstimate = lm(y ~ log(x))

但是,我如何将logEstimate转换回正常比例,并将曲线与先前的线性曲线绘制在一起呢?
2个回答

13

嗯,我不太确定你所说的 "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)

以下是三种获取预测值的方法:

(1) 使用predict函数:

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

(2) 提取数值系数的值:

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

(3) 使用with()魔法函数(需要在参数估计名称周围加上反引号,因为它们包含括号)

with(as.list(coef(logEstimate)),
      curve(`(Intercept)`+`log(x)`*log(x),add=TRUE,col=4))
也许你想要的是什么是:
est1 <- predict(lm(y~x,data=d),newdata=data.frame(x=xvec))
plot(est1,logpred)

虽然我不确定为什么...


非常感谢。您的第二种方法,使用曲线函数,正是我想要的。“Framing the data”具体是什么意思?“Predict”又是做什么的?帮助函数并没有让我理解得很清楚。 - user52291
2
将数据放入数据框中,可以使未来与拟合对象(预测等)的工作更加简单,因为这样可以更容易地让 R 定位输入变量。predict()函数可以进行预测... - Ben Bolker

10

我也不太确定你的意思……但是我猜测有些不同。我认为你想要将这些点拟合成两个模型,一个是线性的,另一个是对数的。然后,你想要绘制这些点和两个模型的函数形式。以下是代码:

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


回答您在评论中的第二个问题,线性回归确实总是返回预测变量的线性组合,但这并不一定意味着它是一条直线。想想您的log转换实际上意味着什么:如果您进行拟合,

y = log(x)

那就是适配的意思

exp(y) = x

这意味着随着x的线性增加,y将呈指数变化,这显然不是一条'直线'。但是,如果你将x轴转换为对数比例,则显示的线条将是直线。

1
请注意,如果您想要一个平滑的对数曲线,您需要使用predictnewdata形式...如果您的数据不是按照递增的x顺序排列,结果可能会很奇怪...(但基本思路是正确的) - Ben Bolker
同意。我本来想追求简单而不是正确性,但你完全正确。 - nograpes
谢谢。这也给了我想要的结果(虽然不像曲线函数那样平滑)。我有点困惑,因为我以为lm总是返回一条直线。你的代码有什么特别之处,让曲线而不是直线出现? - user52291

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接