Skip to content

Commit 54a0586

Browse files
committed
Fix bug from last commit #465
1 parent ea08d86 commit 54a0586

File tree

4 files changed

+52
-5
lines changed

4 files changed

+52
-5
lines changed

R/project.R

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ insert_pars <- function(par, nm, .n, delta_model = FALSE) {
343343
ret
344344
}
345345

346-
move_proj_to_tmbdat <- function(x, object, newdata, called_by_simulate = FALSE) {
346+
move_proj_to_tmbdat <- function(x, object, newdata, called_by_simulate = FALSE, size = NULL) {
347347
x$do_predict <- 0L
348348
x$year_i <- x$proj_year
349349
## x$A_st <- x$proj_mesh
@@ -364,13 +364,30 @@ move_proj_to_tmbdat <- function(x, object, newdata, called_by_simulate = FALSE)
364364
x$y_i <- matrix(NA, ncol = n_m, nrow = nrow(x$proj_X_ij[[1]])) # fake
365365
x$weights_i <- rep(1, nrow(x$y_i)) # fake: FIXME: bring in?
366366
x$area_i <- rep(1, nrow(x$y_i)) # fake FIXME: bring in for index??
367+
367368
if (!called_by_simulate) {
368369
unique_size <- unique(x$size)
369370
if (length(unique_size) != 1L) {
370371
cli_abort("This function hasn't been set up to work with binomial size specified yet.")
371372
}
372373
x$size <- rep(1, nrow(x$y_i)) # FIXME: bring in?
373374
}
375+
if (!is.null(size)) {
376+
if (length(size) != nrow(x$y_i)) cli_abort("size argument doesn't match rows of newdata")
377+
x$size <- size
378+
}
379+
if (!all(x$size == 1L)) {
380+
if (is.null(size)) {
381+
msg <- c(
382+
"It looks like the size/trials were specified for a binomial family with the weights argument.",
383+
"When simulating with newdata all sizes/trials will be assumed to be 1 unless you specify a vector via the `size` argument."
384+
)
385+
cli_inform(msg)
386+
x$size <- rep(1, nrow(x$y_i))
387+
}
388+
} else { # all 1s, but newdata; expand as needed silently
389+
x$size <- rep(1, nrow(x$y_i))
390+
}
374391
x$do_predict <- 0L
375392

376393
# nullify large data objects that are no longer needed:

R/tmb-sim.R

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,9 @@ sdmTMB_simulate <- function(formula,
345345
#' lets you parse out whatever elements you want from the simulation.
346346
#' Not usually needed.
347347
#' @param observation_error Logical. Simulate observation error?
348+
#' @param size A vector of size (trials) in the case of a binomial family with
349+
#' `newdata` specified. If left `NULL` with `newdata`, will be assumed to
350+
#' be a vector of 1s.
348351
#' @param silent Logical. Silent?
349352
#' @param ... Extra arguments passed to [predict.sdmTMB()]. E.g., one may wish
350353
#' to pass an `offset` argument if `newdata` are supplied in a model with an
@@ -397,6 +400,7 @@ simulate.sdmTMB <- function(object, nsim = 1L, seed = sample.int(1e6, 1L),
397400
mcmc_samples = NULL,
398401
return_tmb_report = FALSE,
399402
observation_error = TRUE,
403+
size = NULL,
400404
silent = FALSE,
401405
...) {
402406
set.seed(seed)
@@ -426,7 +430,7 @@ simulate.sdmTMB <- function(object, nsim = 1L, seed = sample.int(1e6, 1L),
426430
# generate prediction TMB data list
427431
p <- predict(object, newdata = newdata, return_tmb_data = TRUE, ...)
428432
# move data elements over
429-
p <- move_proj_to_tmbdat(p, object, newdata, called_by_simulate = TRUE)
433+
p <- move_proj_to_tmbdat(p, object, newdata, called_by_simulate = TRUE, size = size)
430434
p$sim_re <- tmb_dat$sim_re
431435
tmb_dat <- p
432436
}

man/simulate.sdmTMB.Rd

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-tmb-simulation.R

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,10 +195,10 @@ test_that("simulate.sdmTMB works with sizes in binomial GLMs #465", {
195195
fit <- sdmTMB(prop ~ x, data = dat, weights = w, family = binomial(), spatial = "off")
196196
dat$X <- dat$Y <- NA # FIXME
197197
set.seed(1)
198-
snd <- simulate(fit, nsim = 500, newdata = dat)
198+
snd <- simulate(fit, nsim = 500, newdata = dat, size = w)
199199
set.seed(1)
200-
s <- simulate(fit, nsim = 500, newdata = dat)
201-
expect_identical(s, snd)
200+
s <- simulate(fit, nsim = 500)
201+
expect_equal(as.matrix(s), as.matrix(snd), ignore_attr = TRUE)
202202
expect_true(nrow(snd) == 200L)
203203
expect_true(ncol(snd) == 500L)
204204
sim_means <- rowMeans(snd)
@@ -265,4 +265,25 @@ test_that("simulate without observation error works for binomial likelihoods #43
265265
m <- apply(s.b, 1, mean)
266266
p <- predict(fit.b, newdata = qcs_grid)
267267
expect_gt(cor(plogis(p$est), m), 0.95)
268+
269+
# with size specified
270+
expect_error({simulate(
271+
fit.b,
272+
newdata = qcs_grid,
273+
nsim = 1,
274+
observation_error = FALSE,
275+
size = c(1, 2, 3)
276+
)}, regexp = "size")
277+
278+
s.b1 <- simulate(
279+
fit.b,
280+
newdata = qcs_grid,
281+
type = "mle-mvn", # fixed effects at MLE values and random effect MVN draws
282+
mle_mvn_samples = "multiple", # take an MVN draw for each sample
283+
nsim = 50, # increase this for more stable results
284+
observation_error = FALSE, # do not include observation error
285+
seed = 23859,
286+
size = sample(1:9, size = nrow(qcs_grid), replace = TRUE)
287+
)
288+
expect_false(identical(s.b, s.b1))
268289
})

0 commit comments

Comments
 (0)