
Cox regression fitting and formatting helpers
leo_cox.Rdleo_cox() fits one or more Cox proportional hazards models for a
single exposure and incident outcome. leo_cox_format() converts
the returned object into a wide summary table, tidy result table, or
gtsummary output.
Usage
leo_cox(
df,
y_out,
x_exp,
x_cov = NULL,
event_value = 1,
min_followup_time = 0,
x_exp_type = "auto",
simplify = "wide",
p_fmt = "threshold",
verbose = TRUE
)
leo_cox_format(x, style = "wide")Arguments
- df
Data frame containing the outcome, follow-up time, exposure, and covariates.
- y_out
Character vector of length 2 giving the event and follow-up time column names:
c(event, time).- x_exp
Character scalar giving the exposure column name.
- x_cov
NULL, a character vector of covariate column names, or a list of covariate column-name vectors. All models are fitted on the same complete-case cohort defined byy_out,x_exp, and all covariates that appear inx_cov. Ifx_covis a named list, those model names are preserved in the output columns.- event_value
Value in the event column that indicates incident events.
- min_followup_time
Numeric scalar; keep rows with
time > min_followup_time. Default is0, which excludes pre-baseline or baseline events when defining an incident outcome.- x_exp_type
Exposure type handling for
x_exp. Use"auto"to infer from the input type,"continuous"to force a numeric Cox term, or"categorical"to force factor coding. In"auto"mode, small integer-coded exposures will trigger a warning because they may represent categorical groups.- simplify
Output mode:
"wide"(default) returns the wide result table directly;"tidy"returns the tidy result table;FALSEreturns the fullleo_coxobject.- p_fmt
P-value display format:
"threshold"(default) uses<0.001;"scientific"uses scientific notation for p < 0.001 (e.g.2.300e-04).- verbose
Logical; print progress messages.
- x
Result returned by
leo_cox().- style
One of
"wide","tidy", or"gtsummary".
Value
When simplify = FALSE, a leo_cox object containing the default
wide table in $result, the underlying tidy rows in $result_tidy, model
metadata, and fitted coxph objects. When simplify = "wide" or
"tidy", the corresponding formatted table directly.
Formatting output
leo_cox_format() returns:
"wide": a wide summary data frame with one set of HR / CI / p-value columns per model."tidy": the row-level tidy result table stored inx$result_tidy, with formatted display columns added."gtsummary": agtsummaryregression table, or a mergedgtsummarytable when multiple models are present.
Examples
lung_df <- stats::na.omit(
dplyr::transmute(
survival::lung,
outcome = as.integer(status == 2),
outcome_censor = time / 365.25,
age = age,
sex = factor(sex, levels = c(1, 2), labels = c("Male", "Female")),
ecog_group = factor(ph.ecog, levels = 0:3, labels = c("ECOG0", "ECOG1", "ECOG2", "ECOG3"))
)
); head(lung_df)
#> outcome outcome_censor age sex ecog_group
#> 1 1 0.8377823 74 Male ECOG1
#> 2 1 1.2457221 68 Male ECOG0
#> 3 0 2.7652293 56 Male ECOG0
#> 4 1 0.5749487 57 Male ECOG1
#> 5 1 2.4175222 60 Male ECOG0
#> 6 0 2.7980835 74 Male ECOG1
model_cont <- list(
"Crude" = NULL,
"Model A" = c("sex"),
"Model B" = c("sex", "ecog_group")
)
res_age <- leo_cox(
df = lung_df, y_out = c("outcome", "outcome_censor"),
x_exp = "age", x_cov = model_cont, simplify = FALSE, verbose = FALSE
)
res_age$result
#> Exposure Outcome Case N Control N Person-years Class Crude HR
#> 1 age outcome 164 63 190.3409 Continuous 1.019
#> Crude 95% CI Crude P value Model A HR Model A 95% CI Model A P value
#> 1 1.001, 1.038 0.040 1.017 0.999, 1.036 0.061
#> Model B HR Model B 95% CI Model B P value
#> 1 1.011 0.993, 1.029 0.246
leo_cox_format(res_age, style = "tidy")
#> Model Exposure Outcome Level Case N Control N Person-years HR
#> 1 Crude age outcome <NA> 164 63 190.3409 1.019
#> 2 Model A age outcome <NA> 164 63 190.3409 1.017
#> 3 Model B age outcome <NA> 164 63 190.3409 1.011
#> 95% CI P value Class
#> 1 1.001, 1.038 0.040 Continuous
#> 2 0.999, 1.036 0.061 Continuous
#> 3 0.993, 1.029 0.246 Continuous
model_cat <- list(
"Crude" = NULL,
"Model A" = c("sex")
)
res_ecog <- leo_cox(
df = lung_df, y_out = c("outcome", "outcome_censor"),
x_exp = "ecog_group", x_cov = model_cat,
x_exp_type = "categorical", simplify = FALSE, verbose = FALSE
)
res_ecog$result
#> Exposure Outcome Case N Control N Person-years Class
#> 1 ECOG0 (Ref) outcome 37 26 60.6926762 Categorical (4 levels)
#> 2 ECOG1 outcome 82 31 97.2813142 Categorical (4 levels)
#> 3 ECOG2 outcome 44 6 32.0438056 Categorical (4 levels)
#> 4 ECOG3 outcome 1 0 0.3230664 Categorical (4 levels)
#> Crude HR Crude 95% CI Crude P value Model A HR Model A 95% CI
#> 1 1.000 1.000, 1.000 1.000 1.000 1.000, 1.000
#> 2 1.446 0.980, 2.134 0.063 1.519 1.028, 2.246
#> 3 2.500 1.610, 3.883 <0.001 2.579 1.660, 4.007
#> 4 9.097 1.218, 67.937 0.031 7.756 1.037, 58.039
#> Model A P value
#> 1 1.000
#> 2 0.036
#> 3 <0.001
#> 4 0.046
if (requireNamespace("gtsummary", quietly = TRUE) && requireNamespace("broom.helpers", quietly = TRUE)) {
leo_cox_format(res_age, style = "gtsummary")
}