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 concordance

R 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, detail

R 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, basesurv

R 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, basechazard

R 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, median

R 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*, deviance

R 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*, dfbeta

R 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*, mgale

R 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*, scaledsch

R 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*, schoenfeld

R 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*, scores

R 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, csnell

R 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, hr

R 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, xb

R 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

stbase

R 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, median

R 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, rmean

R Package:survival

summary(survival::survfit(s ~ 1), rmean = "common")$table

Differs 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 x2

R 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.group

R 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 z

R 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, efron

R 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, exactp

R 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

stdescribe

R 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, forward

R 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) time

R 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 group

R 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

stjoin

R 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 stratum

R 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

stptime

R 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) time

R 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) time

R 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) time

R 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) time

R 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) time

R 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) time

R 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) time

R 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 graph

R Package:survival

plot(survival::survfit(survival::Surv(time, died) ~ 1, data = data))

Log-rank test

Stata

sts test group

R Package:survival

survival::survdiff(survival::Surv(time, died) ~ group, data = data)
8 more examples and alternatives

Kaplan-Meier survival curve data

Stata

sts list

R 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, cumhaz

R 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, failure

R 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

stsum

R 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 z

R 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.