brms generates a Stan program and a Stan data list for every model,
and stancode() and standata() return them. frmtmb generates
neither: the model is an R closure that build_objective() builds
from the assembled frame, and RTMB differentiates it. So on a fit
both stop with that reason and name what holds the same content.
Usage
stancode(object, ...)
# S3 method for class 'frmtmb_fit'
stancode(object, ...)
standata(object, ...)
# S3 method for class 'frmtmb_fit'
standata(object, ...)Details
standata() does not return the frame instead. The frame's names
are not brms's (X, Z_1_1, J_1, ...), and a list that answers
some of brms's names and not others would be read as brms's by a
ported script.
Examples
set.seed(1)
dd <- data.frame(x = rnorm(40))
dd$y <- rnorm(40, 1 + 0.5 * dd$x, 1)
fit <- frm(bf(y ~ x), family = gaussian(), data = dd)
try(stancode(fit))
#> Error : stancode() has no meaning for a frmtmb fit: there is no Stan program. The model is an R closure built by build_objective() from the assembled frame and differentiated by RTMB, and the closure IS the source: build_objective(fit$frame) returns it, fit$obj$fn is the taped marginal likelihood, and fit$frame holds everything baked into it. See the 'Seeing the model code' section of vignette("brms-migration")
try(standata(fit))
#> Error : standata() has no meaning for a frmtmb fit: nothing is exported to a Stan data list. The assembled frame fit$frame holds the same content (the response, the design matrices, the sparse Z, the addition terms) under frmtmb's names, and model.matrix(), getME() and model.frame() read the pieces of it individually
# the closure that IS the model evaluates the joint negative log
# density; with no random effects that is the negative log likelihood
nll <- build_objective(fit$frame)
all.equal(nll(fit$estimates), -as.numeric(logLik(fit)))
#> [1] TRUE