rvlenth / emmeans

Estimated marginal means
https://rvlenth.github.io/emmeans/
340 stars 30 forks source link

how to compute contrasts between groups? #470

Closed saotts closed 3 months ago

saotts commented 3 months ago

I'm trying to compute contrasts between groups using emmeans:

df <- data.frame(x=rep(c("A","B","C","D"),times=4), z=rep(c("1","2"), each=8), y=runif(16)) mod <- lm(y ~ x*z, data=df) emm <- emmeans(mod, ~ x | z) p <- pairs(emm) p

z = 1: contrast estimate SE df t.ratio p.value A - B -0.7168 0.153 8 -4.689 0.0068 A - C -0.2783 0.153 8 -1.821 0.3312 A - D -0.4801 0.153 8 -3.140 0.0546 B - C 0.4385 0.153 8 2.869 0.0801 B - D 0.2368 0.153 8 1.549 0.4552 C - D -0.2017 0.153 8 -1.320 0.5768

z = 2: contrast estimate SE df t.ratio p.value A - B -0.6411 0.153 8 -4.194 0.0129 A - C -0.0139 0.153 8 -0.091 0.9997 A - D -0.2722 0.153 8 -1.781 0.3477 B - C 0.6272 0.153 8 4.103 0.0145 B - D 0.3689 0.153 8 2.413 0.1516 C - D -0.2583 0.153 8 -1.690 0.3877

I'd like to compare contrast A-B for z=1 vs z=2, A-C for z=1 vs z=2, etc. Is this possible with emmeans? Running pairs(p) won't work as it simply compares contrasts within each z.

rvlenth commented 3 months ago

When you put

emm <- emmeans(mod, ~ x | z)

That sets up z as a by variable, which implies that any contrasts you do will be done separately for each level of z; thus, it necessarily excludes the comparison you wanted. To get it, you can either do

pairs(emm, by = NULL)

which disables that grouping, or don't have the grouping in the first place:

emmxz <- emmeans(mod, ~ x * z)
pairs(emmxz)
saotts commented 3 months ago

Thanks for your quick reply @rvlenth!

Actually, I wanted to contrast the contrasts between z1and z2, not the individual conditions. That's why I set up zas a by variable.

If I run:

emm <- emmeans(mod, ~ x | z)
p <- pairs(emm)
pairs(p, by=NULL)

it computes every possible combination of contrasts within group and between groups, whereas I was looking for a way to only compute the same contrasts between z1and z2:

(A - B z1) - (A - B z2)
(A - C z1) - (A - C z2)
(A - D z1) - (A - D z2)
(B - C z1) - (B - C z2)
(B - D z1) - (B - D z2)
(C - D z1) - (C - D z2)

Since the contrasts are the same in both z1and z2, I thought maybe emmeans would have such an option without having to compute all possible contrast combinations (it takes a really long time with my actual model). But I guess there is no shortcut and I will need to manually select which contrasts I want to test, is that right?

rvlenth commented 3 months ago

There was nothing in the original question that said you wanted a contrast of contrasts (aka interaction contrast). You can do:

emm <- emmeans(mod, ~ x | z)
con <- pairs(emm)
pairs(con, by = "contrast")

Or just

contrast(emm, interaction = "pairwise", by = NULL)

See this vignette section, and know that the package provides an index of vignettes.