Time-varying estimation of machine learning models and their forecasts

[This article was first published on R-Blog on Data modelling to develop ..., and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Introduction

The advent of the COVID-19 pandemic really put everyone in confusion and as the days, weeks went-by, everyone was trying to understand the trend and the direction of the incidence. While the medicals were in their labs trying to understand the anatomy of the various, various statisticians and data scientists were trying to model the trend so as to guide future actions and preparations. One of the early models was done for Australia by (Krispin and Byrnes 2020). After observing the beatifuly animations of the incidence of the virus in the various regions of Australia, the motivation to do so was kindled. However, the first setback was the format the Nigerian Centre for Disease Control (NCDC) (NCDC 2020) was publishing the incidence in Nigeria was not very #RStats (R Core Team 2020) friendly. There were two main issues:

  1. The data was and has been hard-formatted using the comma thousand separator which was and has remain difficult to easily analysed so alternative means of removing the format had to be worked out.

  2. The data supplied by NCDC to the main collation centre of the COVID-19 at the Johns Hopkins University Center for Systems Science and Engineering (JHU-CCSE) (CCSE 2020) was not disaggregated by regions as in the case of Australia, therefore, the data had to be manualy compiled from the website (https://covid19.ncdc.gov.ng/) of the agency.

For the above two reasons, the animation for Nigeria could not be achieved almost immediately. After the initial manual compilation of the data set from NCDC, an animation of the incidence in Nigeria was made on the 3rd of May, 2020 as shown below.

Thereafter, daily summaries, trend of the observed cases and possible future path through modeling and forecasting were made once the data is updated. The forecast lenght was usually the total length of the observed data which entually led to the concept of equal length forecast. It was in this wise that it was observed that the changes in forecast with just a additional day’s data were quite alarming. Hence there was need to have a way of quickly comparing time-variant forecasts. After careful consideration, the concept was synthesized into the Dyn4cast package (Nmadu 2020). Presently, the package has five functions.

  • DynamicForecast

  • constrainedforecast

  • linearsystems

  • MLMetrics

  • MallowsCP

  • Percent

  • quicksummary

  • scaledlogit

  • invscaledlogit

The package is currently available in GitHub and can be installed as follows:

devtools::install_github("JobNmadu/Dyn4cast").

In this blog, the capabilities of the DynamicForecast function is explored.

Load the library and format the data

The sample data is the daily COVID-19 cases recorded and aggregagted into national data. The break points used for the splines modelling were established via visual examination of the observed data. The data cover the period 2020-02-29 to 2021-02-10.

library(Dyn4cast)
data <- COVID19
data$Date <- as.Date(data$Date, format = '%m/%d/%Y')
Dss <- seq(data$Date[1], by = "day", length.out = length(data$Case))
lastdayfo21 <- Dss[length(Dss)]
BREAKS = c(70, 131, 173, 228, 274)

Modelling and forecast for the full data range

The constrained and unconstrained forecast are presented for compaison but the right one is the constrained forecast. It was necessary to consraine the forecast to the positive quadrant since ther is no zero and negative observations.

Days_full <- DynamicForecast(Data = data, BREAKS = BREAKS, MaximumDate = "2021-02-10", Trend = "Day", Length = 0, Type = "Integer")
summary(Days_full$`Ensembled based on summed weight`)
##
## Call:
## stats::lm(formula = Data$Day ~ Without.knots + With.knots + Smooth +
## Quadratic + ARIMA)
##
## Residuals:
## Min 1Q Median 3Q Max
## -120.67 -28.15 13.12 37.93 46.22
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.514e+01 4.148e+00 10.883 <2e-16 ***
## Without.knots 1.082e-05 1.756e-02 0.001 1.000
## With.knots 2.875e-04 5.390e-02 0.005 0.996
## Smooth -2.335e-04 6.355e-02 -0.004 0.997
## Quadratic 3.094e-01 1.363e-02 22.696 <2e-16 ***
## ARIMA -6.179e-05 2.773e-02 -0.002 0.998
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 44.28 on 342 degrees of freedom
## Multiple R-squared: 0.809, Adjusted R-squared: 0.8062
## F-statistic: 289.8 on 5 and 342 DF, p-value: < 2.2e-16
knitr::kable(as.data.frame(Days_full$`Unconstrained Forecast`),
row.names = FALSE, "html")
Model Case
Linear 462222
Semilog 261819
Growth 3158
Without knots 2252100
Smooth Spline -2371123
With knots -1885886
Quadratic Polynomial 857816
Lower ARIMA -275249
Upper ARIMA 945658
Essembled with equal weight 347332
Essembled based on weight 121434
Essembled based on summed weight 280048
Essembled based on weight of fit 323205
knitr::kable(as.data.frame(Days_full$`Constrained Forecast`),
row.names = FALSE, "html")
Model Confirmed cases
Linear 462222
Semilog 261819
Growth 3158
Without knots 80% 126351
Without knots 95% 682497
Smooth Spline 80% 115078
Smooth Spline 95% 700622
With knots 80% 446278
With knots 95% 818931
Quadratic Polynomial 80% 732790
Quadratic Polynomial 95% 769773
ARIMA 80% 22070
ARIMA 95% 925882
Essembled with equal weight 80% 178649
Essembled with equal weight 95% 763216
Essembled based on weight 80% 32107
Essembled based on weight 95% 615990
Essembled based on summed weight 80% 325740
Essembled based on summed weight 95% 396643
Essembled based on weight of fit 80% 145002
Essembled based on weight of fit 95% 753542
knitr::kable(as.data.frame(Days_full$RMSE), row.names = FALSE, "html")
Models RMSE
Linear 369.14
Semilog 397.82
Growth 612.54
Without knots 268.34
Smooth Spline 201.62
With knots 189.71
Quadratic Polynomial 346.37
Lower ARIMA 210.57
Upper ARIMA 210.57
Essembled with equal weight 213.84
Essembled based on weight 471.14
Essembled based on summed weight 469.08
Essembled based on weight of fit 288.98
Days_full$`Unconstrained forecast Plot`

Days_full$`Constrained forecast Plot`

Modelling and forecast by using data as at 28 days earlier

KK_28 <- data[data$Date <= lastdayfo21 - 28, ]
Days_28 <- DynamicForecast(Data = KK_28, BREAKS = BREAKS, MaximumDate = "2021-02-10", Trend = "Day", Length = 0, Type = "Integer")
summary(Days_28$`Ensembled based on summed weight`)
##
## Call:
## stats::lm(formula = Data$Day ~ Without.knots + With.knots + Smooth +
## Quadratic + ARIMA)
##
## Residuals:
## Min 1Q Median 3Q Max
## -52.69 -14.49 5.85 18.70 25.37
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -29.792445 2.763795 -10.780 <2e-16 ***
## Without.knots 0.001976 0.010138 0.195 0.8456
## With.knots 0.002150 0.022524 0.095 0.9240
## Smooth -0.029336 0.025236 -1.162 0.2459
## Quadratic 0.568967 0.009350 60.852 <2e-16 ***
## ARIMA 0.026473 0.012757 2.075 0.0388 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 21.12 on 314 degrees of freedom
## Multiple R-squared: 0.9487, Adjusted R-squared: 0.9479
## F-statistic: 1162 on 5 and 314 DF, p-value: < 2.2e-16
knitr::kable(as.data.frame(Days_28$`Unconstrained Forecast`),
row.names = FALSE, "html")
Model Case
Linear 277722
Semilog 179540
Growth 2721
Without knots 1606956
Smooth Spline 1414254
With knots 991316
Quadratic Polynomial 380508
Lower ARIMA -126404
Upper ARIMA 939766
Essembled with equal weight 1381412
Essembled based on weight 153587
Essembled based on summed weight 210948
Essembled based on weight of fit 1072054
knitr::kable(as.data.frame(Days_28$`Constrained Forecast`),
row.names = FALSE, "html")
Model Confirmed cases
Linear 277722
Semilog 179540
Growth 2721
Without knots 80% 187609
Without knots 95% 782270
Smooth Spline 80% 234556
Smooth Spline 95% 744670
With knots 80% 235264
With knots 95% 678456
Quadratic Polynomial 80% 406348
Quadratic Polynomial 95% 430240
ARIMA 80% 86426
ARIMA 95% 847342
Essembled with equal weight 80% 188264
Essembled with equal weight 95% 730946
Essembled based on weight 80% 80211
Essembled based on weight 95% 179294
Essembled based on summed weight 80% 223874
Essembled based on summed weight 95% 351414
Essembled based on weight of fit 80% 60739
Essembled based on weight of fit 95% 807642
knitr::kable(as.data.frame(Days_28$RMSE), row.names = FALSE, "html")
Models RMSE
Linear 307.33
Semilog 310.78
Growth 475.6
Without knots 221.72
Smooth Spline 171.18
With knots 153.91
Quadratic Polynomial 305.21
Lower ARIMA 169.16
Upper ARIMA 169.16
Essembled with equal weight 175.47
Essembled based on weight 358.35
Essembled based on summed weight 357.6
Essembled based on weight of fit 193.35
Days_28$`Unconstrained forecast Plot`

Days_28$`Constrained forecast Plot`

Modelling and forecast by using data as at 14 days earlier

KK_14 <- data[data$Date <= lastdayfo21 - 14, ]
Days_14 <- DynamicForecast(Data = KK_14, BREAKS = BREAKS, MaximumDate = "2021-02-10", Trend = "Day", Length = 0, Type = "Integer")
summary(Days_14$`Ensembled based on weight`)
##
## Call:
## stats::lm(formula = Data$Day ~ Without.knots * With.knots * Smooth *
## Quadratic * ARIMA)
##
## Residuals:
## Min 1Q Median 3Q Max
## -6.0832 -1.1743 -0.1011 1.2401 6.4968
##
## Coefficients:
## Estimate Std. Error t value
## (Intercept) -1.459e+02 2.899e+00 -50.336
## Without.knots 3.495e-01 1.004e-02 34.826
## With.knots 7.364e-01 3.174e-02 23.205
## Smooth -3.082e-01 8.720e-02 -3.534
## Quadratic 7.485e-01 1.224e-02 61.159
## ARIMA 1.009e+00 7.618e-02 13.245
## Without.knots:With.knots -1.342e-03 9.152e-05 -14.664
## Without.knots:Smooth 5.894e-04 2.494e-04 2.364
## With.knots:Smooth -1.706e-04 1.020e-04 -1.672
## Without.knots:Quadratic -1.151e-03 3.998e-05 -28.783
## With.knots:Quadratic -3.198e-04 5.541e-05 -5.771
## Smooth:Quadratic 7.952e-04 1.729e-04 4.598
## Without.knots:ARIMA -2.919e-03 2.201e-04 -13.260
## With.knots:ARIMA -1.598e-03 9.422e-05 -16.959
## Smooth:ARIMA -4.422e-04 1.087e-04 -4.067
## Quadratic:ARIMA -1.797e-03 1.673e-04 -10.738
## Without.knots:With.knots:Smooth -8.188e-08 3.589e-07 -0.228
## Without.knots:With.knots:Quadratic 1.473e-06 1.035e-07 14.234
## Without.knots:Smooth:Quadratic -1.823e-06 5.690e-07 -3.204
## With.knots:Smooth:Quadratic 4.833e-07 1.333e-07 3.625
## Without.knots:With.knots:ARIMA 4.930e-06 3.601e-07 13.689
## Without.knots:Smooth:ARIMA 2.546e-06 3.063e-07 8.311
## With.knots:Smooth:ARIMA 9.997e-07 1.362e-07 7.339
## Without.knots:Quadratic:ARIMA 6.504e-06 5.474e-07 11.882
## With.knots:Quadratic:ARIMA -6.998e-07 1.474e-07 -4.748
## Smooth:Quadratic:ARIMA 4.766e-07 1.594e-07 2.990
## Without.knots:With.knots:Smooth:Quadratic 4.569e-10 3.882e-10 1.177
## Without.knots:With.knots:Smooth:ARIMA -4.618e-09 4.403e-10 -10.487
## Without.knots:With.knots:Quadratic:ARIMA -5.391e-09 3.916e-10 -13.764
## Without.knots:Smooth:Quadratic:ARIMA -4.609e-09 5.297e-10 -8.702
## With.knots:Smooth:Quadratic:ARIMA 1.278e-09 1.742e-10 7.337
## Without.knots:With.knots:Smooth:Quadratic:ARIMA 4.437e-12 4.318e-13 10.277
## Pr(>|t|)
## (Intercept) < 2e-16 ***
## Without.knots < 2e-16 ***
## With.knots < 2e-16 ***
## Smooth 0.000473 ***
## Quadratic < 2e-16 ***
## ARIMA < 2e-16 ***
## Without.knots:With.knots < 2e-16 ***
## Without.knots:Smooth 0.018723 *
## With.knots:Smooth 0.095509 .
## Without.knots:Quadratic < 2e-16 ***
## With.knots:Quadratic 1.95e-08 ***
## Smooth:Quadratic 6.27e-06 ***
## Without.knots:ARIMA < 2e-16 ***
## With.knots:ARIMA < 2e-16 ***
## Smooth:ARIMA 6.07e-05 ***
## Quadratic:ARIMA < 2e-16 ***
## Without.knots:With.knots:Smooth 0.819692
## Without.knots:With.knots:Quadratic < 2e-16 ***
## Without.knots:Smooth:Quadratic 0.001500 **
## With.knots:Smooth:Quadratic 0.000338 ***
## Without.knots:With.knots:ARIMA < 2e-16 ***
## Without.knots:Smooth:ARIMA 3.25e-15 ***
## With.knots:Smooth:ARIMA 2.01e-12 ***
## Without.knots:Quadratic:ARIMA < 2e-16 ***
## With.knots:Quadratic:ARIMA 3.17e-06 ***
## Smooth:Quadratic:ARIMA 0.003020 **
## Without.knots:With.knots:Smooth:Quadratic 0.240096
## Without.knots:With.knots:Smooth:ARIMA < 2e-16 ***
## Without.knots:With.knots:Quadratic:ARIMA < 2e-16 ***
## Without.knots:Smooth:Quadratic:ARIMA < 2e-16 ***
## With.knots:Smooth:Quadratic:ARIMA 2.03e-12 ***
## Without.knots:With.knots:Smooth:Quadratic:ARIMA < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 2.166 on 302 degrees of freedom
## Multiple R-squared: 0.9995, Adjusted R-squared: 0.9995
## F-statistic: 2.135e+04 on 31 and 302 DF, p-value: < 2.2e-16
knitr::kable(as.data.frame(Days_14$`Unconstrained Forecast`),
row.names = FALSE, "html")
Model Case
Linear 393218
Semilog 195751
Growth 2962
Without knots 2257939
Smooth Spline 1188445
With knots 1080847
Quadratic Polynomial 724740
Lower ARIMA 341460
Upper ARIMA 1286528
Essembled with equal weight 1493442
Essembled based on weight 166387
Essembled based on summed weight 249174
Essembled based on weight of fit 1187572
knitr::kable(as.data.frame(Days_14$`Constrained Forecast`),
row.names = FALSE, "html")
Model Confirmed cases
Linear 393218
Semilog 195751
Growth 2962
Without knots 80% 34305
Without knots 95% NaN
Smooth Spline 80% 299267
Smooth Spline 95% 825759
With knots 80% 197708
With knots 95% 865132
Quadratic Polynomial 80% 657610
Quadratic Polynomial 95% 697937
ARIMA 80% 117721
ARIMA 95% 881259
Essembled with equal weight 80% 51439
Essembled with equal weight 95% 908667
Essembled based on weight 80% 48782
Essembled based on weight 95% 350820
Essembled based on summed weight 80% 171184
Essembled based on summed weight 95% 570590
Essembled based on weight of fit 80% 198623
Essembled based on weight of fit 95% 768927
knitr::kable(as.data.frame(Days_14$RMSE), row.names = FALSE, "html")
Models RMSE
Linear 359.04
Semilog 379.11
Growth 570.94
Without knots 231.2
Smooth Spline 183.12
With knots 130.1
Quadratic Polynomial 341.3
Lower ARIMA 186.95
Upper ARIMA 186.95
Essembled with equal weight 181.65
Essembled based on weight 440.74
Essembled based on summed weight 438.98
Essembled based on weight of fit 261.39
Days_14$`Unconstrained forecast Plot`

Days_14$`Constrained forecast Plot`

Modelling and forecast by using data as at 1 day earlier

KK_1 <- data[data$Date <= lastdayfo21 - 1, ]
Days_1 <- DynamicForecast(Data = KK_1, BREAKS = BREAKS, MaximumDate = "2021-02-10", Trend = "Day", Length = 0, Type = "Integer")
summary(Days_1$`Ensembled based on weight`)
##
## Call:
## stats::lm(formula = Data$Day ~ Without.knots * With.knots * Smooth *
## Quadratic * ARIMA)
##
## Residuals:
## Min 1Q Median 3Q Max
## -8.1629 -1.1653 0.0671 1.3169 4.5735
##
## Coefficients:
## Estimate Std. Error t value
## (Intercept) -1.310e+02 2.608e+00 -50.237
## Without.knots 2.387e-01 1.036e-02 23.039
## With.knots 1.082e+00 6.348e-02 17.047
## Smooth 6.903e-02 7.909e-02 0.873
## Quadratic 6.957e-01 1.296e-02 53.657
## ARIMA 4.032e-01 7.231e-02 5.575
## Without.knots:With.knots -1.640e-03 1.991e-04 -8.237
## Without.knots:Smooth -1.004e-03 2.781e-04 -3.609
## With.knots:Smooth -6.261e-04 1.256e-04 -4.985
## Without.knots:Quadratic -6.224e-04 3.722e-05 -16.722
## With.knots:Quadratic -1.418e-03 8.849e-05 -16.022
## Smooth:Quadratic 4.237e-04 1.101e-04 3.849
## Without.knots:ARIMA -8.041e-04 2.169e-04 -3.707
## With.knots:ARIMA -1.096e-03 2.016e-04 -5.436
## Smooth:ARIMA -1.557e-04 2.338e-04 -0.666
## Quadratic:ARIMA -5.007e-04 1.133e-04 -4.421
## Without.knots:With.knots:Smooth 1.861e-06 3.816e-07 4.876
## Without.knots:With.knots:Quadratic 2.189e-06 2.236e-07 9.790
## Without.knots:Smooth:Quadratic 5.066e-07 3.377e-07 1.500
## With.knots:Smooth:Quadratic 3.715e-07 7.970e-08 4.662
## Without.knots:With.knots:ARIMA 1.300e-06 6.352e-07 2.046
## Without.knots:Smooth:ARIMA 1.807e-06 7.158e-07 2.524
## With.knots:Smooth:ARIMA 1.234e-07 2.338e-07 0.528
## Without.knots:Quadratic:ARIMA 6.727e-07 3.194e-07 2.106
## With.knots:Quadratic:ARIMA 1.909e-06 1.689e-07 11.298
## Smooth:Quadratic:ARIMA -6.559e-07 2.472e-07 -2.653
## Without.knots:With.knots:Smooth:Quadratic -1.680e-09 3.210e-10 -5.234
## Without.knots:With.knots:Smooth:ARIMA -8.270e-10 7.073e-10 -1.169
## Without.knots:With.knots:Quadratic:ARIMA -2.080e-09 5.519e-10 -3.769
## Without.knots:Smooth:Quadratic:ARIMA -3.388e-10 7.983e-10 -0.424
## With.knots:Smooth:Quadratic:ARIMA -3.553e-10 1.232e-10 -2.884
## Without.knots:With.knots:Smooth:Quadratic:ARIMA 6.288e-13 5.749e-13 1.094
## Pr(>|t|)
## (Intercept) < 2e-16 ***
## Without.knots < 2e-16 ***
## With.knots < 2e-16 ***
## Smooth 0.383443
## Quadratic < 2e-16 ***
## ARIMA 5.31e-08 ***
## Without.knots:With.knots 4.79e-15 ***
## Without.knots:Smooth 0.000358 ***
## With.knots:Smooth 1.02e-06 ***
## Without.knots:Quadratic < 2e-16 ***
## With.knots:Quadratic < 2e-16 ***
## Smooth:Quadratic 0.000143 ***
## Without.knots:ARIMA 0.000247 ***
## With.knots:ARIMA 1.09e-07 ***
## Smooth:ARIMA 0.505824
## Quadratic:ARIMA 1.35e-05 ***
## Without.knots:With.knots:Smooth 1.72e-06 ***
## Without.knots:With.knots:Quadratic < 2e-16 ***
## Without.knots:Smooth:Quadratic 0.134598
## With.knots:Smooth:Quadratic 4.63e-06 ***
## Without.knots:With.knots:ARIMA 0.041588 *
## Without.knots:Smooth:ARIMA 0.012087 *
## With.knots:Smooth:ARIMA 0.598058
## Without.knots:Quadratic:ARIMA 0.035994 *
## With.knots:Quadratic:ARIMA < 2e-16 ***
## Smooth:Quadratic:ARIMA 0.008372 **
## Without.knots:With.knots:Smooth:Quadratic 3.04e-07 ***
## Without.knots:With.knots:Smooth:ARIMA 0.243154
## Without.knots:With.knots:Quadratic:ARIMA 0.000196 ***
## Without.knots:Smooth:Quadratic:ARIMA 0.671555
## With.knots:Smooth:Quadratic:ARIMA 0.004194 **
## Without.knots:With.knots:Smooth:Quadratic:ARIMA 0.274932
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 2.029 on 315 degrees of freedom
## Multiple R-squared: 0.9996, Adjusted R-squared: 0.9996
## F-statistic: 2.728e+04 on 31 and 315 DF, p-value: < 2.2e-16
knitr::kable(as.data.frame(Days_1$`Unconstrained Forecast`),
row.names = FALSE, "html")
Model Case
Linear 457715
Semilog 221661
Growth 3144
Without knots 2257880
Smooth Spline -2261566
With knots -2249595
Quadratic Polynomial 850382
Lower ARIMA -178192
Upper ARIMA 912705
Essembled with equal weight 288994
Essembled based on weight 179138
Essembled based on summed weight 269358
Essembled based on weight of fit 278143
knitr::kable(as.data.frame(Days_1$`Constrained Forecast`),
row.names = FALSE, "html")
Model Confirmed cases
Linear 457715
Semilog 221661
Growth 3144
Without knots 80% 54481
Without knots 95% 820859
Smooth Spline 80% 148961
Smooth Spline 95% 642248
With knots 80% 32428
With knots 95% 944351
Quadratic Polynomial 80% 728400
Quadratic Polynomial 95% 765723
ARIMA 80% 47155
ARIMA 95% 907522
Essembled with equal weight 80% 122564
Essembled with equal weight 95% 801896
Essembled based on weight 80% 34078
Essembled based on weight 95% 589955
Essembled based on summed weight 80% 209508
Essembled based on summed weight 95% 524960
Essembled based on weight of fit 80% 123347
Essembled based on weight of fit 95% 759553
knitr::kable(as.data.frame(Days_1$RMSE), row.names = FALSE, "html")
Models RMSE
Linear 369.41
Semilog 397.51
Growth 610.45
Without knots 266.74
Smooth Spline 201.8
With knots 189.7
Quadratic Polynomial 346.87
Lower ARIMA 210.45
Upper ARIMA 210.45
Essembled with equal weight 213.74
Essembled based on weight 469.92
Essembled based on summed weight 467.88
Essembled based on weight of fit 287.22
Days_1$`Unconstrained forecast Plot`

Days_1$`Constrained forecast Plot`

Comparing the constrained forecast plots for the four-time periods

References

CCSE. 2020. “Coronavirus.” Baltimore, MD 21218-2682: Johns Hopkins University’s Center for Systems Science & Engineering. 2020. https://systems.jhu.edu/research/public-health/ncov/.
Krispin, Rami, and Jarrett Byrnes. 2020. Coronavirus: The 2019 Novel Coronavirus COVID-19 (2019-nCoV) Dataset. https://CRAN.R-project.org/package=coronavirus.
NCDC. 2020. “NCDC Coronavirus COVID-19 Microsite.” Abuja, Nigeria: The Nigerian Centre for Disease Control. 2020. https://covid19.ncdc.gov.ng/.
Nmadu, Job. 2020. Dyn4cast: Dynamic Modeling and Machine Learning Environment. https://github.com/JobNmadu/Dyn4cast.
R Core Team. 2020. R: A Language and Environment for Statistical Computing. Vienna, Austria: R Foundation for Statistical Computing. https://www.R-project.org/.
To leave a comment for the author, please follow the link and comment on their blog: R-Blog on Data modelling to develop ....

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)