Survival analysis
Start with the expanded example for each command. Open the variants for options and alternative R approaches. Read the qualifications before adapting the code.
estat
Censored-outcome concordance after Cox regression
Stata
estat concordanceR Package:survival
survival::concordance(fit)Differs from Stata Fixed workflow; adapt the named data columns explicitly. Censoring weights and handling of tied risks/times affect the statistic.
1 more examples and alternatives
Cox proportional-hazards diagnostic
Stata
estat phtest, detailR Package:survival
survival::cox.zph(fit, transform = "identity")Differs from Stata Fixed workflow; adapt the named data columns explicitly. Schoenfeld-residual implementation and default time transformations differ.
ltable
Actuarial life-table survival over fixed intervals
Stata
ltable time event, intervals(0 2 4 6)R Package:base
{ ends <- c(2, 4, 6); starts <- c(0, 2, 4); n <- vapply(starts, function(t) sum(data$time >= t), integer(1)); d <- vapply(seq_along(ends), function(i) sum(data$time >= starts[i] & data$time < ends[i] & data$event == 1), integer(1)); w <- vapply(seq_along(ends), function(i) sum(data$time >= starts[i] & data$time < ends[i] & data$event == 0), integer(1)); q <- d / (n - w / 2); data.frame(start = starts, end = ends, at_risk = n, failures = d, withdrawals = w, survival = cumprod(1 - q)) }Differs from Stata Fixed workflow; adapt the named data columns explicitly. Uses the half-withdrawal actuarial adjustment and left-closed intervals; censoring is assumed uniform within each interval. Boundary conventions and intervals must match.
predict
Baseline Cox survival from cumulative hazard
Stata
predict baseS, basesurvR Package:survival
{ h <- survival::basehaz(fit, centered = FALSE); data.frame(time = h$time, survival = exp(-h$hazard)) }Fixed workflow; adapt the named data columns explicitly. Baseline refers to zero covariates; verify the intended reference profile. Stata basesurv uses a product-limit construction, so exp(-cumulative hazard) is an alternative estimate rather than exact numerical parity.
11 more examples and alternatives
Baseline cumulative hazard at zero covariates
Stata
predict basehaz, basechazardR Package:survival
survival::basehaz(fit, centered = FALSE)Differs from Stata Fixed workflow; adapt the named data columns explicitly. Cox baseline is centered at zero explicitly; Stata stores results on observation rows whereas R returns unique event/censoring times.
Conditional median survival after loglogistic AFT
Stata
predict median_time, medianR Package:survival
stats::predict(fit, type = "quantile", p = .5)Differs from Stata Fixed workflow; adapt the named data columns explicitly. Distribution-specific predicted survival quantiles; not the mean time.
Deviance residuals after Cox regression
Stata
predict residual*, devianceR Package:survival
stats::residuals(fit, type = "deviance")Differs from Stata Fixed workflow; adapt the named data columns explicitly. Schoenfeld residuals have one row per event; score/influence residuals have one row per observation.
Cox coefficient influence residuals
Stata
predict residual*, dfbetaR Package:survival
stats::residuals(fit, type = "dfbeta")Differs from Stata Fixed workflow; adapt the named data columns explicitly. Schoenfeld residuals have one row per event; score/influence residuals have one row per observation.
Martingale residuals after Cox regression
Stata
predict residual*, mgaleR Package:survival
stats::residuals(fit, type = "martingale")Differs from Stata Fixed workflow; adapt the named data columns explicitly. Schoenfeld residuals have one row per event; score/influence residuals have one row per observation.
Scaled Schoenfeld residuals
Stata
predict residual*, scaledschR Package:survival
stats::residuals(fit, type = "scaledsch")Differs from Stata Fixed workflow; adapt the named data columns explicitly. Schoenfeld residuals have one row per event; score/influence residuals have one row per observation.
Event-specific Schoenfeld residuals
Stata
predict residual*, schoenfeldR Package:survival
stats::residuals(fit, type = "schoenfeld")Differs from Stata Fixed workflow; adapt the named data columns explicitly. Schoenfeld residuals have one row per event; score/influence residuals have one row per observation.
Cox score contributions
Stata
predict residual*, scoresR Package:survival
stats::residuals(fit, type = "score")Differs from Stata Fixed workflow; adapt the named data columns explicitly. Schoenfeld residuals have one row per event; score/influence residuals have one row per observation.
Cox-Snell expected-event quantities
Stata
predict value, csnellR Package:survival
stats::predict(fit, type = "expected", reference = "zero")Differs from Stata Fixed workflow; adapt the named data columns explicitly. Centering is explicitly zero for relative predictions; expected-event quantities depend on each observed follow-up time.
Cox relative-hazard scores
Stata
predict value, hrR Package:survival
stats::predict(fit, type = "risk", reference = "zero")Differs from Stata Fixed workflow; adapt the named data columns explicitly. Centering is explicitly zero for relative predictions; expected-event quantities depend on each observed follow-up time.
Cox linear predictors
Stata
predict value, xbR Package:survival
stats::predict(fit, type = "lp", reference = "zero")Differs from Stata Fixed workflow; adapt the named data columns explicitly. Centering is explicitly zero for relative predictions; expected-event quantities depend on each observed follow-up time.
snapspan
Convert snapshots to intervals with covariates applying forward
Stata
snapspan id time event, generate(start)R Package:stats
{ out <- data[order(data$id, data$time), ]; previous <- ave(out$time, out$id, FUN = function(v) c(NA_real_, head(v, -1))); previous_x <- ave(out$x, out$id, FUN = function(v) c(NA_real_, head(v, -1))); out$start <- previous; out$x <- previous_x; out[!is.na(out$start), ] }Fixed workflow; adapt the named data columns explicitly. The first snapshot defines interval entry, event indicators apply at interval exit, and ordinary covariates apply forward. This explicit workflow drops initial zero-duration rows; check Stata’s retained baseline rows before matching row counts.
stbase
Keep baseline record for each subject
Stata
stbaseR Package:base
data[order(data$id, data$start), ][!duplicated(data[order(data$id, data$start), "id"]), ]Fixed workflow; adapt the named data columns explicitly. Record-selection workflow only; stbase may also transform survival-time fields.
stci
Median survival with confidence limits
Stata
stci, medianR Package:survival
stats::quantile(survival::survfit(s ~ 1), probs = .5)Differs from Stata Fixed workflow; adapt the named data columns explicitly. Median interpolation and confidence-limit conventions can differ.
Restricted mean survival through time nine
Stata
stci, rmeanR Package:survival
summary(survival::survfit(s ~ 1), rmean = "common")$tableDiffers from Stata rmean=“common” restricts the survival integral at the largest observed follow-up time, as Stata stci, rmean does; it does not extrapolate beyond follow-up. Match the analysis sample and censoring declaration.
stcox
Cox proportional hazards model
Stata
stcox x1 x2R Package:survival
survival::coxph(survival::Surv(time, died) ~ x1 + x2, data = data)Differs from Stata exp(coef(fit)) gives the hazard ratios that stcox reports. coxph() defaults to Efron handling of ties; Stata stcox defaults to Breslow. Set ties = “breslow” to match tied-event likelihoods.
9 more examples and alternatives
Cox treatment-covariate interaction
Stata
stcox c.x##i.groupR Package:survival
survival::coxph(survival::Surv(time, event) ~ x * factor(group), ties = "breslow", data = data)Differs from Stata Fixed workflow; adapt the named data columns explicitly. Match ties, risk intervals, weights and reference inference explicitly.
Cox regression with Breslow ties
Stata
stcox x zR Package:survival
survival::coxph(survival::Surv(time, event) ~ x + z, data = data, ties = "breslow")Differs from Stata Fixed workflow; adapt the named data columns explicitly. Match ties, risk intervals, weights and reference inference explicitly.
Weighted Cox model with sandwich covariance
Stata
stcox x z [pw=w], vce(robust)R Package:survival
survival::coxph(survival::Surv(time, event) ~ x + z, ties = "breslow", data = data, weights = w, robust = TRUE)Differs from Stata Fixed workflow; adapt the named data columns explicitly. Match ties, risk intervals, weights and reference inference explicitly.
Cox regression with Efron ties
Stata
stcox x z, efronR Package:survival
survival::coxph(survival::Surv(time, event) ~ x + z, data = data, ties = "efron")Differs from Stata Fixed workflow; adapt the named data columns explicitly. Match ties, risk intervals, weights and reference inference explicitly.
Cox regression with exact partial likelihood
Stata
stcox x z, exactpR Package:survival
survival::coxph(survival::Surv(time, event) ~ x + z, data = data, ties = "exact")Differs from Stata Fixed workflow; adapt the named data columns explicitly. Match ties, risk intervals, weights and reference inference explicitly.
Shared gamma frailty Cox model
Stata
stcox x z, shared(id)R Package:survival
survival::coxph(survival::Surv(time, event) ~ x + z + frailty(id, distribution = "gamma"), ties = "breslow", data = data)Differs from Stata Fixed workflow; adapt the named data columns explicitly. Match ties, risk intervals, weights and reference inference explicitly.
Stratified Cox baseline hazards
Stata
stcox x z, strata(group)R Package:survival
survival::coxph(survival::Surv(time, event) ~ x + z + strata(group), ties = "breslow", data = data)Differs from Stata Fixed workflow; adapt the named data columns explicitly. Match ties, risk intervals, weights and reference inference explicitly.
Cluster-robust Cox inference
Stata
stcox x z, vce(cluster id)R Package:survival
survival::coxph(survival::Surv(time, event) ~ x + z, ties = "breslow", data = data, cluster = id)Differs from Stata Fixed workflow; adapt the named data columns explicitly. Match ties, risk intervals, weights and reference inference explicitly.
Cox time-varying log-time coefficient
Stata
stcox x, tvc(z) texp(ln(_t))R Package:survival
survival::coxph(survival::Surv(time, event) ~ x + tt(z), ties = "breslow", data = data, tt = function(z, t, ...) z * log(t))Differs from Stata Fixed workflow; adapt the named data columns explicitly. Match ties, risk intervals, weights and reference inference explicitly.
stcrreg
Fine-Gray subdistribution-hazard workflow
Stata
stcrreg x z, compete(cause==2)R Package:survival
{ expanded <- survival::finegray(survival::Surv(time, cause) ~ x + z + id, data = data, etype = "target"); survival::coxph(survival::Surv(fgstart, fgstop, fgstatus) ~ x + z, data = expanded, weights = fgwt, cluster = id) }Differs from Stata Fixed workflow; adapt the named data columns explicitly. Weighted expanded-data implementation; censoring weights and variance choices can differ.
stdescribe
Describe single-record survival data
Stata
stdescribeR Package:base
data.frame(subjects = nrow(data), failures = sum(data$event), time_at_risk = sum(data$time))Fixed workflow; adapt the named data columns explicitly. Single-record, zero-entry fixture; multiple-record subjects require distinct-ID counting.
stfill
Carry observed covariates forward within survival subjects
Stata
stfill z, forwardR Package:zoo
{ out <- data[order(data$id, data$start), ]; out$z <- ave(out$z, out$id, FUN = function(v) zoo::na.locf(v, na.rm = FALSE)); out }Differs from Stata Fixed workflow; adapt the named data columns explicitly. Requires correctly ordered non-overlapping spells. Leading missing values remain missing; later information is never carried backward.
stgen
Mark subjects ever exposed during their observed survival history
Stata
stgen ever_x = ever(x==1)R Package:stats
transform(data, ever_x = ave(x == 1, id, FUN = function(v) as.integer(any(v))))Differs from Stata Fixed workflow; adapt the named data columns explicitly. All observed spells contribute to the history. Missing exposure values require an explicit convention rather than treating NA as false.
stintreg
Lognormal regression for interval-censored outcomes
Stata
stintreg x, interval(lower upper) distribution(lognormal)R Package:survival
survival::survreg(survival::Surv(lower, upper, type = "interval2") ~ x, data = data, dist = "lognormal")Differs from Stata Stata requires interval(lower upper). The Weibull time option selects AFT coefficients, matching survreg rather than Stata default PH coefficients. For interval2, equal endpoints are exact events, NA lower endpoints denote left censoring, and NA upper endpoints right censoring; encode Stata left-censoring bounds explicitly.
Weibull regression for interval-censored outcomes
Stata
stintreg x, interval(lower upper) distribution(weibull) timeR Package:survival
survival::survreg(survival::Surv(lower, upper, type = "interval2") ~ x, data = data, dist = "weibull")Differs from Stata Stata requires interval(lower upper). The Weibull time option selects AFT coefficients, matching survreg rather than Stata default PH coefficients. For interval2, equal endpoints are exact events, NA lower endpoints denote left censoring, and NA upper endpoints right censoring; encode Stata left-censoring bounds explicitly.
stir
Compare two incidence rates
Stata
stir groupR Package:stats
{ counts <- tapply(data$event, data$group, sum); times <- tapply(data$time, data$group, sum); stats::poisson.test(counts, T = times) }Differs from Stata Fixed workflow; adapt the named data columns explicitly. R gives a conditional exact test and interval; Stata default intervals may use a different method.
stjoin
Rejoin adjacent constant-covariate spells
Stata
stjoinR Package:stats
{ out <- stats::aggregate(cbind(time = time - start, event) ~ id, data = spells, sum); names(out)[2] <- "duration"; out }Fixed workflow; adapt the named data columns explicitly. Only valid when adjacent spells have identical covariates and no intervening event; inspect before collapsing.
stmh
Mantel-Haenszel stratified incidence-rate-ratio point estimate
Stata
stmh exposed stratumR Package:base
with(data, sum(events1 * time0 / (time1 + time0)) / sum(events0 * time1 / (time1 + time0)))Fixed workflow; adapt the named data columns explicitly. Input is pre-aggregated failure counts and person-time by exposure/stratum. This supplies the rate-ratio point estimate only, not Stata’s variance or trend tests.
stptime
Crude incidence rate from person-time
Stata
stptimeR Package:base
{ pt <- sum(data$time); events <- sum(data$event); c(person_time = pt, failures = events, rate = events / pt) }Fixed workflow; adapt the named data columns explicitly. Assumes zero entry times and non-overlapping observation spells.
strate
Group-specific rates per thousand person-time units
Stata
strate group, per(1000)R Package:stats
{ out <- stats::aggregate(cbind(time, event) ~ group, data, sum); out$rate_per_1000 <- 1000 * out$event / out$time; out }Fixed workflow; adapt the named data columns explicitly. Point-rate workflow; confidence intervals need a separate choice.
streg
Parametric survival model
Stata
streg x, distribution(weibull)R Package:survival
survival::survreg(survival::Surv(time, died) ~ x, data = data, dist = "weibull")Differs from Stata survreg() reports the accelerated failure-time form; Stata’s Weibull default is the hazard form, so signs and scales differ.
7 more examples and alternatives
exponential accelerated-failure-time model
Stata
streg x z, distribution(exponential) timeR Package:survival
survival::survreg(survival::Surv(time, event) ~ x + z, data = data, dist = "exponential")Differs from Stata Fixed workflow; adapt the named data columns explicitly. survreg reports AFT coefficients; Weibull PH coefficients require sign and scale conversion.
loglogistic accelerated-failure-time model
Stata
streg x z, distribution(loglogistic) timeR Package:survival
survival::survreg(survival::Surv(time, event) ~ x + z, data = data, dist = "loglogistic")Differs from Stata Fixed workflow; adapt the named data columns explicitly. survreg reports AFT coefficients; Weibull PH coefficients require sign and scale conversion.
lognormal accelerated-failure-time model
Stata
streg x z, distribution(lognormal) timeR Package:survival
survival::survreg(survival::Surv(time, event) ~ x + z, data = data, dist = "lognormal")Differs from Stata Fixed workflow; adapt the named data columns explicitly. survreg reports AFT coefficients; Weibull PH coefficients require sign and scale conversion.
weibull accelerated-failure-time model
Stata
streg x z, distribution(weibull) timeR Package:survival
survival::survreg(survival::Surv(time, event) ~ x + z, data = data, dist = "weibull")Differs from Stata Fixed workflow; adapt the named data columns explicitly. survreg reports AFT coefficients; Weibull PH coefficients require sign and scale conversion.
loglogistic AFT model with group-specific scale
Stata
streg x, distribution(loglogistic) strata(group) timeR Package:survival
survival::survreg(survival::Surv(time, event) ~ x + factor(group) + strata(group), data = data, dist = "loglogistic")Differs from Stata factor(group) gives stratum-specific intercepts and strata(group) gives stratum-specific scales, as in Stata streg, strata(). survreg reports AFT coefficients; convert Weibull/exponential coefficients before comparing Stata hazard-ratio output.
lognormal AFT model with group-specific scale
Stata
streg x, distribution(lognormal) strata(group) timeR Package:survival
survival::survreg(survival::Surv(time, event) ~ x + factor(group) + strata(group), data = data, dist = "lognormal")Differs from Stata factor(group) gives stratum-specific intercepts and strata(group) gives stratum-specific scales, as in Stata streg, strata(). survreg reports AFT coefficients; convert Weibull/exponential coefficients before comparing Stata hazard-ratio output.
weibull AFT model with group-specific scale
Stata
streg x, distribution(weibull) strata(group) timeR Package:survival
survival::survreg(survival::Surv(time, event) ~ x + factor(group) + strata(group), data = data, dist = "weibull")Differs from Stata factor(group) gives stratum-specific intercepts and strata(group) gives stratum-specific scales, as in Stata streg, strata(). survreg reports AFT coefficients; convert Weibull/exponential coefficients before comparing Stata hazard-ratio output.
sts
Kaplan-Meier curve
Stata
sts graphR Package:survival
plot(survival::survfit(survival::Surv(time, died) ~ 1, data = data))Log-rank test
Stata
sts test groupR Package:survival
survival::survdiff(survival::Surv(time, died) ~ group, data = data)8 more examples and alternatives
Kaplan-Meier survival curve data
Stata
sts listR Package:survival
survival::survfit(s ~ 1)Differs from Stata Fixed workflow; adapt the named data columns explicitly. R returns curve data; confidence transformations and tied-event handling should be specified for comparisons.
Group-specific Kaplan-Meier curves
Stata
sts list, by(group)R Package:survival
survival::survfit(s ~ data$group)Differs from Stata Fixed workflow; adapt the named data columns explicitly. R returns curve data; confidence transformations and tied-event handling should be specified for comparisons.
Nelson-Aalen cumulative hazard
Stata
sts list, cumhazR Package:survival
{ f <- survival::survfit(s ~ 1); data.frame(time = f$time, cumhaz = f$cumhaz) }Differs from Stata Fixed workflow; adapt the named data columns explicitly. R returns curve data; confidence transformations and tied-event handling should be specified for comparisons.
Cumulative failure probability
Stata
sts list, failureR Package:survival
{ f <- survival::survfit(s ~ 1); data.frame(time = f$time, failure = 1 - f$surv) }Differs from Stata Fixed workflow; adapt the named data columns explicitly. R returns curve data; confidence transformations and tied-event handling should be specified for comparisons.
Kaplan-Meier interval with log transformation
Stata
sts list, level(95)R Package:survival
survival::survfit(s ~ 1, conf.type = "log", conf.int = .95)Fixed workflow; adapt the named data columns explicitly. Explicit R confidence transformation; Stata’s displayed default may differ.
Kaplan-Meier interval with log-log transformation
Stata
sts list, level(95)R Package:survival
survival::survfit(s ~ 1, conf.type = "log-log", conf.int = .95)Fixed workflow; adapt the named data columns explicitly. Explicit R confidence transformation; Stata’s displayed default may differ.
Kaplan-Meier interval with plain transformation
Stata
sts list, level(95)R Package:survival
survival::survfit(s ~ 1, conf.type = "plain", conf.int = .95)Fixed workflow; adapt the named data columns explicitly. Explicit R confidence transformation; Stata’s displayed default may differ.
Log-rank comparison of survival curves
Stata
sts test group R Package:survival
survival::survdiff(s ~ data$group, rho = 0)Differs from Stata Fixed workflow; adapt the named data columns explicitly. Unstratified two-group log-rank test.
stset
Declare survival-time data
Stata
stset time, failure(died)R Package:survival
survival::Surv(data$time, data$died)R has no declaration step: Surv(time, died) goes on the left of each model formula.
2 more examples and alternatives
Delayed-entry counting-process response
Stata
stset exit, enter(time entry) failure(event)R Package:survival
survival::Surv(data$entry, data$time, data$event)Differs from Stata Fixed workflow; adapt the named data columns explicitly. Supply entry and exit explicitly; multiple spells require one row per risk interval.
Right-censored survival response
Stata
stset time, failure(event)R Package:survival
survival::Surv(data$time, data$event)Differs from Stata Fixed workflow; adapt the named data columns explicitly. Creates a response object rather than declaring global dataset state.
stsplit
Split risk intervals at fixed cut points
Stata
stsplit period, at(3 6)R Package:survival
{ Surv <- survival::Surv; survival::survSplit(Surv(time, event) ~ ., data = data, cut = c(3, 6), start = "start", end = "time", event = "event", episode = "period") }Differs from Stata Fixed workflow; adapt the named data columns explicitly. Returns expanded interval data; the episode variable is an interval index.
stsum
Summary of survival times
Stata
stsumR Package:survival
survival::survfit(survival::Surv(time, died) ~ 1, data = data)1 more examples and alternatives
Person-time and failure counts by group
Stata
stsum, by(group)R Package:stats
stats::aggregate(cbind(person_time = time, failures = event) ~ group, data = data, FUN = sum)Fixed workflow; adapt the named data columns explicitly. Subset of stsum output; no survival quantiles are computed.
sttocc
Sample nested case-control risk sets from a cohort
Stata
sttocc, number(2)R Package:base
{ cases <- which(data$event == 1); sets <- lapply(seq_along(cases), function(j) { i <- cases[j]; at_risk <- which(data$entry <= data$time[i] & data$time >= data$time[i] & data$id != data$id[i]); controls <- sample(at_risk, min(2L, length(at_risk)), replace = FALSE); out <- data[c(i, controls), ]; out$case <- c(1L, rep(0L, length(controls))); out$set <- j; out$failure_time <- data$time[i]; out }); do.call(rbind, sets) }Fixed workflow; adapt the named data columns explicitly. One-record cohort with no tied failures. Controls are sampled from those at risk for each failure and may recur across sets; tied-failure random ordering and multiple spells need a fuller implementation.
stvary
Check within-subject covariate variation and missingness
Stata
stvary x zR Package:base
lapply(split(data, data$id), function(d) vapply(d[c("x", "z")], function(v) c(varies = length(unique(v[!is.na(v)])) > 1, any_missing = anyNA(v)), logical(2)))Fixed workflow; adapt the named data columns explicitly. Returns per-subject flags rather than Stata’s aggregate summary table; ignores sampling weights as stvary does.