我使用NLS来拟合激光雷达波形数据。它似乎适用于3或4个峰值。 for(i in 1:3){ 平均值< - c(mean,realind [i]) }
sd=runif(3,6,20)
c=runif(3,100,250)
df<-data.frame(x=seq_along(y),y)
fit<-nls(y ~(c1 * exp(-(x - mean1)**2/(2 * sigma1**2)) +
c2 * exp(-(x - mean2)**2/(2 * sigma2**2))+
c3 * exp(-(x - mean3)**2/(2 * sigma3**2))), data=df,
start=list(c1=c[1], mean1=mean[1], sigma1=sd[1],
c2=c[2], mean2=mean[2], sigma2=sd[2],
c3=c[3], mean3=mean[3], sigma3=sd[3]), algorithm="port")
但问题是每次你必须手动编写这个长公式和参数的开始。所以我想知道如何通过循环自动生成函数,然后公式= y~f(x,c,mean,sd)并且也可以通过循环生成start。并确保这些可以在nls中工作。另外我希望你们能给我一些关于多峰高斯拟合的建议,我试过GPfit,GMM。
在本网站上也遇到同样问题的人,但是没有得到令人满意的答案。您可以通过nls when the data is a convoluted spectra (variable number of variables)
来引用它答案 0 :(得分:0)
你在这里挤了很多问题。我会回答看似主要的问题。您可以将公式构建为字符串。然后你可以将它转换为公式。使用您想要的初始参数构建列表并不困难。这是一个这样的功能
gennls <- function(c, mean, sd) {
n <- seq_along(c)
fs <- paste("y ~",
paste(
paste0("c",n, " * exp(-(x-mean",n,")**2/(2 * sigma",n,"**2))"),
collapse=" + ")
)
names(c)<-paste0("c",seq_along(c))
names(mean)<-paste0("mean",seq_along(c))
names(sd)<-paste0("sigma",seq_along(sd))
list(
formula=as.formula(fs),
start=c(as.list(c), as.list(mean), as.list(sd))
)
}
然后你可以用
运行它init <- gennls(runif(3), runif(3), runif(3))
这将返回一个带有公式的列表
init$formula
# y ~ c1 * exp(-(x - mean1)^2/(2 * sigma1^2)) + c2 * exp(-(x -
# mean2)^2/(2 * sigma2^2)) + c3 * exp(-(x - mean3)^2/(2 * sigma3^2))
和初始参数
str(iniy$start)
# List of 9
# $ c1 : num 0.883
# $ c2 : num 0.0521
# $ c3 : num 0.664
# $ mean1 : num 0.665
# $ mean2 : num 0.902
# $ mean3 : num 0.449
# $ sigma1: num 0.672
# $ sigma2: num 0.429
# $ sigma3: num 0.865