Cox models are the most commonly used methods to estimate the magnitude of the effect in survival analyses. It assumes proportional hazards; that is, it assumes that the ratio of the hazards of the two groups (e.g. two arms) is constant over time. This ratio is referred to as the “hazard ratio” and is one of the most commonly reported metrics to describe the effect size in survival analysis.
The summarize_coxreg function fits, tidies and arranges a Cox regression model in a table layout using the rtables framework. For a Cox regression model, arguments variables, control, and at can be specified (see ?summarize_coxreg for more details and customization options). All variables specified within variables must be present in the data used when building the table.
To see the same model as a data.frame object, these three arguments (as well as the data) can be passed to the fit_coxreg_univar function, and the resulting list tidied using broom::tidy().
variables <-list(time ="AVAL",event ="EVENT",arm ="ARM",covariates =c("AGE", "SEX", "RACE"))lyt <-basic_table() %>%split_cols_by("col_label") %>%summarize_coxreg(variables = variables) %>%append_topleft("Effect/Covariate Included in the Model")result <-build_table(lyt = lyt, df = anl)result
Treatment Effect Adjusted for Covariate
Effect/Covariate Included in the Model n Hazard Ratio 95% CI p-value
—————————————————————————————————————————————————————————————————————————————————————————
Treatment:
A: Drug X vs control (B: Placebo) 247 0.97 (0.66, 1.43) 0.8934
Covariate:
Age 247 0.95 (0.65, 1.40) 0.7948
Sex 247 0.98 (0.67, 1.43) 0.8970
Race 247 0.98 (0.67, 1.44) 0.9239
Experimental use!
WebR is a tool allowing you to run R code in the web browser. Modify the code below and click run to see the results. Alternatively, copy the code and click here to open WebR in a new tab.
The argument control can be used to modify standard outputs; control_coxreg() helps in adopting the right settings (see ?control_coxreg). For instance, control is used to include the interaction terms.
Treatment Effect Adjusted for Covariate
Effect/Covariate Included in the Model n Hazard Ratio 95% CI p-value Interaction p-value
——————————————————————————————————————————————————————————————————————————————————————————————————————————
Treatment:
A: Drug X vs control (B: Placebo) 247 0.97 (0.66, 1.43) 0.8934
Covariate:
Age 247 0.7878
34 0.95 (0.65, 1.40)
Race 247 0.6850
ASIAN 1.05 (0.63, 1.75)
BLACK OR AFRICAN AMERICAN 1.08 (0.51, 2.29)
WHITE 0.67 (0.27, 1.71)
Experimental use!
WebR is a tool allowing you to run R code in the web browser. Modify the code below and click run to see the results. Alternatively, copy the code and click here to open WebR in a new tab.
The optional argument at allows the user to provide the expected level of estimation for the interaction when the predictor is a quantitative variable. For instance, it might be relevant to choose the age at which the hazard ratio should be estimated. If no input is provided to at, the median value is used in the row name (as in the previous tab).
Treatment Effect Adjusted for Covariate
Effect/Covariate Included in the Model n Hazard Ratio 95% CI p-value Interaction p-value
——————————————————————————————————————————————————————————————————————————————————————————————————————————
Treatment:
A: Drug X vs control (B: Placebo) 247 0.97 (0.66, 1.43) 0.8934
Covariate:
Age 247 0.7878
30 0.98 (0.63, 1.51)
40 0.91 (0.54, 1.51)
50 0.84 (0.32, 2.20)
Sex 247 0.1455
F 0.77 (0.47, 1.27)
M 1.38 (0.75, 2.52)
Experimental use!
WebR is a tool allowing you to run R code in the web browser. Modify the code below and click run to see the results. Alternatively, copy the code and click here to open WebR in a new tab.
Additional controls can be customized using control_coxreg (see ?control_coxreg) such as the ties calculation method and the confidence level. Stratification variables can be added via the strata element of the variables list.
Treatment Effect Adjusted for Covariate
Effect/Covariate Included in the Model n Hazard Ratio 90% CI p-value Interaction p-value
——————————————————————————————————————————————————————————————————————————————————————————————————————————
Treatment:
A: Drug X vs control (B: Placebo) 247 0.98 (0.71, 1.35) 0.9063
Covariate:
Age 247 0.7733
30 0.98 (0.68, 1.42)
40 0.91 (0.59, 1.39)
50 0.84 (0.38, 1.87)
Race 247 0.6501
ASIAN 1.07 (0.64, 1.77)
BLACK OR AFRICAN AMERICAN 1.08 (0.51, 2.29)
WHITE 0.66 (0.26, 1.67)
Experimental use!
WebR is a tool allowing you to run R code in the web browser. Modify the code below and click run to see the results. Alternatively, copy the code and click here to open WebR in a new tab.
Code
library(dplyr)library(tern)adsl <- random.cdisc.data::cadsladtte <- random.cdisc.data::cadtte# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels.adsl <-df_explicit_na(adsl)adtte <-df_explicit_na(adtte)adsl_filtered <- adsl %>% dplyr::filter( RACE %in%c("ASIAN", "BLACK OR AFRICAN AMERICAN", "WHITE"))adtte_filtered <- dplyr::inner_join(x = adsl_filtered[, c("STUDYID", "USUBJID")],y = adtte,by =c("STUDYID", "USUBJID"))anl <- adtte_filtered %>%filter(PARAMCD =="OS") %>%mutate(EVENT =1- CNSR) %>%filter(ARM %in%c("B: Placebo", "A: Drug X")) %>%mutate(ARM =droplevels(relevel(ARM, "B: Placebo"))) %>%mutate(RACE =droplevels(RACE) %>% formatters::with_label("Race"))# Add variable for column split labelanl <- anl %>%mutate(col_label ="Treatment Effect Adjusted for Covariate")
library(teal.modules.clinical)arm_ref_comp <-list(ACTARMCD =list(ref ="ARM B",comp =c("ARM A", "ARM C") ),ARM =list(ref ="B: Placebo",comp =c("A: Drug X", "C: Combination") ))## Data reproducible codedata <-teal_data()data <-within(data, { ADSL <- random.cdisc.data::cadsl ADTTE <- random.cdisc.data::cadtte# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. ADSL <-df_explicit_na(ADSL) ADTTE <-df_explicit_na(ADTTE)})datanames <-c("ADSL", "ADTTE")datanames(data) <- datanamesjoin_keys(data) <- default_cdisc_join_keys[datanames]## Reusable Configuration For ModulesADTTE <- data[["ADTTE"]]## Setup Appapp <-init(data = data,modules =modules(tm_t_coxreg(label ="Cox Reg.",dataname ="ADTTE",arm_var =choices_selected(c("ARM", "ACTARMCD"), "ARM"),arm_ref_comp = arm_ref_comp,paramcd =choices_selected(value_choices(ADTTE, "PARAMCD", "PARAM"), "OS" ),strata_var =choices_selected(c("SEX", "STRATA1", "STRATA2"), NULL ),cov_var =choices_selected(c("AGE", "SEX", "RACE"), "AGE" ),multivariate =FALSE ) ))shinyApp(app$ui, app$server)
Experimental use!
shinylive allow you to modify to run shiny application entirely in the web browser. Modify the code below and click re-run the app to see the results. The performance is slighly worse and some of the features (e.g. downloading) might not work at all.
#| '!! shinylive warning !!': |#| shinylive does not work in self-contained HTML documents.#| Please set `embed-resources: false` in your metadata.#| standalone: true#| viewerHeight: 800#| editorHeight: 200#| components: [viewer, editor]#| layout: vertical# -- WEBR HELPERS --options(webr_pkg_repos = c("r-universe" = "https://insightsengineering.r-universe.dev", getOption("webr_pkg_repos")))# -- APP CODE --library(teal.modules.clinical)arm_ref_comp <- list( ACTARMCD = list( ref = "ARM B", comp = c("ARM A", "ARM C") ), ARM = list( ref = "B: Placebo", comp = c("A: Drug X", "C: Combination") ))## Data reproducible codedata <- teal_data()data <- within(data, { ADSL <- random.cdisc.data::cadsl ADTTE <- random.cdisc.data::cadtte # Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. ADSL <- df_explicit_na(ADSL) ADTTE <- df_explicit_na(ADTTE)})datanames <- c("ADSL", "ADTTE")datanames(data) <- datanamesjoin_keys(data) <- default_cdisc_join_keys[datanames]## Reusable Configuration For ModulesADTTE <- data[["ADTTE"]]## Setup Appapp <- init( data = data, modules = modules( tm_t_coxreg( label = "Cox Reg.", dataname = "ADTTE", arm_var = choices_selected(c("ARM", "ACTARMCD"), "ARM"), arm_ref_comp = arm_ref_comp, paramcd = choices_selected( value_choices(ADTTE, "PARAMCD", "PARAM"), "OS" ), strata_var = choices_selected( c("SEX", "STRATA1", "STRATA2"), NULL ), cov_var = choices_selected( c("AGE", "SEX", "RACE"), "AGE" ), multivariate = FALSE ) ))shinyApp(app$ui, app$server)
---title: COXT01subtitle: Cox Regression---------------------------------------------------------------------------{{< include ../../_utils/envir_hook.qmd >}}```{r setup, echo = FALSE, warning = FALSE, message = FALSE}library(dplyr)library(tern)adsl <- random.cdisc.data::cadsladtte <- random.cdisc.data::cadtte# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels.adsl <- df_explicit_na(adsl)adtte <- df_explicit_na(adtte)adsl_filtered <- adsl %>% dplyr::filter( RACE %in% c("ASIAN", "BLACK OR AFRICAN AMERICAN", "WHITE"))adtte_filtered <- dplyr::inner_join( x = adsl_filtered[, c("STUDYID", "USUBJID")], y = adtte, by = c("STUDYID", "USUBJID"))anl <- adtte_filtered %>% filter(PARAMCD == "OS") %>% mutate(EVENT = 1 - CNSR) %>% filter(ARM %in% c("B: Placebo", "A: Drug X")) %>% mutate(ARM = droplevels(relevel(ARM, "B: Placebo"))) %>% mutate(RACE = droplevels(RACE) %>% formatters::with_label("Race"))# Add variable for column split labelanl <- anl %>% mutate(col_label = "Treatment Effect Adjusted for Covariate")``````{r include = FALSE}webr_code_labels <- c("setup")```{{< include ../../_utils/webr_no_include.qmd >}}## OutputCox models are the most commonly used methods to estimate the magnitude of the effect in survival analyses. It assumes proportional hazards; that is, it assumes that the ratio of the hazards of the two groups (e.g. two arms) is constant over time. This ratio is referred to as the "hazard ratio" and is one of the most commonly reported metrics to describe the effect size in survival analysis.::::::: panel-tabset## Cox RegressionThe `summarize_coxreg` function fits, tidies and arranges a Cox regression model in a table layout using the `rtables` framework. For a Cox regression model, arguments `variables`, `control`, and `at` can be specified (see `?summarize_coxreg` for more details and customization options). All variables specified within `variables` must be present in the data used when building the table.To see the same model as a `data.frame` object, these three arguments (as well as the data) can be passed to the `fit_coxreg_univar` function, and the resulting list tidied using `broom::tidy()`.::: {.panel-tabset .nav-justified group="webr"}## {{< fa regular file-lines sm fw >}} Preview```{r variant1, test = list(result_v1 = "result")}variables <- list( time = "AVAL", event = "EVENT", arm = "ARM", covariates = c("AGE", "SEX", "RACE"))lyt <- basic_table() %>% split_cols_by("col_label") %>% summarize_coxreg(variables = variables) %>% append_topleft("Effect/Covariate Included in the Model")result <- build_table(lyt = lyt, df = anl)result``````{r include = FALSE}webr_code_labels <- c("variant1")```{{< include ../../_utils/webr.qmd >}}:::## Cox Regression <br/> with Interaction TermThe argument `control` can be used to modify standard outputs; `control_coxreg()` helps in adopting the right settings (see `?control_coxreg`). For instance, `control` is used to include the interaction terms.::: {.panel-tabset .nav-justified group="webr"}## {{< fa regular file-lines sm fw >}} Preview```{r variant2, test = list(result_v2 = "result")}variables <- list( time = "AVAL", event = "EVENT", arm = "ARM", covariates = c("AGE", "RACE"))lyt <- basic_table() %>% split_cols_by("col_label") %>% summarize_coxreg( variables = variables, control = control_coxreg(interaction = TRUE), .stats = c("n", "hr", "ci", "pval", "pval_inter") ) %>% append_topleft("Effect/Covariate Included in the Model")result <- build_table(lyt = lyt, df = anl)result``````{r include = FALSE}webr_code_labels <- c("variant2")```{{< include ../../_utils/webr.qmd >}}:::## Cox Regression <br/> Specifying CovariatesThe optional argument `at` allows the user to provide the expected level of estimation for the interaction when the predictor is a quantitative variable. For instance, it might be relevant to choose the age at which the hazard ratio should be estimated. If no input is provided to `at`, the median value is used in the row name (as in the previous tab).::: {.panel-tabset .nav-justified group="webr"}## {{< fa regular file-lines sm fw >}} Preview```{r variant3, test = list(result_v3 = "result")}variables <- list( time = "AVAL", event = "EVENT", arm = "ARM", covariates = c("AGE", "SEX"))lyt <- basic_table() %>% split_cols_by("col_label") %>% summarize_coxreg( variables = variables, control = control_coxreg(interaction = TRUE), at = list(AGE = c(30, 40, 50)), .stats = c("n", "hr", "ci", "pval", "pval_inter") ) %>% append_topleft("Effect/Covariate Included in the Model")result <- build_table(lyt = lyt, df = anl)result``````{r include = FALSE}webr_code_labels <- c("variant3")```{{< include ../../_utils/webr.qmd >}}:::## Cox Regression Setting <br/> Strata, Ties, Alpha LevelAdditional controls can be customized using `control_coxreg` (see `?control_coxreg`) such as the ties calculation method and the confidence level. Stratification variables can be added via the `strata` element of the `variables` list.::: {.panel-tabset .nav-justified group="webr"}## {{< fa regular file-lines sm fw >}} Preview```{r variant4, test = list(result_v4 = "result")}variables <- list( time = "AVAL", event = "EVENT", arm = "ARM", covariates = c("AGE", "RACE"), strata = "SEX")control <- control_coxreg( ties = "breslow", interaction = TRUE, conf_level = 0.90)lyt <- basic_table() %>% split_cols_by("col_label") %>% summarize_coxreg( variables = variables, control = control, at = list(AGE = c(30, 40, 50)), .stats = c("n", "hr", "ci", "pval", "pval_inter") ) %>% append_topleft("Effect/Covariate Included in the Model")result <- build_table(lyt = lyt, df = anl)result``````{r include = FALSE}webr_code_labels <- c("variant4")```{{< include ../../_utils/webr.qmd >}}:::## Data Setup```{r setup}#| code-fold: show```:::::::{{< include ../../_utils/save_results.qmd >}}## `teal` App::: {.panel-tabset .nav-justified}## {{< fa regular file-lines fa-sm fa-fw >}} Preview```{r teal, opts.label = c("skip_if_testing", "app")}library(teal.modules.clinical)arm_ref_comp <- list( ACTARMCD = list( ref = "ARM B", comp = c("ARM A", "ARM C") ), ARM = list( ref = "B: Placebo", comp = c("A: Drug X", "C: Combination") ))## Data reproducible codedata <- teal_data()data <- within(data, { ADSL <- random.cdisc.data::cadsl ADTTE <- random.cdisc.data::cadtte # Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. ADSL <- df_explicit_na(ADSL) ADTTE <- df_explicit_na(ADTTE)})datanames <- c("ADSL", "ADTTE")datanames(data) <- datanamesjoin_keys(data) <- default_cdisc_join_keys[datanames]## Reusable Configuration For ModulesADTTE <- data[["ADTTE"]]## Setup Appapp <- init( data = data, modules = modules( tm_t_coxreg( label = "Cox Reg.", dataname = "ADTTE", arm_var = choices_selected(c("ARM", "ACTARMCD"), "ARM"), arm_ref_comp = arm_ref_comp, paramcd = choices_selected( value_choices(ADTTE, "PARAMCD", "PARAM"), "OS" ), strata_var = choices_selected( c("SEX", "STRATA1", "STRATA2"), NULL ), cov_var = choices_selected( c("AGE", "SEX", "RACE"), "AGE" ), multivariate = FALSE ) ))shinyApp(app$ui, app$server)```{{< include ../../_utils/shinylive.qmd >}}:::{{< include ../../repro.qmd >}}