Epidemiology

Start with the expanded example for each command. Open the variants for options and alternative R approaches. Read the qualifications before adapting the code.

cc

Case-control cross-product odds ratio

Stata

cc case exposed

R Package:base

unname(a * d / (b * c))

Differs from Stata Fixed workflow; adapt the named data columns explicitly. Odds ratio is identified under case-control sampling; absolute disease risk is not.

Exact conditional odds-ratio inference

Stata

cc case exposed, exact

R Package:stats

stats::fisher.test(tab, alternative = "two.sided")

Differs from Stata Fixed workflow; adapt the named data columns explicitly. Conditional estimate and two-sided p-value conventions can differ.

Approximate log-odds Wald interval

Stata

cc case exposed, woolf

R Package:stats

{ log_or <- log(a * d / (b * c)); se <- sqrt(sum(1 / tab)); exp(c(estimate = log_or, lower = log_or - qnorm(.975) * se, upper = log_or + qnorm(.975) * se)) }

Differs from Stata Fixed workflow; adapt the named data columns explicitly. Requires nonzero counts; no automatic continuity correction is applied.

cci

Case-control cross-product odds ratio

Stata

cci 20 10 80 90

R Package:base

unname(a * d / (b * c))

Differs from Stata Fixed workflow; adapt the named data columns explicitly. Odds ratio is identified under case-control sampling; absolute disease risk is not.

Exact conditional odds-ratio inference

Stata

cci 20 10 80 90, exact

R Package:stats

stats::fisher.test(tab, alternative = "two.sided")

Differs from Stata Fixed workflow; adapt the named data columns explicitly. Conditional estimate and two-sided p-value conventions can differ.

Approximate log-odds Wald interval

Stata

cci 20 10 80 90, woolf

R Package:stats

{ log_or <- log(a * d / (b * c)); se <- sqrt(sum(1 / tab)); exp(c(estimate = log_or, lower = log_or - qnorm(.975) * se, upper = log_or + qnorm(.975) * se)) }

Differs from Stata Fixed workflow; adapt the named data columns explicitly. Requires nonzero counts; no automatic continuity correction is applied.

cs

Risk ratio and risk difference

Stata

cs case exposed

R Package:base

{ risk1 <- a / (a + c); risk0 <- b / (b + d); c(risk_exposed = risk1, risk_unexposed = risk0, risk_ratio = risk1 / risk0, risk_difference = risk1 - risk0) }

Differs from Stata Fixed workflow; adapt the named data columns explicitly. Point measures assume a cohort with comparable follow-up; case-control sampling does not identify risk.

Exposed and population attributable fractions

Stata

cs case exposed

R Package:base

{ rr <- (a / (a + c)) / (b / (b + d)); af_exposed <- 1 - 1 / rr; risk_population <- (a + b) / (a + b + c + d); c(attributable_fraction_exposed = af_exposed, attributable_fraction_population = (risk_population - b / (b + d)) / risk_population) }

Differs from Stata Fixed workflow; adapt the named data columns explicitly. Causal interpretation additionally requires exchangeability and correct study sampling.

Fisher exact association test for cohort table

Stata

cs case exposed, exact

R Package:stats

stats::fisher.test(tab)

Differs from Stata Fixed workflow; adapt the named data columns explicitly. R reports a conditional maximum-likelihood odds ratio; Stata also reports sample cross-product measures.

Woolf odds-ratio interval in cohort table

Stata

cs case exposed, or woolf

R Package:stats

{ odds <- a * d / (b * c); se <- sqrt(1 / a + 1 / b + 1 / c + 1 / d); c(odds_ratio = odds, lower = exp(log(odds) - qnorm(.975) * se), upper = exp(log(odds) + qnorm(.975) * se)) }

Differs from Stata Fixed workflow; adapt the named data columns explicitly. Woolf approximation requires positive cell counts.

csi

Risk ratio and risk difference

Stata

csi 20 10 80 90

R Package:base

{ risk1 <- a / (a + c); risk0 <- b / (b + d); c(risk_exposed = risk1, risk_unexposed = risk0, risk_ratio = risk1 / risk0, risk_difference = risk1 - risk0) }

Differs from Stata Fixed workflow; adapt the named data columns explicitly. Point measures assume a cohort with comparable follow-up; case-control sampling does not identify risk.

Exposed and population attributable fractions

Stata

csi 20 10 80 90

R Package:base

{ rr <- (a / (a + c)) / (b / (b + d)); af_exposed <- 1 - 1 / rr; risk_population <- (a + b) / (a + b + c + d); c(attributable_fraction_exposed = af_exposed, attributable_fraction_population = (risk_population - b / (b + d)) / risk_population) }

Differs from Stata Fixed workflow; adapt the named data columns explicitly. Causal interpretation additionally requires exchangeability and correct study sampling.

Fisher exact association test for cohort table

Stata

csi 20 10 80 90, exact

R Package:stats

stats::fisher.test(tab)

Differs from Stata Fixed workflow; adapt the named data columns explicitly. R reports a conditional maximum-likelihood odds ratio; Stata also reports sample cross-product measures.

Woolf odds-ratio interval in cohort table

Stata

csi 20 10 80 90, or woolf

R Package:stats

{ odds <- a * d / (b * c); se <- sqrt(1 / a + 1 / b + 1 / c + 1 / d); c(odds_ratio = odds, lower = exp(log(odds) - qnorm(.975) * se), upper = exp(log(odds) + qnorm(.975) * se)) }

Differs from Stata Fixed workflow; adapt the named data columns explicitly. Woolf approximation requires positive cell counts.

dstdize

Direct standardization of stratum-specific rates

Stata

dstdize deaths population age, by(group) base(1)

R Package:base

sum(data$deaths / data$population * standard / sum(standard))

Fixed workflow; adapt the named data columns explicitly. Fixed one-population calculation; standard weights must represent the intended reference population.

ir

Incidence-rate ratio and rate difference

Stata

ir cases exposed time

R Package:base

c(rate_exposed = 20 / 100, rate_unexposed = 10 / 200, incidence_rate_ratio = (20 / 100) / (10 / 200), rate_difference = 20 / 100 - 10 / 200)

Differs from Stata Fixed workflow; adapt the named data columns explicitly. Counts and person-time denominators, not risks.

Exact comparison of two Poisson incidence rates

Stata

ir cases exposed time, exact

R Package:stats

stats::poisson.test(c(20, 10), T = c(100, 200))

Differs from Stata Fixed workflow; adapt the named data columns explicitly. Stata ir/iri default mid-p differs; this example requests exact inference.

iri

Incidence-rate ratio and rate difference

Stata

iri 20 10 100 200

R Package:base

c(rate_exposed = 20 / 100, rate_unexposed = 10 / 200, incidence_rate_ratio = (20 / 100) / (10 / 200), rate_difference = 20 / 100 - 10 / 200)

Differs from Stata Fixed workflow; adapt the named data columns explicitly. Counts and person-time denominators, not risks.

Exact comparison of two Poisson incidence rates

Stata

iri 20 10 100 200, exact

R Package:stats

stats::poisson.test(c(20, 10), T = c(100, 200))

Differs from Stata Fixed workflow; adapt the named data columns explicitly. Stata ir/iri default mid-p differs; this example requests exact inference.

istdize

Indirect standardization and mortality ratio

Stata

istdize deaths population age using reference, by(group)

R Package:base

{ expected <- sum(data$population * reference_rate); observed <- sum(data$deaths); c(observed = observed, expected = expected, SMR = observed / expected) }

Fixed workflow; adapt the named data columns explicitly. Point estimates only; reference strata and person-time units must match.

mcc

Matched odds ratio from discordant pairs

Stata

mcc exposed_case exposed_control

R Package:base

c(matched_odds_ratio = tab[1, 2] / tab[2, 1], discordant_pairs = tab[1, 2] + tab[2, 1])

Differs from Stata Fixed workflow; adapt the named data columns explicitly. Concordant pairs do not inform the matched odds ratio.

McNemar comparison of matched binary exposures

Stata

mcc exposed_case exposed_control

R Package:stats

stats::mcnemar.test(tab, correct = FALSE)

Differs from Stata Fixed workflow; adapt the named data columns explicitly. Uncorrected asymptotic statistic; exact or continuity-corrected alternatives differ.

mcci

Matched odds ratio from discordant pairs

Stata

mcci 30 12 4 54

R Package:base

c(matched_odds_ratio = tab[1, 2] / tab[2, 1], discordant_pairs = tab[1, 2] + tab[2, 1])

Differs from Stata Fixed workflow; adapt the named data columns explicitly. Concordant pairs do not inform the matched odds ratio.

McNemar comparison of matched binary exposures

Stata

mcci 30 12 4 54

R Package:stats

stats::mcnemar.test(tab, correct = FALSE)

Differs from Stata Fixed workflow; adapt the named data columns explicitly. Uncorrected asymptotic statistic; exact or continuity-corrected alternatives differ.

mhodds

Mantel-Haenszel common odds ratio

Stata

mhodds case exposed stratum

R Package:stats

stats::mantelhaen.test(tabs, correct = FALSE)

Differs from Stata Fixed workflow; adapt the named data columns explicitly. Table orientation determines the odds-ratio direction; assumes a common stratum effect.

tabodds

Odds of disease by exposure category

Stata

tabodds case exposed

R Package:stats

{ out <- stats::aggregate(case ~ exposed, data = data, function(v) c(cases = sum(v), noncases = sum(1 - v))); data.frame(exposed = out$exposed, odds = out$case[, 1] / out$case[, 2]) }

Fixed workflow; adapt the named data columns explicitly. Computes category odds only; no adjusted trend test.