在R中使用lm和nls拟合正弦曲线

时间:2013-11-20 19:03:49

标签: r curve-fitting

我是曲线拟合的初学者,Stackoverflow上的几篇文章对我有帮助。

我尝试使用lmnls将正弦曲线拟合到我的数据中,但两种方法都显示出奇怪的拟合,如下所示。谁能指出我哪里出错了。我怀疑与时间有关,但无法做到正确。我的数据可以从here访问。 plot

data <- read.table(file="900days.txt", header=TRUE, sep="")
time<-data$time
temperature<-data$temperature

#lm fitting
xc<-cos(2*pi*time/366)
xs<-sin(2*pi*time/366)
fit.lm<-lm(temperature~xc+xs)
summary(fit.lm)
plot(temp~time, data=data, xlim=c(1, 900))
par(new=TRUE)
plot(fit.lm$fitted, type="l", col="red", xlim=c(1, 900), pch=19, ann=FALSE, xaxt="n",
yaxt="n")

#nls fitting
fit.nls<-nls(temp~C+alpha*sin(W*time+phi),
   start=list(C=27.63415, alpha=27.886, W=0.0652, phi=14.9286))
summary(fit.nls)
plot(fit.nls$fitted, type="l", col="red", xlim=c(1, 900), pch=19, ann=FALSE, xaxt="n", 
axt="n")

4 个答案:

答案 0 :(得分:9)

这是因为要从适合的数据中删除NA值(并且您的数据中有相当多的数据);因此,当您绘制fit.lm$fitted时,绘图方法将该系列的索引解释为'x'值以对其进行绘制。

试试这个[请注意我如何更改变量名称以防止与函数timedata(阅读this帖子)]冲突:

Data <- read.table(file="900days.txt", header=TRUE, sep="")
Time <- Data$time 
temperature <- Data$temperature

xc<-cos(2*pi*Time/366)
xs<-sin(2*pi*Time/366)
fit.lm <- lm(temperature~xc+xs)

# access the fitted series (for plotting)
fit <- fitted(fit.lm)  

# find predictions for original time series
pred <- predict(fit.lm, newdata=data.frame(Time=Time))    

plot(temperature ~ Time, data= Data, xlim=c(1, 900))
lines(fit, col="red")
lines(Time, pred, col="blue")

这给了我:

enter image description here

这可能是你所希望的。

答案 1 :(得分:4)

如何选择X和Y而不是选择Y.

plot(time,predict(fit.nls),type="l", col="red", xlim=c(1, 900), pch=19, ann=FALSE, xaxt="n",
yaxt="n")

同时,lmnls都会为您提供拟合点数。因此,您必须估算其余的点,以便制作曲线,线图。由于您使用的是nlslm,因此函数predict可能很有用。

答案 2 :(得分:1)

不确定这是否有帮助 - 我只使用正弦得到类似的拟合:

y = amplitude * sin(pi * (x - center) / width) + Offset

amplitude =  2.0009690806953033E+00
center = -2.5813588834888215E+01
width =  1.8077550471975817E+02
Offset =  2.6872265116104828E+01

Fitting target of lowest sum of squared absolute error = 3.6755174406241423E+01

Degrees of freedom (error): 90
Degrees of freedom (regression): 3
Chi-squared: 36.7551744062
R-squared: 0.816419142696
R-squared adjusted: 0.810299780786
Model F-statistic: 133.415731033
Model F-statistic p-value: 1.11022302463e-16
Model log-likelihood: -89.2464811027
AIC: 1.98396768304
BIC: 2.09219299292
Root Mean Squared Error (RMSE): 0.625309918107

amplitude = 2.0009690806953033E+00
       std err squared: 1.03828E-02
       t-stat: 1.96374E+01
       p-stat: 0.00000E+00
       95% confidence intervals: [1.79853E+00, 2.20340E+00]
center = -2.5813588834888215E+01
       std err squared: 2.98349E+01
       t-stat: -4.72592E+00
       p-stat: 8.41245E-06
       95% confidence intervals: [-3.66651E+01, -1.49621E+01]
width = 1.8077550471975817E+02
       std err squared: 3.54835E+00
       t-stat: 9.59680E+01
       p-stat: 0.00000E+00
       95% confidence intervals: [1.77033E+02, 1.84518E+02]
Offset = 2.6872265116104828E+01
       std err squared: 5.15458E-03
       t-stat: 3.74289E+02
       p-stat: 0.00000E+00
       95% confidence intervals: [2.67296E+01, 2.70149E+01]

Coefficient Covariance Matrix
[ 0.02542366 0.01786683 -0.05016085 -0.00652111]
[ 1.78668314e-02 7.30548346e+01 -2.18160818e+01 1.24965136e-01]
[ -5.01608451e-02 -2.18160818e+01 8.68860810e+00 -1.27401806e-02]
[-0.00652111 0.12496514 -0.01274018 0.0126217 ]
詹姆斯菲利普斯 zunzun@zunzun.com

答案 3 :(得分:0)

或者,您可以在阅读之后从数据中删除NA:

data <- subset(data, !is.na(temperature))

然后,在绘图时,您可以将x轴设置为缩小数据集中的时间点:

plot(temp~time, data=data, xlim=c(1, 900))
lines(x=time, y=fit.lm$fitted, col="red")

这条曲线不会像@ andy-barbour那样平滑,但它会在紧要关头工作。