Skip to content

Commit fda4338

Browse files
committed
Rework vignette so it will build
1 parent 15f934f commit fda4338

File tree

1 file changed

+48
-31
lines changed

1 file changed

+48
-31
lines changed

vignettes/articles/forecasting.Rmd

Lines changed: 48 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ We then have different options for including time in the model.
9393

9494
To include spatiotemporal variation as an AR(1) process, we can specify `spatiotemporal = "AR1"`:
9595

96-
```{r ar1, message=FALSE, warning=FALSE, results='hide'}
96+
```{r ar1, message=FALSE, warning=FALSE, results='hide', eval=FALSE}
9797
fit_ar1 <- sdmTMB(
9898
density ~ depth_scaled + depth_scaled2,
9999
time = "year",
@@ -111,7 +111,7 @@ fit_ar1 <- sdmTMB(
111111

112112
Or, we can set spatiotemporal variation to a random walk with `spatiotemporal = "RW"`:
113113

114-
```{r fit-rw, message=FALSE, warning=FALSE, results='hide'}
114+
```{r fit-rw, message=FALSE, warning=FALSE, results='hide', eval= FALSE}
115115
fit_rw <- sdmTMB(
116116
density ~ depth_scaled + depth_scaled2,
117117
time = "year",
@@ -129,7 +129,7 @@ fit_rw <- sdmTMB(
129129

130130
We can also model the intercept as a random walk by removing the intercept from the main formula (adding `0` to the model equation) and including the argument `time_varying = ~1`:
131131

132-
```{r fit-rw-ar1, message=FALSE, warning=FALSE, results='hide'}
132+
```{r fit-rw-ar1, message=FALSE, warning=FALSE, results='hide', eval=FALSE}
133133
fit_rw_ar1 <- sdmTMB(
134134
density ~ 0 + depth_scaled + depth_scaled2, #<< remove intercept with 0
135135
time = "year",
@@ -148,7 +148,7 @@ fit_rw_ar1 <- sdmTMB(
148148

149149
We can also add a smoother on year as a variable in the model equation with `s(year)` in the model equation and keeping `spatiotemporal="AR1"`:
150150

151-
```{r, fit-sm, results='hide', message=FALSE, warning=FALSE}
151+
```{r, fit-sm, results='hide', message=FALSE, warning=FALSE, eval=FALSE}
152152
fit_sm <- sdmTMB(
153153
density ~ s(year, k = 5) + depth_scaled + depth_scaled2, #<< add smoother on year
154154
time = "year",
@@ -174,42 +174,60 @@ In deciding which method (AR(1), RW, etc) to use for including time in the model
174174
# `project()`` function for faster long-term forecasting
175175

176176
Because forecasting can be slow---especially for large datasets or for projections far into the future, sdmTMB also includes a `project()` function for doing projections via simulations.
177-
Keeping with the `pcod` dataset, we'll first define the years for the historical (fitting) and projection period.
177+
Using the built-in `dogfish` dataset, we'll first define the years for the historical (fitting) and projection period. This is based off an approach first developed in the `project_model()` function in VAST.
178178

179179
```{r}
180-
mesh <- make_mesh(pcod, c("X", "Y"), cutoff = 25)
181-
historical_years <- 2003:2017
180+
mesh <- make_mesh(dogfish, c("X", "Y"), cutoff = 30)
181+
historical_years <- 2004:2022
182182
to_project <- 5
183183
future_years <- seq(max(historical_years) + 1, max(historical_years) + to_project)
184184
all_years <- c(historical_years, future_years)
185-
proj_grid <- replicate_df(qcs_grid, "year", all_years)
185+
proj_grid <- replicate_df(wcvi_grid, "year", all_years)
186+
186187
```
187-
Next, we'll fit the model. This is a binomial model of presence-absence, with no covariates and an AR(1) spatiotemporal field that is responsible for future forecasts.
188+
189+
Next, we'll fit the model. We'll use an AR(1) spatiotemporal field that is responsible for future forecasts.
188190

189191
```{r}
190192
fit <- sdmTMB(
191-
present ~ 1,
193+
catch_weight ~ 1,
192194
time = "year",
195+
offset = log(dogfish$area_swept),
193196
extra_time = historical_years, #< does *not* include projection years
194197
spatial = "on",
195198
spatiotemporal = "ar1",
196-
data = pcod,
199+
data = dogfish,
197200
mesh = mesh,
198-
family = binomial()
201+
family = tweedie(link = "log")
199202
)
200203
```
201204

202-
Finally, we'll do the projections for the last 5 years.
203-
We'll only use 20 draws for simplicity, but you should increase this for real-world applications so that you have stable results.
205+
Finally, we'll do the projections.
206+
We'll only use 20 draws for speed and simplicity, but you should increase this for real-world applications so that you have stable results.
204207

205-
```{r}
208+
```{r, message=FALSE}
206209
set.seed(1)
207210
out <- project(fit, newdata = proj_grid, nsim = 20)
208211
```
209212

210-
The `out` object now contains two objects: `out$est` and `out$epsilon_est`, each with dimensions of the number of rows in the prediction data (`proj_grid`) and number of draws for this example (n = 20).
213+
The `out` object now contains two objects: `out$est` and `out$epsilon_est`, each with dimensions of the number of rows in the prediction data (`proj_grid`) (rows) and number of draws for this example (n = 20) (columns).
214+
The first (`est`) are the predictions (in link space) and the second (`epsilon_est`) is the spatiotemporal random effects.
211215
These can be summarized and visualized in several ways to show trends in both the mean, as well as the confidence intervals.
212216

217+
For example, here are the projections:
218+
219+
```{r}
220+
proj_grid$est_mean <- apply(out$est, 1, mean)
221+
ggplot(subset(proj_grid, year > 2022), aes(X, Y, fill = est_mean)) +
222+
geom_raster() +
223+
facet_wrap(~year) +
224+
coord_fixed() +
225+
scale_fill_viridis_c() +
226+
ggtitle("Projection simulation (mean)")
227+
```
228+
229+
See the help file `?sdmTMB::project` for additional examples.
230+
213231
# Interpolating in space to unsampled areas
214232

215233
We can also interpolate predicted values to unsampled areas within the geographic extent of the data.
@@ -275,36 +293,38 @@ newdf <- expand.grid(
275293
x = seq(min(dat$x), max(dat$x), 5),
276294
y = seq(min(dat$y), max(dat$y), 5)
277295
)
278-
p <- predict(fit,
279-
newdata = newdf, se_fit = TRUE
280-
)
296+
p <- predict(fit, newdata = newdf)
281297
282298
ggplot(p, aes(x, y)) +
283299
geom_raster(data = p, aes(x, y, fill = est)) +
284300
geom_point(data = dat, aes(x, y)) +
285-
labs(fill = "tree density")
301+
labs(fill = "tree density") +
302+
scale_fill_viridis_c()
286303
```
287304

288-
We can also use add the argument `nsim = 500` when predicting and then summarize predicted densities from all simulations in a matrix
305+
We can also use add the argument `nsim = 200` when predicting and then summarize predicted densities from all simulations in a matrix
289306

290307
```{r}
291-
p2 <- predict(fit, newdata = newdf, nsim = 500)
308+
p2 <- predict(fit, newdata = newdf, nsim = 200)
292309
newdf$p2 <- apply(p2, 1, mean)
293310
ggplot(newdf, aes(x, y)) +
294311
geom_raster(data = newdf, aes(x, y, fill = p2)) +
295312
geom_point(data = dat, aes(x, y)) +
296-
labs(fill = "tree density")
313+
labs(fill = "tree density") +
314+
scale_fill_viridis_c()
297315
```
298316

299317
We can also visualize uncertainty in the forecasts by mapping the standard error of predicted densities at each point in space.
300318
We see that uncertainty is higher at vertices.
301319
This is because there are fewer neighbors, e.g. [this tutorial](https://ourcodingclub.github.io/tutorials/spatial-modelling-inla/)
302320

303321
```{r vis-vert}
322+
newdf$est_se <- apply(p2, 1, sd)
304323
ggplot() +
305-
geom_point(data = p, aes(x = x, y = y, col = est_se)) +
324+
geom_raster(data = newdf, aes(x = x, y = y, fill = est_se)) +
306325
coord_equal() +
307-
labs(col = "Standard error\nof spatiotemporal field")
326+
labs(col = "Standard error\nof spatiotemporal field") +
327+
scale_fill_viridis_c(option = "D")
308328
```
309329

310330
### Extrapolating outside the survey domain
@@ -317,17 +337,14 @@ Here, we expand the geographic domain by 100 in all directions, and keep the res
317337
Then, we can use the same model fit to predict to the expanded geographic domain.
318338

319339
```{r pred-fit2, echo=FALSE, eval=TRUE, message=FALSE, warning=FALSE}
320-
# makes all combinations of x and y:
321340
newdf <- expand.grid(
322341
x = seq(min(dat$x) - 100, max(dat$x) + 100, 5),
323342
y = seq(min(dat$y) - 100, max(dat$y) + 100, 5)
324343
)
325-
p3 <- predict(fit,
326-
newdata = newdf, se_fit = TRUE
327-
)
344+
p3 <- predict(fit, newdata = newdf)
328345
ggplot(p3, aes(x, y)) +
329346
geom_raster(data = p3, aes(x, y, fill = est)) +
330347
geom_point(data = dat, aes(x, y)) +
331-
labs(fill = "tree density")
348+
labs(fill = "tree density") +
349+
scale_fill_viridis_c()
332350
```
333-

0 commit comments

Comments
 (0)