我有一组树木的高度和直径数据。我想找到它们之间的回归关系并绘制它。例如,我想尝试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
上述指示是否符合我的目的?
答案 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=
参数。您需要提供a
,b
和c
参数的实际值。这是一个可重现的例子
#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")
这给出了