Time-varying estimation of machine learning models and their forecasts

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")
ModelCase
Linear462222
Semilog261819
Growth3158
Without knots2252100
Smooth Spline-2371123
With knots-1885886
Quadratic Polynomial857816
Lower ARIMA-275249
Upper ARIMA945658
Essembled with equal weight347332
Essembled based on weight121434
Essembled based on summed weight280048
Essembled based on weight of fit323205
knitr::kable(as.data.frame(Days_full$`Constrained Forecast`),
             row.names = FALSE, "html")
ModelConfirmed cases
Linear462222
Semilog261819
Growth3158
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")
ModelsRMSE
Linear369.14
Semilog397.82
Growth612.54
Without knots268.34
Smooth Spline201.62
With knots189.71
Quadratic Polynomial346.37
Lower ARIMA210.57
Upper ARIMA210.57
Essembled with equal weight213.84
Essembled based on weight471.14
Essembled based on summed weight469.08
Essembled based on weight of fit288.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")
ModelCase
Linear277722
Semilog179540
Growth2721
Without knots1606956
Smooth Spline1414254
With knots991316
Quadratic Polynomial380508
Lower ARIMA-126404
Upper ARIMA939766
Essembled with equal weight1381412
Essembled based on weight153587
Essembled based on summed weight210948
Essembled based on weight of fit1072054
knitr::kable(as.data.frame(Days_28$`Constrained Forecast`),
             row.names = FALSE, "html")
ModelConfirmed cases
Linear277722
Semilog179540
Growth2721
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")
ModelsRMSE
Linear307.33
Semilog310.78
Growth475.6
Without knots221.72
Smooth Spline171.18
With knots153.91
Quadratic Polynomial305.21
Lower ARIMA169.16
Upper ARIMA169.16
Essembled with equal weight175.47
Essembled based on weight358.35
Essembled based on summed weight357.6
Essembled based on weight of fit193.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")
ModelCase
Linear393218
Semilog195751
Growth2962
Without knots2257939
Smooth Spline1188445
With knots1080847
Quadratic Polynomial724740
Lower ARIMA341460
Upper ARIMA1286528
Essembled with equal weight1493442
Essembled based on weight166387
Essembled based on summed weight249174
Essembled based on weight of fit1187572
knitr::kable(as.data.frame(Days_14$`Constrained Forecast`),
             row.names = FALSE, "html")
ModelConfirmed cases
Linear393218
Semilog195751
Growth2962
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")
ModelsRMSE
Linear359.04
Semilog379.11
Growth570.94
Without knots231.2
Smooth Spline183.12
With knots130.1
Quadratic Polynomial341.3
Lower ARIMA186.95
Upper ARIMA186.95
Essembled with equal weight181.65
Essembled based on weight440.74
Essembled based on summed weight438.98
Essembled based on weight of fit261.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")
ModelCase
Linear457715
Semilog221661
Growth3144
Without knots2257880
Smooth Spline-2261566
With knots-2249595
Quadratic Polynomial850382
Lower ARIMA-178192
Upper ARIMA912705
Essembled with equal weight288994
Essembled based on weight179138
Essembled based on summed weight269358
Essembled based on weight of fit278143
knitr::kable(as.data.frame(Days_1$`Constrained Forecast`),
             row.names = FALSE, "html")
ModelConfirmed cases
Linear457715
Semilog221661
Growth3144
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")
ModelsRMSE
Linear369.41
Semilog397.51
Growth610.45
Without knots266.74
Smooth Spline201.8
With knots189.7
Quadratic Polynomial346.87
Lower ARIMA210.45
Upper ARIMA210.45
Essembled with equal weight213.74
Essembled based on weight469.92
Essembled based on summed weight467.88
Essembled based on weight of fit287.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/.
Job Nmadu
Professor of Agricultural Economics and Dean, School of Agriculture and Agricultural Technology

Research interests are economic efficiencies of small scale farming and welfare effects of agricultural interventions.

Related

Next
Previous