nls峰拟合与混合正态和对数正态数据集(R)

时间:2015-06-02 23:07:35

标签: r curve-fitting nls

我试图使用nls()来曲线拟合由正态和对数正态分布值的混合组成的数据集。但是,正态分布的子集包含对数正态函数不能容忍的负值。使用nls(),有没有办法约束拟合曲线的PORTION评估的值? (例如,让正常函数在0之间进行求值并强制对数正态函数仅评估x> 0)

这是我一直在玩的测试案例:

test <- rnorm(5000, 2, 2)
test2 <- rlnorm(10000,2,2)
test3 <- append(test, test2)

bins <- seq(min(test3),100, .1)
tops <- data.frame(bin=bins, count=NA)
for (i in 1:nrow(tops)) {  tops[i,2] <- length(test3[which(test3>=tops[i,1] & 
     test3<tops[i+1,1])])  }

fit <- nls(count ~ exp(-(bin-n.mu)^2/(2*n.sd^2))/(sqrt(2*pi)*n.sd)*C1 + 
         exp(-(log(bin)-l.mu)^2/(2*l.sd^2))/(sqrt(2*pi)*l.sd*bin)*C2,
         data=tops, start=list(n.mu=2, n.sd=2, C1=500, l.mu=2, l.sd=2, C2=1000), 
         algorithm="port", trace=T)

coef(fit)
topsfit <- data.frame(bin=seq(-3, 100, 0.1))
topsfit$fit <- predict(fit, newdata=topsfit)

ggplot() + geom_point(data=tops, aes(x=(bins), y=count), shape=1, size=4) + 
  geom_path(data=topsfit, aes(x=(bin), y=fit), colour="red", size=1.5) 

非常简单,我正在拟合普通的PDF +对数正态PDF。问题是对数正态PDF中的log(bin)与负数不一致......但我不想裁剪负值,因为这会影响基础的正态分布值的计算。我只想让曲线的对数正常一半忽略它们。

或者,是否有不同的方法来完成这项不依赖于nls()的任务?

1 个答案:

答案 0 :(得分:1)

似乎没有人愿意触及这个主题,所以我会发布一个我在非互联网同志的帮助下想出的解决方案 - 我的问题的关键在于产生将构成的功能我的曲线。分别编写对数正态函数允许对x值进行条件评估,这正是我所需要的。一旦我发现nls()函数对向量进行操作并编写了我的函数来匹配,事情很好地形成了。

normal <- function(x, mu, sd, C) {  
  ans <- vector(length = length(x), mode = "numeric")
  for (i in 1:length(x)) {  
    value <- exp(-(x[i]-mu)^2/(2*sd^2))/(sqrt(2*pi)*sd)*C
    ans[i] <- value
  };  return(ans)  }

lognormal <- function(x, mu, sd, C) {
  ans <- vector(length = length(x), mode = "numeric")
  for (i in 1:length(x)) {
    if (x[i]>0) {
      value <- exp(-(log10(x[i])-mu)^2/(2*sd^2))/(sqrt(2*pi)*sd*x[i])*C
      ans[i] <- value
    }  else {  ans[i] <- 0  }  };  return(ans)  }


fit <- nls(count ~ normal(bin, n.mu, n.sd, C1) + lognormal(bin, l.mu, l.sd, C2),
             data=tops, start=list(n.mu=30, n.sd=30, C1=5000, 
             l.mu=4, l.sd=2, C2=5000), algorithm="port", trace=T)

......就这样,你可以解决混合正态分布和对数正态分布。