Skip to contents

Calculates the joint effect for every combination of two interacting categorical variables, relative to the model's reference group. This function reproduces the output of a joint-variable model (e.g., `~ A_B`) using the results from an interaction-term model (e.g., `~ A * B`). Output can be specified on the log scale (e.g., log-OR/log-HR) or the ratio scale (e.g., OR/HR).

It works for various model types, including `svyglm`, `svycoxph`, `glm`, and `coxph`, by dynamically identifying the main effect and interaction coefficients.

Usage

jointeffects(
  interaction_model,
  factor1_name,
  factor2_name,
  scale = c("ratio", "log"),
  conf.level = 0.95,
  digits = 2
)

Arguments

interaction_model

A fitted model object (e.g., `svycoxph`, `svyglm`) containing a two-way interaction term (e.g., `A*B`).

factor1_name

Character string. The name of the first factor variable in the interaction (e.g., `"Race1"`).

factor2_name

Character string. The name of the second factor variable (e.g., `"ObeseStatus"`).

scale

Character string. The scale for the output estimates, CIs, and SE. Options are `"ratio"` (default, e.g., OR/HR) or `"log"` (log-OR/log-HR).

conf.level

Confidence level for the interval (default 0.95).

digits

Integer. Number of decimal places for rounding estimates, SE, and CIs when `scale = "ratio"`. Default is 2. (Set to NULL for no rounding).

Value

A `tibble` (data frame) with one row for each combination of factor levels. Columns include:

  • `Level1`: The level of the first factor.

  • `Level2`: The level of the second factor.

  • `Estimate`: The point estimate on the specified `scale`.

  • `SE`: The standard error on the specified `scale`. Calculated using the delta method for `scale = "ratio"`.

  • `CI.low`: The lower bound of the confidence interval (on the specified `scale`).

  • `CI.upp`: The upper bound of the confidence interval (on the specified `scale`).

Examples

# \donttest{
# --- Load required libraries for the example ---
if (requireNamespace("survey", quietly = TRUE) &&
    requireNamespace("NHANES", quietly = TRUE) &&
    requireNamespace("dplyr", quietly = TRUE) &&
    requireNamespace("tidyr", quietly = TRUE) &&
    requireNamespace("msm", quietly = TRUE)) { # msm needed for ratio SE

  library(survey)
  library(NHANES)
  library(dplyr)
  library(tidyr)
  library(msm) # Load msm

  # --- 1. Data Preparation (NHANES Example) ---
  data(NHANESraw)

  vars_needed <- c("Age", "Race1", "BPSysAve", "BMI", "ObeseStatus", "Hypertension_130",
                   "SDMVPSU", "SDMVSTRA", "WTMEC2YR")

  nhanes_adults_processed <- NHANESraw %>%
    filter(Age >= 20) %>%
    mutate(
      ObeseStatus = factor(ifelse(BMI >= 30, "Obese", "Not Obese"),
                           levels = c("Not Obese", "Obese")),
      Hypertension_130 = factor(ifelse(BPSysAve >= 130, "Yes", "No"),
                                levels = c("No", "Yes")),
      Race1 = relevel(as.factor(Race1), ref = "White")
    ) %>%
    select(all_of(vars_needed)) %>%
    drop_na()

  adult_design_binary <- svydesign(
    id = ~SDMVPSU, strata = ~SDMVSTRA, weights = ~WTMEC2YR,
    nest = TRUE, data = nhanes_adults_processed
  )

  # --- 2. Fit the Interaction Model ---
  interaction_model_logit <- svyglm(
    Hypertension_130 ~ Race1 * ObeseStatus + Age,
    design = adult_design_binary, family = quasibinomial()
  )

  # --- 3. Run the function ---

  # Example 1: Output on Ratio scale (default)
  joint_effects_ratio <- jointeffects(
    interaction_model = interaction_model_logit,
    factor1_name = "Race1",
    factor2_name = "ObeseStatus",
    scale = "ratio"
  )
  print("--- Joint Effects (Ratio Scale) ---")
  print(joint_effects_ratio, n = 50)

  # Example 2: Output on Log scale
  joint_effects_log <- jointeffects(
    interaction_model = interaction_model_logit,
    factor1_name = "Race1",
    factor2_name = "ObeseStatus",
    scale = "log"
  )
  print("--- Joint Effects (Log Scale) ---")
  print(joint_effects_log, n = 50)
}
#> [1] "--- Joint Effects (Ratio Scale) ---"
#> # A tibble: 10 × 6
#>    Level1   Level2    Estimate    SE CI.low CI.upp
#>    <chr>    <chr>        <dbl> <dbl>  <dbl>  <dbl>
#>  1 White    Not Obese     1     0      1      1   
#>  2 Black    Not Obese     2.11  0.21   1.73   2.58
#>  3 Hispanic Not Obese     0.99  0.12   0.77   1.27
#>  4 Mexican  Not Obese     1.17  0.12   0.95   1.43
#>  5 Other    Not Obese     1.05  0.1    0.87   1.28
#>  6 White    Obese         1.4   0.1    1.21   1.61
#>  7 Black    Obese         2.53  0.32   1.98   3.24
#>  8 Hispanic Obese         1.65  0.22   1.27   2.13
#>  9 Mexican  Obese         1.92  0.21   1.55   2.39
#> 10 Other    Obese         1.15  0.26   0.74   1.8 
#> [1] "--- Joint Effects (Log Scale) ---"
#> # A tibble: 10 × 6
#>    Level1   Level2    Estimate     SE  CI.low CI.upp
#>    <chr>    <chr>        <dbl>  <dbl>   <dbl>  <dbl>
#>  1 White    Not Obese  0       0       0       0    
#>  2 Black    Not Obese  0.748   0.101   0.550   0.946
#>  3 Hispanic Not Obese -0.00992 0.125  -0.255   0.235
#>  4 Mexican  Not Obese  0.154   0.104  -0.0493  0.358
#>  5 Other    Not Obese  0.0516  0.0983 -0.141   0.244
#>  6 White    Obese      0.335   0.0732  0.191   0.478
#>  7 Black    Obese      0.930   0.125   0.685   1.18 
#>  8 Hispanic Obese      0.498   0.132   0.240   0.756
#>  9 Mexican  Obese      0.655   0.112   0.436   0.873
#> 10 Other    Obese      0.141   0.229  -0.308   0.590
# }