rvlenth/emmeans

Understanding the effect's direction through the "eff_size" function

JulianGaviriaL opened this issue · 7 comments

The data:
r_001.csv

# The Linear Model:
require(lmerTest)
require(emmeans)
m001 <- lm(Observations ~ Group ,data=r_001)
summary<-summary(m001)
summary

Call:
lm(formula = Observations ~ Group, data = r_001)
Residuals:
Min 1Q Median 3Q Max
-0.22600 -0.08271 -0.03100 0.06900 0.36400

Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.38600 0.01978 19.514 <2e-16 ***
Grouppre -0.06439 0.03097 -2.079 0.0411 *

#Compute the effect size
E_r001 <- emmeans(m001, "Group")
ES_r001<- eff_size(E_r001, sigma = sigma(m001), edf = Inf)
ES_r001

contrast effect.size SE df lower.CL upper.CL
ctr - pre 0.485 0.233 74 0.0202 0.95

sigma used for effect sizes: 0.1327
Confidence level used: 0.95

I need to understand the direction of the effect in terms of the difference between levels "ctr" and "pre" of the factor "Group". Why do I obtain a positive effect size (i.e., effect size=0.485) if the difference between the intercept (Groupctr=0.38600) and the slope Grouppre is negative (-0.06439)?

Considering how the data is modeled in lmer ("ctr" is the first level, and "pre" the 2nd level of the "Group" factor), I would expect a negative effect size. Therefore, I would interpret the results as follows: The mean difference between "ctr" and "pre" indicates a larger effect in "ctr". However, I am doubtful due to the positive effect size.

Many thanks in advance for your comments.

As you state, the reference level is ctr and the other level is pre, meaning that the regression coefficient for the intercept is the prediction for ctr, and that for Grouppre is the change from ctr, i.e., pre - ctr; and it is negative. However, in the eff_size output, the row label is ctr - pre (not pre - ctr), which therefore must be positive. So your effect size does have the correct sign.

If you want the difference to go the other way, use

eff_size(E_r001, sigma = sigma(m001), edf = Inf, method = "revpairwise")

Thank you very much Prof. @rvlenth

Just one last thing, if possible. How can I list the same effect size from multiple emmGrid objects (>100)? For instance:

ES_r001<- eff_size(E_r001, sigma = sigma(m001), edf = Inf)
ES_r002<- eff_size(E_r002, sigma = sigma(m002), edf = Inf)
....
ES_r200<- eff_size(E_r200, sigma = sigma(m200), edf = Inf)

Ideally, the list would include all effect sizes. Something like:

**#Ideal output** 
    ES          contrast       effect.size      SE      df    lower.CL    upper. CL
ES_r001       ctr - pre         0.299         0.302     70     -0.304       0.901
ES_r002       ctr - pre         -0.03         0.224     70     -0.304       0.044
....
ES_r200       ctr - pre         0.299         0.802     70     -0.284       0.901

The following code with the foreach package did not work

require(foreach)

output_position <- grep("ES",ls())
all_effects <- foreach(i=output_position,.combine="rbind") %do% {
  output <- get(ls()[i])
  unlist(output["ctr-pre",])
}
rownames(all_effects) <- ls()[output_position]
all_effects
b<-as.data.frame(all_effects)

Many thanks in advance

You can combine them into a data frame. Starting with your output_position vector

summList <- lapply(output_position, \(x) data.frame(get(x)))
all_ES <- cbind(ES = output_position, do.call(rbind, summList))

(I didn't need the foreach package)

You can do a similar thing to combine them into an emmGrid object by omitting the data.frame() call; however, that requires all of the results to have been obtained from the same model, which I doubt is the case.

thanks @rvlenth
What is "x" in summList?

#the models:
m001 <- lm(Observations ~ Group ,data=r_001)
m002 <- lm(Observations ~ Group ,data=r_002)
m200 <- lm(Observations ~ Group ,data=r_200)
#Compute the effect size
E_r001 <- emmeans(m001, "Group")
E_r002 <- emmeans(m002, "Group")
E_r200 <- emmeans(m200, "Group")
ES_r001<- eff_size(E_r001, sigma = sigma(m001), edf = Inf)
ES_r002<- eff_size(E_r002, sigma = sigma(m002), edf = Inf)
ES_r200<- eff_size(E_r200, sigma = sigma(m200), edf = Inf)
#list the effect size of the contrast ctr - pre from all the emmGrid objects (i.e., ES_rxxx)
output_position <- grep("ES",ls())
summList <- lapply(output_position, \(x) data.frame(get(x)))

Error in get(x) : invalid first argument

I misread your code. Instead of using grep, use ls

ESs <- ls(pat = "ES")   # names instead of numbers
summList <- lapply(ES, \(x) data.frame(get(x)))
all_ES <- cbind(ES = ESs, do.call(rbind, summList))

Dear Professor @rvlenth,

Your suggestion works very well. Thank you very much and I wish you happy holidays.

Thanks, and happy holidays to you as well.