sdmTMB
sdmTMB copied to clipboard
Add random slopes via formula interface
follow same general approach as glmmTMB
Going through issues & one thought I had on this is that there's the way to include random slopes by group in the formula, e.g. y ~ s(depth|g)
, but random slopes are kind of already in sdmTMB via the time_varying
arg. Another approach with these is that in cases where groups are time steps y ~ s(depth|year)
, we could add these into the existing block as 'iid' REs
https://github.com/pbs-assess/sdmTMB/blob/10105ced2fdf0cb22592ff2f3551eeb18d138928/src/sdmTMB.cpp#L541
@ericward-noaa, thanks for all your work getting this together over in this branch!
I'm moving discussion here so I can keep track of it:
Priors: we had allowed priors on sigma_G before. With correlated REs, users would have to put priors on the covariance matrix for each group-model combination. Getting that right seems like it'd be a pain for most users, so I'm not sure what to do here. There's also choices between the inv-Wishart / LKJ prior -- and I haven't thought through which would be better
I think we can skip worrying about this for now.
Printing: I added a new option for tidy (currently
ran_vcov
) that returns a list of covariance matrices by model and group. Alternatively, tidy could return the flattened parameters of those matrices, and the function in tidy.r could be called by users to create the covariance matrices from tidy output. Both lmer() and glmmTMB() print versions of those matrices in summary() -- and it'd be good to think through what all to show without making output overwhelming
Perhaps we should aim to create something like glmmTMB/lme4 as a starting point:
Random effects:
Groups Name Variance Std.Dev. Corr
Subject (Intercept) 565.48 23.780
Days 32.68 5.717 0.08
Residual 654.95 25.592
Number of obs: 180, groups: Subject, 18
Maybe we can skip including both the variance and SD? Just the SD and correlation? Tidy should probably return those SDs in a data frame. We can look at broom.mixed for guidance. We do already have an effects = "ran_pars"
that we could work with and then maybe leave your ran_vcov
as is?
Prediction: I also didn't touch the prediction part of these models yet, because I wasn't exactly clear on how the new RE design matrices should get created. I used the lme4::mkReTrms() function to generate the design matrices -- and I think we want the design matrices generated for newdata to have the same dimensions / levels. lme4 uses lme4::mkNewReTrms(object, ...) to create the design matrices -- and because I never created a fitted model object, I don't know whether we should do that -- or just use
mkReTrms()
instead, like with the original data.
I am not sure either and would have to experiment.
I wonder if using lmer(control = lmerControl(optimizer = NULL))
would be helpful to create an object without fitting for use with lme4::mkNewReTrms
. I assume mkNewReTrms
is important for dealing with factor levels in newdata.
Actually, looking at glmmTMB, it looks like they never use mkNewReTrms
and reapply mkReTrms
after some levels checking: https://github.com/glmmTMB/glmmTMB/blob/409490f4a5e0ea5f49e89109e0fea8cc08f8af35/glmmTMB/R/glmmTMB.R#L649-L651
https://github.com/glmmTMB/glmmTMB/blob/409490f4a5e0ea5f49e89109e0fea8cc08f8af35/glmmTMB/R/predict.R#L343
That same function gets applies in fitting and then predicting with new data.
So, we can probably use mkReTrms
within your parse_formula
again for prediction on newdata.
Which also gives me the badly timed idea (so we should probably ignore) that we could probably just rely on an unevaluated call to glmmTMB to get the random effect matrix for input into TMB. Heck, now that glmmTMB does smoothers, which gets merged into the mkReTrms stuff, we could use it for all that.
Thanks for the thoughts.
I don't have strong feelings about whether or not to adopt glmmTMB to generate the design matrices. I imagine the sparse matrices are pretty similar to what we've got -- the annoying thing is keeping track of models / groups -- and that likely won't change much.
We should at least adopt the same approach as glmmTMB and use mkReTrms
to generate levels on new data. Two things I will spend time working on next week:
- [ ] working on the printing / tidying piece
- [ ] add multivariate simulation piece https://github.com/pbs-assess/sdmTMB/blob/c12b55db1f0c2f3980d08853df36ca340403e702/src/sdmTMB.cpp#L617
- [ ] start looking into prediction