Skip to content

Commit 6d893dc

Browse files
committed
Built site for prolfqua@1.4.0: ed9eedc
1 parent f598a3a commit 6d893dc

13 files changed

Lines changed: 704 additions & 42 deletions

articles/Comparing2Groups.html

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

articles/Contrasts_from_factors.html

Lines changed: 411 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

articles/Contrasts_from_factors.md

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,253 @@
11
# Contrasts from factors
2+
3+
## Purpose
4+
5+
When working with factorial experimental designs (e.g. two conditions
6+
crossed with three time points), specifying all the relevant contrasts
7+
by hand is tedious and error-prone. The `generate_contrasts` family of
8+
functions in prolfqua automates this by generating contrast
9+
specifications from factor levels. These contrast strings can then be
10+
passed directly to the `Contrasts` class for statistical testing.
11+
12+
This vignette demonstrates how to:
13+
14+
- Generate main effect, level-specific, and interaction contrasts for a
15+
two-factor design
16+
- Use `annotation_add_contrasts` to produce a combined annotation and
17+
contrast table ready for analysis
18+
19+
## Group labelling convention
20+
21+
All contrast generation functions assume that the group levels in the
22+
fitted model follow the naming convention `G_<primary>_<secondary>`,
23+
which is produced by
24+
[`group_label()`](https://wolski.github.io/prolfqua/reference/group_label.md):
25+
26+
``` r
27+
library(prolfqua)
28+
29+
group_label("MI", "T0")
30+
```
31+
32+
## [1] "G_MI_T0"
33+
34+
``` r
35+
group_label("MINOCA", "T300")
36+
```
37+
38+
## [1] "G_MINOCA_T300"
39+
40+
This means that before fitting a model, the data must contain a grouping
41+
column with levels in this format. The `annotation_add_contrasts`
42+
function creates such a column automatically using
43+
[`tidyr::unite`](https://tidyr.tidyverse.org/reference/unite.html).
44+
45+
## Building contrasts step by step
46+
47+
Consider a two-factor design with disease type (MI, MINOCA) and time
48+
point (T0, T150, T300):
49+
50+
``` r
51+
primary_levels <- c("MI", "MINOCA")
52+
secondary_levels <- c("T0", "T150", "T300")
53+
```
54+
55+
### Main effect contrasts
56+
57+
Main effects average across all levels of the secondary factor. For
58+
example, the main effect of MINOCA vs MI is the average difference
59+
across all time points:
60+
61+
``` r
62+
me <- main_effect_contrasts(primary_levels, secondary_levels)
63+
data.frame(ContrastName = names(me), Contrast = unlist(me))
64+
```
65+
66+
## ContrastName
67+
## MINOCA_vs_MI MINOCA_vs_MI
68+
## Contrast
69+
## MINOCA_vs_MI ( (G_MINOCA_T0 + G_MINOCA_T150 + G_MINOCA_T300)/3 - (G_MI_T0 + G_MI_T150 + G_MI_T300)/3 )
70+
71+
Swapping the roles of primary and secondary gives main effects for time
72+
points averaged across disease types:
73+
74+
``` r
75+
me2 <- main_effect_contrasts(secondary_levels, primary_levels)
76+
data.frame(ContrastName = names(me2), Contrast = unlist(me2))
77+
```
78+
79+
## ContrastName
80+
## T150_vs_T0 T150_vs_T0
81+
## T300_vs_T0 T300_vs_T0
82+
## T300_vs_T150 T300_vs_T150
83+
## Contrast
84+
## T150_vs_T0 ( (G_T150_MI + G_T150_MINOCA)/2 - (G_T0_MI + G_T0_MINOCA)/2 )
85+
## T300_vs_T0 ( (G_T300_MI + G_T300_MINOCA)/2 - (G_T0_MI + G_T0_MINOCA)/2 )
86+
## T300_vs_T150 ( (G_T300_MI + G_T300_MINOCA)/2 - (G_T150_MI + G_T150_MINOCA)/2 )
87+
88+
### Level-specific contrasts
89+
90+
These compare primary factor levels at each individual level of the
91+
secondary factor:
92+
93+
``` r
94+
ls <- level_specific_contrasts(primary_levels, secondary_levels)
95+
data.frame(ContrastName = names(ls), Contrast = unlist(ls))
96+
```
97+
98+
## ContrastName Contrast
99+
## MINOCA_vs_MI_at_T0 MINOCA_vs_MI_at_T0 G_MINOCA_T0 - G_MI_T0
100+
## MINOCA_vs_MI_at_T150 MINOCA_vs_MI_at_T150 G_MINOCA_T150 - G_MI_T150
101+
## MINOCA_vs_MI_at_T300 MINOCA_vs_MI_at_T300 G_MINOCA_T300 - G_MI_T300
102+
103+
### Interaction contrasts
104+
105+
Interaction contrasts test whether the difference between primary levels
106+
changes across secondary levels (difference of differences):
107+
108+
``` r
109+
ic <- interaction_contrasts(primary_levels, secondary_levels)
110+
data.frame(ContrastName = names(ic), Contrast = unlist(ic))
111+
```
112+
113+
## ContrastName
114+
## interaction_MINOCA_vs_MI_at_T150_vs_T0 interaction_MINOCA_vs_MI_at_T150_vs_T0
115+
## interaction_MINOCA_vs_MI_at_T300_vs_T0 interaction_MINOCA_vs_MI_at_T300_vs_T0
116+
## interaction_MINOCA_vs_MI_at_T300_vs_T150 interaction_MINOCA_vs_MI_at_T300_vs_T150
117+
## Contrast
118+
## interaction_MINOCA_vs_MI_at_T150_vs_T0 (G_MINOCA_T150 - G_MI_T150) - (G_MINOCA_T0 - G_MI_T0)
119+
## interaction_MINOCA_vs_MI_at_T300_vs_T0 (G_MINOCA_T300 - G_MI_T300) - (G_MINOCA_T0 - G_MI_T0)
120+
## interaction_MINOCA_vs_MI_at_T300_vs_T150 (G_MINOCA_T300 - G_MI_T300) - (G_MINOCA_T150 - G_MI_T150)
121+
122+
### Single-factor contrasts
123+
124+
For a one-factor design, `generate_contrasts_for_factor` generates all
125+
pairwise comparisons:
126+
127+
``` r
128+
group_levels <- c("CondA", "CondB", "CondC")
129+
sf <- generate_contrasts_for_factor(group_levels)
130+
data.frame(ContrastName = names(sf), Contrast = unlist(sf))
131+
```
132+
133+
## ContrastName Contrast
134+
## CondB_vs_CondA CondB_vs_CondA CondB - CondA
135+
## CondC_vs_CondA CondC_vs_CondA CondC - CondA
136+
## CondC_vs_CondB CondC_vs_CondB CondC - CondB
137+
138+
## Generating all contrasts at once
139+
140+
`generate_contrasts` combines main effects, level-specific, and
141+
interaction contrasts into a single data frame:
142+
143+
``` r
144+
all_contrasts <- generate_contrasts(primary_levels, secondary_levels)
145+
knitr::kable(all_contrasts, row.names = FALSE)
146+
```
147+
148+
| ContrastName | Contrast |
149+
|:-----------------------------------------|:------------------------------------------------------------------------------------------|
150+
| MINOCA_vs_MI | ( (G_MINOCA_T0 + G_MINOCA_T150 + G_MINOCA_T300)/3 - (G_MI_T0 + G_MI_T150 + G_MI_T300)/3 ) |
151+
| MINOCA_vs_MI_at_T0 | G_MINOCA_T0 - G_MI_T0 |
152+
| MINOCA_vs_MI_at_T150 | G_MINOCA_T150 - G_MI_T150 |
153+
| MINOCA_vs_MI_at_T300 | G_MINOCA_T300 - G_MI_T300 |
154+
| interaction_MINOCA_vs_MI_at_T150_vs_T0 | (G_MINOCA_T150 - G_MI_T150) - (G_MINOCA_T0 - G_MI_T0) |
155+
| interaction_MINOCA_vs_MI_at_T300_vs_T0 | (G_MINOCA_T300 - G_MI_T300) - (G_MINOCA_T0 - G_MI_T0) |
156+
| interaction_MINOCA_vs_MI_at_T300_vs_T150 | (G_MINOCA_T300 - G_MI_T300) - (G_MINOCA_T150 - G_MI_T150) |
157+
158+
To exclude interaction contrasts:
159+
160+
``` r
161+
no_int <- generate_contrasts(primary_levels, secondary_levels, interactions = FALSE)
162+
knitr::kable(no_int, row.names = FALSE)
163+
```
164+
165+
| ContrastName | Contrast |
166+
|:---------------------|:------------------------------------------------------------------------------------------|
167+
| MINOCA_vs_MI | ( (G_MINOCA_T0 + G_MINOCA_T150 + G_MINOCA_T300)/3 - (G_MI_T0 + G_MI_T150 + G_MI_T300)/3 ) |
168+
| MINOCA_vs_MI_at_T0 | G_MINOCA_T0 - G_MI_T0 |
169+
| MINOCA_vs_MI_at_T150 | G_MINOCA_T150 - G_MI_T150 |
170+
| MINOCA_vs_MI_at_T300 | G_MINOCA_T300 - G_MI_T300 |
171+
172+
## Working with annotation tables
173+
174+
In a typical prolfquapp workflow, you start with a sample annotation
175+
table that has columns for the two factors. `annotation_add_contrasts`
176+
creates a united Group column, generates all contrasts, and binds them
177+
alongside the annotation:
178+
179+
``` r
180+
# x5463yzwer453bbb is a bundled example annotation table
181+
# with factor_A (MI / MINOCA) and factor_B (T0 / T150 / T300)
182+
head(prolfqua::x5463yzwer453bbb[, c("Name", "Group", "factor_A", "factor_B")])
183+
```
184+
185+
## # A tibble: 6 × 4
186+
## Name Group factor_A factor_B
187+
## <chr> <chr> <chr> <chr>
188+
## 1 MI_150_6 MI_T150 MI T150
189+
## 2 MINOCA_0_3 MINOCA_T0 MINOCA T0
190+
## 3 MINOCA_300_5 MINOCA_T300 MINOCA T300
191+
## 4 MI_150_5 MI_T150 MI T150
192+
## 5 MI_150_1 MI_T150 MI T150
193+
## 6 MI_0_3 MI_T0 MI T0
194+
195+
``` r
196+
result <- annotation_add_contrasts(
197+
prolfqua::x5463yzwer453bbb,
198+
primary_col = "factor_A",
199+
secondary_col = "factor_B",
200+
prefix = "primary"
201+
)
202+
203+
# The annotation with united Group and contrast columns
204+
knitr::kable(head(result$annot[, c("Name", "Group", "ContrastName", "Contrast")], 10),
205+
row.names = FALSE)
206+
```
207+
208+
| Name | Group | ContrastName | Contrast |
209+
|:-------------|:------------|:-----------------------------------------|:------------------------------------------------------------------------------------------|
210+
| MI_150_6 | MI_T150 | MINOCA_vs_MI | ( (G_MINOCA_T0 + G_MINOCA_T150 + G_MINOCA_T300)/3 - (G_MI_T0 + G_MI_T150 + G_MI_T300)/3 ) |
211+
| MINOCA_0_3 | MINOCA_T0 | MINOCA_vs_MI_at_T0 | G_MINOCA_T0 - G_MI_T0 |
212+
| MINOCA_300_5 | MINOCA_T300 | MINOCA_vs_MI_at_T150 | G_MINOCA_T150 - G_MI_T150 |
213+
| MI_150_5 | MI_T150 | MINOCA_vs_MI_at_T300 | G_MINOCA_T300 - G_MI_T300 |
214+
| MI_150_1 | MI_T150 | interaction_MINOCA_vs_MI_at_T150_vs_T0 | (G_MINOCA_T150 - G_MI_T150) - (G_MINOCA_T0 - G_MI_T0) |
215+
| MI_0_3 | MI_T0 | interaction_MINOCA_vs_MI_at_T300_vs_T0 | (G_MINOCA_T300 - G_MI_T300) - (G_MINOCA_T0 - G_MI_T0) |
216+
| MINOCA_150_1 | MINOCA_T150 | interaction_MINOCA_vs_MI_at_T300_vs_T150 | (G_MINOCA_T300 - G_MI_T300) - (G_MINOCA_T150 - G_MI_T150) |
217+
| MI_300_2 | MI_T300 | NA | NA |
218+
| MINOCA_150_5 | MINOCA_T150 | NA | NA |
219+
| MI_300_3 | MI_T300 | NA | NA |
220+
221+
``` r
222+
# Suggested output file name
223+
result$name
224+
```
225+
226+
## [1] "DEA_primary_dataset.csv"
227+
228+
Swapping primary and secondary factors gives contrasts from the other
229+
perspective:
230+
231+
``` r
232+
result2 <- annotation_add_contrasts(
233+
prolfqua::x5463yzwer453bbb,
234+
primary_col = "factor_B",
235+
secondary_col = "factor_A",
236+
prefix = "secondary"
237+
)
238+
knitr::kable(head(result2$annot[, c("Name", "Group", "ContrastName", "Contrast")], 10),
239+
row.names = FALSE)
240+
```
241+
242+
| Name | Group | ContrastName | Contrast |
243+
|:-------------|:------------|:---------------------------------------|:------------------------------------------------------------------|
244+
| MI_150_6 | T150_MI | T150_vs_T0 | ( (G_T150_MI + G_T150_MINOCA)/2 - (G_T0_MI + G_T0_MINOCA)/2 ) |
245+
| MINOCA_0_3 | T0_MINOCA | T300_vs_T0 | ( (G_T300_MI + G_T300_MINOCA)/2 - (G_T0_MI + G_T0_MINOCA)/2 ) |
246+
| MINOCA_300_5 | T300_MINOCA | T300_vs_T150 | ( (G_T300_MI + G_T300_MINOCA)/2 - (G_T150_MI + G_T150_MINOCA)/2 ) |
247+
| MI_150_5 | T150_MI | T150_vs_T0_at_MI | G_T150_MI - G_T0_MI |
248+
| MI_150_1 | T150_MI | T150_vs_T0_at_MINOCA | G_T150_MINOCA - G_T0_MINOCA |
249+
| MI_0_3 | T0_MI | T300_vs_T0_at_MI | G_T300_MI - G_T0_MI |
250+
| MINOCA_150_1 | T150_MINOCA | T300_vs_T0_at_MINOCA | G_T300_MINOCA - G_T0_MINOCA |
251+
| MI_300_2 | T300_MI | T300_vs_T150_at_MI | G_T300_MI - G_T150_MI |
252+
| MINOCA_150_5 | T150_MINOCA | T300_vs_T150_at_MINOCA | G_T300_MINOCA - G_T150_MINOCA |
253+
| MI_300_3 | T300_MI | interaction_T150_vs_T0_at_MINOCA_vs_MI | (G_T150_MINOCA - G_T0_MINOCA) - (G_T150_MI - G_T0_MI) |

pkgdown.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ articles:
1010
QualityControlAndSampleSizeEstimation: QualityControlAndSampleSizeEstimation.html
1111
SimulateData: SimulateData.html
1212
TestingMissingInference: TestingMissingInference.html
13-
last_built: 2026-02-21T15:05Z
13+
last_built: 2026-02-21T16:22Z
1414
urls:
1515
reference: https://wolski.github.io/prolfqua/reference
1616
article: https://wolski.github.io/prolfqua/articles

reference/ModelFirth.html

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

reference/ModelFirth.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -326,9 +326,9 @@ mod$anova_histogram()
326326
#> Warning: not implemented
327327
#> NULL
328328
mod$write_coef_figures(tempdir())
329-
#> Writing figure into : /tmp/Rtmp6FlOkH/Coef_Histogram_modelFirth.pdf
330-
#> Writing figure into : /tmp/Rtmp6FlOkH/Coef_VolcanoPlot_modelFirth.pdf
331-
#> Writing figure into : /tmp/Rtmp6FlOkH/Coef_Pairsplot_modelFirth.pdf
329+
#> Writing figure into : /tmp/RtmpRM6e2C/Coef_Histogram_modelFirth.pdf
330+
#> Writing figure into : /tmp/RtmpRM6e2C/Coef_VolcanoPlot_modelFirth.pdf
331+
#> Writing figure into : /tmp/RtmpRM6e2C/Coef_Pairsplot_modelFirth.pdf
332332
#> # A tibble: 10 × 4
333333
#> subject_Id `(Intercept)` group_B group_Ctrl
334334
#> <chr> <dbl> <dbl> <dbl>
@@ -400,9 +400,9 @@ mod$anova_histogram()
400400
#> Warning: not implemented
401401
#> NULL
402402
mod$write_coef_figures(tempdir())
403-
#> Writing figure into : /tmp/Rtmp6FlOkH/Coef_Histogram_modelFirth.pdf
404-
#> Writing figure into : /tmp/Rtmp6FlOkH/Coef_VolcanoPlot_modelFirth.pdf
405-
#> Writing figure into : /tmp/Rtmp6FlOkH/Coef_Pairsplot_modelFirth.pdf
403+
#> Writing figure into : /tmp/RtmpRM6e2C/Coef_Histogram_modelFirth.pdf
404+
#> Writing figure into : /tmp/RtmpRM6e2C/Coef_VolcanoPlot_modelFirth.pdf
405+
#> Writing figure into : /tmp/RtmpRM6e2C/Coef_Pairsplot_modelFirth.pdf
406406
#> # A tibble: 10 × 4
407407
#> subject_Id `(Intercept)` group_B group_Ctrl
408408
#> <chr> <dbl> <dbl> <dbl>

0 commit comments

Comments
 (0)