Contrast estimates from a fitted design

Description

The second step of the two-step API (mirroring causatr::contrast() and the etverse convention): given a matcha() fit, compute the requested effect on the chosen scale and return a matchatr_result. matcha() resolves the sampling design and runs the analysis; contrast() turns the fitted estimates into a reported effect with uncertainty.

Usage

contrast(
  fit,
  type = c("difference", "ratio", "or", "hr", "af", "excess", "rmst"),
  ci_method = c("model", "sandwich", "bootstrap"),
  conf_level = 0.95,
  times = NULL,
  ...
)

Arguments

fit A matchatr_fit object returned by matcha().
type Character contrast scale: “difference”, “ratio”, “or” (odds ratio), “hr” (hazard ratio, nested case-control risk-set / weighted Cox), “af” (acceleration factor / time ratio, the IPW NCC accelerated failure time model), “excess” (excess hazard / additive rate difference, the IPW NCC additive-hazards model), or “rmst” (restricted mean survival time difference, the design-weighted causal-survival estimator). When omitted, it defaults to the estimand the design and estimator identify — “or” for the classical odds-ratio engines, “hr” for the risk-set / weighted Cox engines, “af” for ipw_aft, “excess” for ipw_aalen, “difference” otherwise. Each estimator identifies exactly one family of scales, so an off-scale request aborts with matchatr_unidentified_estimand.
ci_method Character variance source for the interval: “model” (information-matrix Wald, the default), “sandwich” (Huber-White robust), or “bootstrap”.
conf_level Numeric confidence level for the interval, a single number strictly in (0, 1). Defaults to 0.95.
times Numeric vector of follow-up times (risk difference / ratio) or RMST horizons at which to report a marginal causal-survival contrast (the design-weighted surv_gcomp estimator). Required for that estimator; ignored by the non-survival engines. Defaults to NULL.
Reserved for estimator-specific contrast arguments. The case-control-weighted estimators accept n_boot (integer, default 1000), the number of within-stratum bootstrap replicates used when ci_method = “bootstrap”.

Details

What is identifiable depends on the design. From an unmatched case-control sample only the conditional odds ratio (type = “or”) is identified: under separate case / control sampling the marginal outcome frequency is fixed, so a marginal risk difference (type = “difference”) or risk ratio (type = “ratio”) requires the source-population prevalence q0 and a case-control-weighted estimator. Requesting an unidentified estimand aborts with the classed matchatr_unidentified_estimand condition.

A fit whose engine has no wired estimator carries no estimates — its model slot is NULL — so contrast() validates its arguments and then aborts with matchatr_not_estimated.

For an odds-ratio result the confidence interval is Wald on the log scale and exponentiated, so it is asymmetric on the OR scale: estimate +/- z * se does not reproduce the reported ci_lower / ci_upper (the se is the delta-method OR-scale SE, kept for reference). Use the reported bounds.

Value

A matchatr_result object carrying the estimates, the contrasts, and their variance-covariance matrix.

See Also

matcha(), tidy.matchatr_fit()

Other contrasts: absolute_risk(), excess_risk(), print.matchatr_absolute_risk(), print.matchatr_excess_risk(), tidy.matchatr_absolute_risk(), tidy.matchatr_excess_risk()

Examples

library("matchatr")

set.seed(1)
df <- data.frame(
  case = rep(c(1, 0), each = 100),
  x = rbinom(200, 1, 0.4),
  age = rnorm(200, 50, 10)
)
fit <- matcha(df, outcome = "case", exposure = "x",
              design = unmatched_cc(), confounders = ~ age)
# The conditional odds ratio is identified:
contrast(fit, type = "or")
<matchatr_result>
 Estimator:  logistic  (engine: glm_logistic)
 Estimand:   conditional OR
 Contrast:   Odds ratio
 CI method:  model
 N:          200

Contrasts:
   comparison estimate        se  ci_lower ci_upper
       <char>    <num>     <num>     <num>    <num>
1:          x 1.127078 0.3239669 0.6416305 1.979808
# The risk difference is not (no prevalence q0):
try(contrast(fit, type = "difference"))
Error in contrast(fit = fit, type = "difference") : 
  The risk difference is not identified from an unmatched case-control sample without the source-population prevalence q0.
ℹ Report the conditional odds ratio with `type = "or"`.
ℹ For a marginal risk difference / ratio, supply `prevalence =` on the design and use a case-control-weighted estimator (e.g. `estimator = "ccw_gformula"`).