Подгонка nls () в r, когда некоторые значения x равны нулю - PullRequest
0 голосов
/ 05 марта 2020

Можно ли рассчитать регрессию NLS, если у вас есть x = 0?

mydf <- structure(list(x = c(0, 25.8, 51.6, 77.4, 103.2, 129, 154.8, 
                             180.6, 206.4, 232.2, 258), y = c(1, 0.04347826, 0.021739129, 
                                                              0.013888888, 0.010869564, 0.008620688, 0.007299269, 0.006289307, 
                                                              0.005405404, 0.004830917, 0.004329003)), class = "data.frame", row.names = c(NA, 
                                                                                                                                           -11L))

lmod <- lm(log(y) ~ log(x), data = mydf)

a_start <- exp(lmod$coefficients[[1]])
b_start <- lmod$coefficients[[2]]

nlmod <- nls(y ~ a*x^b, data = mydf, 
             start = list(a = a_start,
                          b = b_start))

library(ggplot2)
ggplot(mydf, aes(x = x, y = y)) +
  geom_point() +
  stat_smooth(method = 'nls', formula = y~a*x^b, 
              method.args = list(start = c(a = a_start,b = b_start)),
              se=FALSE)

Это приводит к следующим ошибкам из-за log(0).

Error in lm.fit(x, y, offset = offset, singular.ok = singular.ok, ...) : 
  NA/NaN/Inf in 'x'

Error in numericDeriv(form[[3L]], names(ind), env) : 
  Missing value or an infinity produced when evaluating the model

Очевидно, это работает когда я фильтрую по x>0, но y ограничивается 1, поскольку это пропорция, и при использовании x>0 только мы получаем значения, где y>1.

1 Ответ

2 голосов
/ 05 марта 2020

Используйте pmax(x, 1) вместо x и немного упростите, используя nls для начальных значений:

fm0 <- nls(log(y) ~ log(a * pmax(x, 1)^b), mydf, start = list(a = 1, b = 1))
fm1 <- nls(y ~ a * pmax(x, 1)^b, mydf, start = coef(fm0)) 

Обновление

Внес ряд улучшений.

...