NlS多重高斯,自动生成公式

时间:2014-06-03 20:58:02

标签: r gaussian nls

我使用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)

来引用它

1 个答案:

答案 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