r中散点图的回归线和拟合曲线

时间:2014-07-05 08:07:57

标签: r plot

我有一组树木的高度和直径数据。我想找到它们之间的回归关系并绘制它。例如,我想尝试a * DIAMETER + b * DIAMETER^2 + C并在散点图中显示其曲线。 通过bellow指令我达到了几行,但我只想要一个与开发模型相关的趋势线。我该怎么办?

setwd('D:\\PhD\\Data\\Field Measurments\\Data Analysis\\')

dat1 = read.table('Fagus.csv', header = TRUE, sep =',')


# fit a non-linear regression

Height = dat1$Height

Diameter = dat1$Diameter 

plot(Diameter, Height, main="Height Curve", xlab="Diameter", ylab="Height", pch=19)

nls1 <- nls(Height ~ a*(Diameter)^2+b*Diameter+c, data = dat1, start = list(a =a, b=b,c=c), algorithm="port")

lines(fitted(nls1) ~ Diameter, lty = 1, col = "red") # solid red line

上述指示是否符合我的目的?

3 个答案:

答案 0 :(得分:1)

如上所述,您不应将系数放入公式中。尝试:

nls1 <- nls(Height ~ I(Diameter^2) + Diameter, data = dat1,  algorithm="port")

关于I(Diameter ^2)
“为了避免这种混淆,可以使用函数I()来包含模型公式的那些部分,其中运算符在算术意义上使用。例如,在公式y ~ a + I(b+c)中,术语{{ 1}}被解释为b和c的总和。“ 〜b+c文档

我没有运行其余的(在移动设备上),但乍一看你的代码看起来还不错。

答案 1 :(得分:1)

这里似乎存在关于线性与非线性模型的误解。线性模型是系数中的线性。非线性模型不是。模型在预测变量中是否是线性的(在您的情况下是直径)是无关紧要的。因此,在您的情况下,形式的模型:

  

高度= a *直径+ b *直径^ 2 + c

线性模型。您不需要使用nls(...)。您可以用两种方式指定模型公式,这两种方式都会产生相同的结果:

Height~Diameter + I(Diameter^2)

Height~poly(Diameter,2,raw=TRUE)

第二种形式使用poly(...)函数创建阶数为2的多项式。raw=T告诉poly(...)生成原始多项式,而不是正交多项式(默认值)。除非你想要大于2的多项式,否则第一种形式会更简单一些。这是一个使用两种形式的例子。

set.seed(1)    # for reproducible example
df <- data.frame(Diameter=sample(1:50,50))
df$Height <- with(df,2*Diameter + .5*Diameter^2 + 4 + rnorm(50,sd=30))

fit <- lm(Height~Diameter + I(Diameter^2),df)
summary(fit)
# ...
# Coefficients:
#               Estimate Std. Error t value Pr(>|t|)    
# (Intercept)   -6.85088   12.26720  -0.558  0.57917    
# Diameter       3.31030    1.10964   2.983  0.00451 ** 
# I(Diameter^2)  0.47717    0.02109  22.622  < 2e-16 ***

fit.poly<- lm(Height~poly(Diameter,2,raw=TRUE),df)
summary(fit.poly)
# Coefficients:
#                                Estimate Std. Error t value Pr(>|t|)    
# (Intercept)                    -6.85088   12.26720  -0.558  0.57917    
# poly(Diameter, 2, raw = TRUE)1  3.31030    1.10964   2.983  0.00451 ** 
# poly(Diameter, 2, raw = TRUE)2  0.47717    0.02109  22.622  < 2e-16 ***

绘制数据和趋势曲线:

df$pred <- predict(fit)
with(df,plot(Height~Diameter))
with(df[order(df$Diameter),],lines(pred~Diameter,col="red",lty=2))

答案 2 :(得分:0)

您的问题是start=参数。您需要提供abc参数的实际值。这是一个可重现的例子

#sample data
dat<-data.frame(Diameter = runif(50, 2, 6))
dat<-transform(dat,Height=2*Diameter + .75 * Diameter^2 +4 + rnorm(50))
dat<-dat[order(dat$Diameter), ]

#now fit the model
mynls<-nls(Height ~ a*I(Diameter^2) + b*Diameter + c, dat,
    start=list(a=1, b=1, c=1), algorithm="port")

注意我们如何为每个系数设置默认值1。您可以设置您认为最合适的任何内容。以及如何使用拟合结果绘制原始值

plot(Height~Diameter,dat, main="Height Curve", 
    xlab="Diameter", ylab="Height", pch=19)
lines(fitted(mynls)~ dat$Diameter, col="red")

这给出了

enter image description here