@@ -332,8 +332,12 @@ sdmTMB_simulate <- function(formula,
332
332
# ' effects (this only simulates observation error). `~0` or `NA` to simulate
333
333
# ' new random affects (smoothers, which internally are random effects, will
334
334
# ' not be simulated as new).
335
+ # ' @param mle_mvn_samples Applies if `type = "mle-mvn"`. If `"single"`, take
336
+ # ' a single MVN draw from the random effects. If `"multiple"`, take an MVN
337
+ # ' draw from the random effects for each of the `nsim`.
335
338
# ' @param model If a delta/hurdle model, which model to simulate from?
336
339
# ' `NA` = combined, `1` = first model, `2` = second mdoel.
340
+ # ' @param newdata Optional new data frame from which to simulate.
337
341
# ' @param mcmc_samples An optional matrix of MCMC samples. See `extract_mcmc()`
338
342
# ' in the \href{https://github.com/pbs-assess/sdmTMBextra}{sdmTMBextra}
339
343
# ' package.
@@ -381,10 +385,16 @@ sdmTMB_simulate <- function(formula,
381
385
simulate.sdmTMB <- function (object , nsim = 1L , seed = sample.int(1e6 , 1L ),
382
386
type = c(" mle-eb" , " mle-mvn" ),
383
387
model = c(NA , 1 , 2 ),
384
- re_form = NULL , mcmc_samples = NULL , silent = FALSE , ... ) {
388
+ newdata = NULL ,
389
+ re_form = NULL ,
390
+ mle_mvn_samples = c(" single" , " multiple" ),
391
+ mcmc_samples = NULL ,
392
+ silent = FALSE ,
393
+ ... ) {
385
394
set.seed(seed )
386
395
type <- tolower(type )
387
396
type <- match.arg(type )
397
+ mle_mvn_samples <- match.arg(mle_mvn_samples )
388
398
assert_that(as.integer(model [[1 ]]) %in% c(NA_integer_ , 1L , 2L ))
389
399
390
400
# need to re-attach environment if in fresh session
@@ -403,6 +413,16 @@ simulate.sdmTMB <- function(object, nsim = 1L, seed = sample.int(1e6, 1L),
403
413
stopifnot(length(object $ tmb_data $ sim_re ) == 6L ) # in case this gets changed
404
414
tmb_dat $ sim_re <- c(rep(1L , 5L ), 0L ) # last is smoothers; don't simulate them
405
415
}
416
+
417
+ if (! is.null(newdata )) {
418
+ # generate prediction TMB data list
419
+ p <- predict(object , newdata = newdata , return_tmb_data = TRUE , ... )
420
+ # move data elements over
421
+ p <- move_proj_to_tmbdat(p , object , newdata )
422
+ p $ sim_re <- tmb_dat $ sim_re
423
+ tmb_dat <- p
424
+ }
425
+
406
426
newobj <- TMB :: MakeADFun(
407
427
data = tmb_dat , map = object $ tmb_map ,
408
428
random = object $ tmb_random , parameters = object $ tmb_obj $ env $ parList(), DLL = " sdmTMB"
@@ -411,9 +431,17 @@ simulate.sdmTMB <- function(object, nsim = 1L, seed = sample.int(1e6, 1L),
411
431
# params MLE/MVN stuff
412
432
if (is.null(mcmc_samples )) {
413
433
if (type == " mle-mvn" ) {
414
- new_par <- .one_sample_posterior(object )
434
+ if (mle_mvn_samples == " single" ) {
435
+ new_par <- .one_sample_posterior(object )
436
+ new_par <- replicate(nsim , new_par )
437
+ } else {
438
+ new_par <- lapply(seq_len(nsim ), \(i ) .one_sample_posterior(object ))
439
+ new_par <- do.call(cbind , new_par )
440
+ }
415
441
} else if (type == " mle-eb" ) {
416
442
new_par <- object $ tmb_obj $ env $ last.par.best
443
+ new_par <- lapply(seq_len(nsim ), \(i ) new_par )
444
+ new_par <- do.call(cbind , new_par )
417
445
} else {
418
446
cli_abort(" `type` type not defined" )
419
447
}
@@ -432,7 +460,7 @@ simulate.sdmTMB <- function(object, nsim = 1L, seed = sample.int(1e6, 1L),
432
460
} else {
433
461
for (i in seq_len(nsim )) {
434
462
if (! silent ) cli :: cli_progress_update()
435
- ret [[i ]] <- newobj $ simulate(par = new_par , complete = FALSE )$ y_i
463
+ ret [[i ]] <- newobj $ simulate(par = new_par [, i , drop = TRUE ] , complete = FALSE )$ y_i
436
464
}
437
465
}
438
466
if (! silent ) cli :: cli_progress_done()
0 commit comments