Skip to content

Commit dbe5dbb

Browse files
committed
int2
1 parent a381af2 commit dbe5dbb

30 files changed

+3843
-232
lines changed

_freeze/confounding9/execute-results/html.json

Lines changed: 3 additions & 5 deletions
Large diffs are not rendered by default.

confounding9.qmd

Lines changed: 23 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
## Interaction {.unnumbered}
22

3-
# Introduction {-}
3+
Interaction is commonly assessed by either
44

5-
Interaction is commonly assessed by either creating a **joint exposure** factor or by including **main effects and a product term**. When the specification is saturated, these parameterizations are mathematically equivalent and encode the same set of contrasts on the log-odds scale. For clear presentation, it is often helpful to report the full set of joint effects relative to a single reference, and selected simple effects within strata, alongside additive interaction measures [@knol2012recommendations].
5+
(1) creating a **joint exposure** factor or
6+
(2) by including **main effects and a product term**.
7+
8+
When the specification is saturated, these parameterizations are mathematically equivalent and encode the same set of contrasts on the log-odds scale.
9+
10+
For clear presentation, it is often helpful to report the full set of joint effects relative to a single reference, and selected simple effects within strata, alongside additive interaction measures [@knol2012recommendations].
611

712
The motivating example in this document uses publicly available **NHANES 2009–2012** data, studying hypertension defined by systolic blood pressure ≥ 130 mmHg and examining whether the effect of obesity differs across levels of self reported race or ethnicity.
813

914
We will use interaction analysis functions (`jointeffects, inteffects, addint, addintlist` from `svyTable1` package) to compute and present joint effects, simple effects, and additive interaction measures with appropriate survey adjustments from saturated logistic regression models.
1015

11-
# Methods {-}
12-
1316
## Data and variables {-}
1417

1518
We use **NHANES 2009–2012** adults (Age ≥ 20) with survey design variables. The binary outcome is **Hypertension_130**, defined from average systolic BP. The two interacting exposures are **Race1** and **ObeseStatus** derived from BMI ≥ 30, with `"White"` and `"Not Obese"` as reference levels. We adjust for **Age**.
@@ -54,14 +57,16 @@ adult_design <- svydesign(
5457
)
5558
5659
f1_levels <- levels(adult_design$variables$Race1)
60+
kable(f1_levels)
5761
f2_levels <- levels(adult_design$variables$ObeseStatus)
62+
kable(f2_levels)
5863
```
5964

6065
## Models {-}
6166

6267
### Model 1. Joint variable model {-}
6368

64-
Create one factor for all combinations of Race1 × ObeseStatus with `"White_Not Obese"` as the reference, and fit a survey-weighted logistic regression adjusting for Age.
69+
Create one factor (variable) for all combinations of Race1 × ObeseStatus with `"White_Not Obese"` as the reference, and fit a survey-weighted logistic regression adjusting for Age.
6570

6671
```{r joint-model, cache=TRUE}
6772
# Create joint exposure factor inside the data
@@ -70,6 +75,7 @@ nhanes_adults <- nhanes_adults %>%
7075
Race1_ObeseStatus = interaction(Race1, ObeseStatus, sep = "_"),
7176
Race1_ObeseStatus = relevel(Race1_ObeseStatus, ref = "White_Not Obese")
7277
)
78+
kable(levels(nhanes_adults$Race1_ObeseStatus))
7379
7480
# Recreate survey design with the new variable included
7581
adult_design_joint <- svydesign(
@@ -86,8 +92,7 @@ joint_model <- svyglm(
8692
design = adult_design_joint,
8793
family = binomial()
8894
)
89-
90-
m1 <- publish(joint_model)
95+
m1 <- publish(joint_model)
9196
```
9297

9398
### Model 2. Interaction term model {-}
@@ -100,12 +105,9 @@ interaction_model <- survey::svyglm(
100105
design = adult_design,
101106
family = binomial()
102107
)
103-
104-
m2 <- publish(interaction_model)
108+
m2 <- publish(interaction_model)
105109
```
106110

107-
# Results {-}
108-
109111
## Joint effects from either parameterization {-}
110112

111113
Retrieve the **joint effects** for each Race1 × ObeseStatus combination relative to `"White & Not Obese"`. From the interaction model we obtain these by post-estimation transformation using the function `jointeffects`. From the joint model they correspond directly to exponentiated coefficients for the non-reference levels.
@@ -122,7 +124,11 @@ joint_from_interaction <- jointeffects(
122124
kable(joint_from_interaction,
123125
caption = "Table 1. Joint effects (OR) for Race1 × ObeseStatus vs White & Not Obese") %>%
124126
kable_styling(full_width = FALSE)
127+
```
128+
129+
### Check equivalence of results obtained from joint variable model
125130

131+
```{r joint-effects-table2, results='asis', cache=TRUE}
126132
kable(m1$regressionTable)
127133
```
128134

@@ -146,7 +152,11 @@ simple_from_joint <- inteffects(
146152
kable(simple_from_joint,
147153
caption = "Table 2. Simple effects: Obese vs Not Obese within Race1 strata") %>%
148154
kable_styling(full_width = FALSE)
155+
```
149156

157+
### Check equivalence of results obtained from interaction model
158+
159+
```{r simple-effects-table2, results='asis', cache=TRUE}
150160
kable(m2$regressionTable)
151161
```
152162

@@ -168,57 +178,14 @@ kable(add_tab,
168178
kable_styling(full_width = FALSE)
169179
```
170180

171-
# Discussion {-}
181+
## Reporting guideline {-}
172182

173183
The NHANES example illustrates that, under saturation, the joint-variable and interaction-term parameterizations are equivalent on the multiplicative scale. The joint-variable model directly presents the set of contrasts most often recommended for reporting, while the interaction model provides the traditional interaction coefficient and requires transformation to recover the same joint effects. Either model supports simple effects within strata. Reporting both joint and selected simple effects, together with additive interaction measures, provides a more complete summary.
174184

175-
# Key messages {-}
185+
## Key messages {-}
176186

177187
- Under saturation, joint and interaction models encode the same multiplicative contrasts.
178188
- Present the full set of joint effects against a single reference profile.
179189
- Include selected simple effects and additive interaction measures for clarity.
180190

181-
# Appendix {-}
182-
183-
## Minimal code to reproduce tables {-}
184-
185-
```{r echo=TRUE, eval=FALSE, cache=TRUE}
186-
# Joint effects from interaction model
187-
joint_from_interaction <- jointeffects(
188-
interaction_model = interaction_model,
189-
factor1_name = "Race1",
190-
factor2_name = "ObeseStatus",
191-
scale = "ratio",
192-
digits = 2
193-
)
194-
195-
# Simple effects from joint model
196-
simple_from_joint <- inteffects(
197-
joint_model = joint_model,
198-
joint_var_name = "Race1_ObeseStatus",
199-
factor1_name = "Race1",
200-
factor2_name = "ObeseStatus",
201-
factor1_levels = f1_levels,
202-
factor2_levels = f2_levels,
203-
level_separator = "-",
204-
scale = "ratio",
205-
digits = 2
206-
)
207-
208-
# Additive interaction measures
209-
add_tab <- addintlist(
210-
model = interaction_model,
211-
factor1_name = "Race1",
212-
factor2_name = "ObeseStatus",
213-
measures = "all",
214-
digits = 3
215-
)
216-
217-
list(
218-
joint_effects = head(joint_from_interaction, 4),
219-
simple_effects = head(simple_from_joint, 4),
220-
additive = head(add_tab, 4)
221-
)
222-
```
223-
224191
# References

confounding9_cache/html/__packages

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Matrix
2+
survival
3+
survey
4+
dplyr
5+
NHANES
6+
tidyr
7+
knitr
8+
prodlim
9+
Publish
10+
kableExtra
11+
svyTable1
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)