我试图使用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()的任务?答案 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)
......就这样,你可以解决混合正态分布和对数正态分布。