Skip to content

Commit b434414

Browse files
author
Nicholas Clark
committed
fix small bug in forecasting piecewise logistic
1 parent c6b5bd1 commit b434414

File tree

5 files changed

+82
-3
lines changed

5 files changed

+82
-3
lines changed

R/forecast.mvgam.R

+1-1
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,7 @@ forecast_draws = function(object,
904904
cap <- data.frame(series = data_test$series,
905905
time = data_test$index..time..index,
906906
cap = suppressWarnings(linkfun(data_test$cap,
907-
link = family_links$link)))
907+
link = family_links()$link)))
908908

909909
if(any(is.na(cap$cap)) | any(is.infinite(cap$cap))){
910910
stop(paste0('Missing or infinite values found for some "cap" terms\n',

src/mvgam.dll

0 Bytes
Binary file not shown.

tests/testthat/Rplots.pdf

34.8 KB
Binary file not shown.

tests/testthat/test-RW.R

+13-2
Original file line numberDiff line numberDiff line change
@@ -155,12 +155,23 @@ dat <- rbind(dplyr::bind_cols(sim_corcar1(phi = 0.65,
155155
data.frame(series = 'series2'))) %>%
156156
dplyr::mutate(series = as.factor(series))
157157

158+
dat_train <- dat %>%
159+
dplyr::group_by(series) %>%
160+
dplyr::arrange(time) %>%
161+
dplyr::slice_head(n = 110) %>%
162+
dplyr::ungroup()
163+
dat_test <- dat %>%
164+
dplyr::group_by(series) %>%
165+
dplyr::arrange(time) %>%
166+
dplyr::slice_tail(n = 10)%>%
167+
dplyr::ungroup()
168+
158169
test_that("CAR1 sets up correctly", {
159170
# mvgam with CAR(1) trends and series-level seasonal smooths
160171
mod <- mvgam(formula = y ~ s(season, bs = 'cc',
161172
k = 5, by = series),
162173
trend_model = CAR(),
163-
data = dat,
174+
data = dat_train,
164175
family = gaussian(),
165176
run_model = FALSE)
166177
expect_true(inherits(mod, 'mvgam_prefit'))
@@ -175,7 +186,7 @@ test_that("CAR1 sets up correctly", {
175186
k = 5, by = series),
176187
trend_model = CAR(),
177188
drift = TRUE,
178-
data = dat,
189+
data = dat_train,
179190
family = gaussian(),
180191
run_model = FALSE)
181192
expect_true(inherits(mod, 'mvgam_prefit'))

tests/testthat/test-piecewise.R

+68
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,71 @@ test_that("logistic caps should be included in the correct order", {
100100
dplyr::arrange(time) %>%
101101
dplyr::pull(cap)))))
102102
})
103+
104+
test_that("piecewise models fit and forecast without error", {
105+
skip_on_cran()
106+
# Example of logistic growth with possible changepoints
107+
# Simple logistic growth model
108+
dNt = function(r, N, k){
109+
r * N * (k - N)
110+
}
111+
112+
# Iterate growth through time
113+
Nt = function(r, N, t, k) {
114+
for (i in 1:(t - 1)) {
115+
116+
# population at next time step is current population + growth,
117+
# but we introduce several 'shocks' as changepoints
118+
if(i %in% c(5, 15, 25, 41, 45, 60, 80)){
119+
N[i + 1] <- max(1, N[i] + dNt(r + runif(1, -0.1, 0.1),
120+
N[i], k))
121+
} else {
122+
N[i + 1] <- max(1, N[i] + dNt(r, N[i], k))
123+
}
124+
}
125+
N
126+
}
127+
128+
# Simulate expected values
129+
set.seed(11)
130+
expected <- Nt(0.004, 2, 100, 30)
131+
plot(expected, xlab = 'Time')
132+
133+
# Take Poisson draws
134+
y <- rpois(100, expected)
135+
136+
# Assemble data into dataframe and model. We set a
137+
# fixed carrying capacity of 35 for this example, but note that
138+
# this value is not required to be fixed at each timepoint
139+
mod_data <- data.frame(y = y,
140+
time = 1:100,
141+
cap = 35,
142+
series = as.factor('series_1'))
143+
dat_train <- mod_data %>%
144+
dplyr::filter(time <= 90)
145+
dat_test <- mod_data %>%
146+
dplyr::filter(time > 90)
147+
148+
# The intercept is nonidentifiable when using piecewise
149+
# trends because the trend functions have their own offset
150+
# parameters 'm'; it is recommended to always drop intercepts
151+
# when using these trend models
152+
mod <- mvgam(y ~ 0,
153+
trend_model = PW(growth = 'logistic'),
154+
family = poisson(),
155+
data = dat_train,
156+
chains = 2)
157+
# Compute and plot forecasts
158+
fc <- forecast(mod, newdata = dat_test)
159+
expect_no_error(capture_output(plot(fc)))
160+
161+
# Should also work for piecewise linear
162+
mod <- mvgam(y ~ 0,
163+
trend_model = PW(growth = 'linear'),
164+
family = poisson(),
165+
data = dat_train,
166+
chains = 2)
167+
# Compute and plot forecasts
168+
fc <- forecast(mod, newdata = dat_test)
169+
expect_no_error(capture_output(plot(fc)))
170+
})

0 commit comments

Comments
 (0)