В дополнение к моему комментарию выше, мне не ясно, что вы пытаетесь сделать. Если вы хотите смоделировать ставку Growth
, вам нужно соответствовать какой-либо форме модели.
Для начала, как насчет экспоненциальной модели вида y = y0 * exp(k * time)
?
В этом случае мы можем линеаризовать модель (и данные), взяв журнал, а затем использовать lm
для оценки коэффициентов модели log(y0)
и k
.
df <- corona_entire %>% mutate(Time = as.integer(Date - min(Date)))
fit <- lm(log(Growth) ~ Time, weights = df$Growth, data = df)
Здесь я использовал взвешенные наименьшие квадраты подходить, взвешивая каждую точку по ее скорости Growth
.
Затем мы можем построить точки и кривую наилучшего соответствия:
f <- function(x, fit) exp(coef(fit)[1])*exp(coef(fit)[2] * x)
ggplot(df, aes(Time, Growth)) +
geom_point() +
stat_function(fun = f, args = list(fit = fit)) +
labs(x = sprintf("Days since %s", min(df$Date)))
![enter image description here](https://i.stack.imgur.com/f5Peb.png)
Не совсем подходит, но это должно дать вам некоторые идеи. Вы, вероятно, хотите подобрать более подходящую нелинейную модель скорости роста и оценить параметры, используя nls
.
Обновление
Поскольку вы действительно хотите предсказать Cases
, давайте переформулируем нашу модель.
Мы начнем снова с экспоненциальной модели вида Cases ~ y0 * exp(k * Time)
ggplot(df, aes(Time, Cases)) +
geom_point()
fit1 <- lm(log(Cases) ~ Time, data = df)
f1 <- function(x, fit) exp(coef(fit)[1])*exp(coef(fit)[2] * x)
ggplot(df, aes(Time, Cases)) +
geom_point() +
stat_function(fun = f1, args = list(fit = fit1)) +
labs(x = sprintf("Days since %s", min(df$Date)))
![enter image description here](https://i.stack.imgur.com/M8Lut.png)
Не совсем подходит! Результаты указывают на субэкспоненциальный рост. Простая модель субэкспоненциального роста в эпидемиологии - это модель вида Cases ~ (r / m * Time + A)^m
, см., Например, Chowell et al., Phys. Life Rev. 18, 66 (2016) .
Итак, давайте подгоним модель, на этот раз с помощью нелинейной процедуры наименьших квадратов nls
.
fit2 <- nls(
Cases ~ (r / m * Time + A)^m,
data = df,
start = list(r = 4, m = 3, A = 1))
f2 <- function(x, r, m, A) (r / m * x + A)^m
ggplot(df, aes(Time, Cases)) +
geom_point() +
stat_function(
fun = f2,
args = list(
r = coef(fit2)[1],
m = coef(fit2)[2],
A = coef(fit2)[3])) +
labs(x = sprintf("Days since %s", min(df$Date)))
![enter image description here](https://i.stack.imgur.com/aj2RZ.png)
Выглядит как приличная посадка. Вы можете проверить качество подгонки и нелинейных оценок наименьших квадратов для коэффициентов, если вы наберете summary(fit2)
summary(fit2)
#
#Formula: Cases ~ (r/m * Time + A)^m
#
#Parameters:
# Estimate Std. Error t value Pr(>|t|)
#r 2.3308 0.6543 3.562 0.00391 **
#m 3.3316 0.4202 7.929 4.12e-06 ***
#A 2.1101 0.3126 6.750 2.04e-05 ***
#---
#Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#
#Residual standard error: 51.41 on 12 degrees of freedom
#
#Number of iterations to convergence: 6
#Achieved convergence tolerance: 6.514e-07
#