Yeah on the rstanarm GitHub repo there is the feature/survival
branch and the feature/frailty-models
branch.
The feature/survival
one should be good to go and fits a bunch of right censored survival models. I can’t remember how many extra features I added to that branch.
The feature/frailty-models
branch contains an additional bunch of extensions I’ve been working on more recently: left/right/interval censored data, delayed entry, time-varying effects, time-varying covariates, hierarchical survival models, etc. I can’t remember exactly which of these features were already on the feature/survival
branch but perhaps some. I’ve not added anything related to competing risks or multi-state tho (and doubt I will get the time to either).
I’ll merge the feature/frailty-models
branch into the feature/survival
branch in the near future I think (I had just wanted to test it / finalise it a bit more).
There is a pretty detailed vignette here, but you need to install the feature/frailty-models
branch to compile the vignette, so it’s not that easy to view at the moment. Maybe I will upload it to my website and then post a link here, just until the vignette is actually available on CRAN.
The approach we took was M-splines on the baseline hazard. So it’s not exactly the Cox-equivalent @Emmanuel_Charpentier is after. But it is more parsimonious and requires less data wrangling. One potential downside is that it requires quadrature for time-varying effects (i.e. time-varying hazard ratios), where as the poisson time-splitting method doesn’t and so may be faster for that specific use case. Note that we implement the M-splines using the splines2 package, which allows piecewise constant as a special case when the M-splines degree is set equal to 0. So we effectively get piecewise constant baseline hazards implemented for free. Using a large number of knots should get you close to the Poisson time-splitting Cox model approximation (in theory the Cox model occurs once the knots are at each unique event time).
Yeah this is correct. If you want the observational unit to the be the individual, then you have to calculate the likelihood contribution for each row of data (allowing for delayed entry) and then collapse (i.e. sum) within each individual. This is how the loo method for rstanarm::stan_jm
works.
I’ve not yet bothered with that for rstanarm::stan_surv
. The log_lik
and loo
methods for stansurv objects just operate on each row of data but allow for delayed entry. It’s currently up to the user to decide whether the rows of data are meaningful units of observation. If they aren’t, then I guess they could use the log_lik
method, then manually collapse rows (i.e. sum) within each individual, and then pass the collapsed matrix to loo::loo.matrix()
for evaluating loo/WAIC. I guess that eventually it might make sense to have an idvar
argument and then collapse the log likelihood across unique values of idvar
just like stan_jm does.
The most common prediction quantities would be the hazard, cumulative hazard, or survival probability (and their log variants). In rstanarm they are implemented through the rstanarm::posterior_survfit
function (as opposed to rstanarm::posterior_predict
). At the moment this function will throw a stop if the user tries to predict with the original data that contained start/stop notation – for exactly the reason you highlight (i.e. we probably only want a prediction for each individual, not each row).
The way to circumvent the issue is either pass newdata
with one row per individual (it’s very unlikely the user actually wants to predict using multiple rows of covariate data for each individual! That would only be necessary for time-varying covariates in the prediction data, which would be a nightmare to interpret). If the reason that the user was trying to predict with start/stop data is because they want to predict under the assumption of delated entry, then the last known survival time should be entered explicitly via the last_time
argument and NOT via the prediction data.
Hope this helps a bit. Of course it’s all related to rstanarm and not Stan proper, but it should give you some pointers incase you plan to implement something similar using your own Stan code.
As Jonah mentioned, @ermeel will present a bunch of this stuff and related concepts at StanCon this year. We also plan to publish a notebook as part of that StanCon talk.