A unified, extensible toolkit for time-to-event analysis: one interface over the established R survival stack, with cross-method triangulation as the consistency check on top.
survkit puts one clean interface over the established R survival stack —
parametric accelerated-failure-time models, Cox proportional hazards, competing
risks, recurrent events, frailty, flexible splines, and a non-parametric
Kaplan-Meier baseline — driven by an extensible method registry so new
estimators slot in without an API change. Every fit returns a single typed
object with consistent prediction, summary and tidying methods.
On top of the fits sits the value layer that makes survkit a methodology rather than a wrapper:
survkit_triangulate()) that reads
disagreement between methods as a model-misspecification signal.survkit_rmst()) and cumulative incidence (survkit_cuminc()).survkit_score()) — concordance and the
censoring-weighted Brier score with its index of prediction accuracy.survkit_validate_method()).It stands alone — siblings are optional (Suggests, behind requireNamespace()
guards) and R CMD check is clean with none installed.
# from a local clone
devtools::install("survkit")
survival is the only modelling dependency; flexsurv, cmprsk, coxme,
flexsurvcure and icenReg are optional backends, pulled only when a method
needs them.
library(survkit)
# what can it fit?
survkit_methods()
# a Weibull accelerated-failure-time model
fit <- survkit(survival::Surv(time, status) ~ age + sex, survival::lung,
method = "weibull")
fit
survkit_tidy(fit) # estimates, ratios, CIs
survkit_curve(fit, times = c(100, 300, 500))
# Cox proportional hazards on the same data
cox <- survkit(survival::Surv(time, status) ~ age + sex, survival::lung,
method = "cox")
# competing risks (Fine-Gray subdistribution hazard)
# event is a factor: first level = censoring
mg <- survival::mgus2
mg$etime <- with(mg, ifelse(pstat == 1, ptime, futime))
mg$event <- with(mg, factor(ifelse(pstat == 1, "pcm",
ifelse(death == 1, "death", "censor")),
levels = c("censor", "pcm", "death")))
survkit(survival::Surv(etime, event) ~ age + sex, mg, method = "fine_gray",
cause = "pcm")
Survival models identify from events, not rows. survkit() runs an
events-per-variable check on every fit and warns when a model is under-powered,
so you can simplify, penalise, or abstain rather than trust over-fit estimates:
small_data <- survival::lung[1:25, ]
survkit_power(survival::Surv(time, status) ~ age + sex + ph.ecog, small_data)
#> $verdict "underpowered"
#> $events_per_variable 7.3
Fit the same question under several methods and let their disagreement flag a model worth a closer look:
survkit_triangulate(survival::Surv(time, status) ~ age + sex, survival::lung,
methods = c("weibull", "cox", "km"), tau = 500)
#> <survkit_triangulation> methods: weibull, cox, km
#> restricted mean at tau = 500
#> method tau rmst
#> weibull 500 311.6
#> cox 500 312.7
#> km 500 310.3
#> verdict: agreement -- methods concur within threshold
fit <- survkit(survival::Surv(time, status) ~ age, survival::lung, method = "km")
survkit_rmst(fit, tau = 365) # restricted mean survival time
survkit_score(cox, survival::lung, times = c(200, 400, 600)) # C-index, Brier, IPA
A new estimator is one registry call — no change to survkit():
survkit_register("my_method", kind = "parametric", backend = "somepkg",
fit = function(formula, data, ...) {
raw <- somepkg::fit(formula, data, ...)
list(raw = raw, coef = coef(raw), vcov = vcov(raw),
loglik = as.numeric(logLik(raw)),
n = nrow(data), n_events = NA_integer_,
kind = "parametric", backend = "somepkg")
})
Bug reports and suggestions are welcome through the issue tracker.
citation("survkit")
MIT © Max Moldovan.