afex icon indicating copy to clipboard operation
afex copied to clipboard

emmeans for mixed models is very slow

Open mattansb opened this issue 5 years ago • 2 comments

Not sure why this is happening... See example below (6 min vc 500ms)

library(afex)
library(emmeans)

data(obk.long, package = "afex")

fit_lmm <- mixed(value ~ treatment * gender * phase * hour + (phase * hour || id),
                 data = obk.long,
                 method = "S", # p-value method
                 expand_re = TRUE)
#> Contrasts set to contr.sum for the following variables: treatment, gender, phase, hour, id
#> Fitting one lmer() model.
#> boundary (singular) fit: see ?isSingular
#> [DONE]
#> Calculating p-values. [DONE]

emm_options(lmer.df = "satterthwaite")

t1 <- Sys.time()
joint_tests(fit_lmm, by = "gender")
#> gender = F:
#>  model term           df1   df2 F.ratio p.value
#>  treatment              2 10.00   1.329 0.3077 
#>  phase                  2 14.04   4.875 0.0247 
#>  hour                   4 13.47   8.830 0.0010 
#>  treatment:phase        4 14.04   2.333 0.1063 
#>  treatment:hour         8 13.47   0.395 0.9046 
#>  phase:hour             8 11.19   1.264 0.3495 
#>  treatment:phase:hour  16 11.19   0.516 0.8892 
#> 
#> gender = M:
#>  model term           df1   df2 F.ratio p.value
#>  treatment              2 10.00   6.158 0.0181 
#>  phase                  2 14.04   9.048 0.0030 
#>  hour                   4 13.47   4.835 0.0124 
#>  treatment:phase        4 14.04   2.959 0.0576 
#>  treatment:hour         8 13.47   0.378 0.9143 
#>  phase:hour             8 11.19   0.778 0.6309 
#>  treatment:phase:hour  16 11.19   0.371 0.9651 
Sys.time() - t1
#> Time difference of 6.453859 mins

t2 <- Sys.time()
joint_tests(fit_lmm$full_model, by = "gender")
#> gender = F:
#>  model term           df1   df2 F.ratio p.value
#>  treatment              2 10.00   1.329 0.3077 
#>  phase                  2 14.04   4.875 0.0247 
#>  hour                   4 13.47   8.830 0.0010 
#>  treatment:phase        4 14.04   2.333 0.1063 
#>  treatment:hour         8 13.47   0.395 0.9046 
#>  phase:hour             8 11.19   1.264 0.3495 
#>  treatment:phase:hour  16 11.19   0.516 0.8892 
#> 
#> gender = M:
#>  model term           df1   df2 F.ratio p.value
#>  treatment              2 10.00   6.158 0.0181 
#>  phase                  2 14.04   9.048 0.0030 
#>  hour                   4 13.47   4.835 0.0124 
#>  treatment:phase        4 14.04   2.959 0.0576 
#>  treatment:hour         8 13.47   0.378 0.9143 
#>  phase:hour             8 11.19   0.778 0.6309 
#>  treatment:phase:hour  16 11.19   0.371 0.9651 

Sys.time() - t2
#> Time difference of 0.5516829 secs

mattansb avatar Jun 21 '20 07:06 mattansb

That is very surprising. Thanks for the report. Also, sorry for the delay at the moment.

singmann avatar Jul 15 '20 10:07 singmann

No worries (:

mattansb avatar Jul 16 '20 12:07 mattansb

It took me only around 4 years, but I hope this is fixed now. I just needed to deactivate a check in the emmeans() method that I believe was needed back in the days when first implementing it but seems unnecessary now.

If you have the time to check if it works and makes stuff much faster, please let me know. I will close this issue now, feel free to reopen if necessary.

suppressPackageStartupMessages(library(afex))
library(emmeans)

data(obk.long, package = "afex")

fit_lmm <- mixed(value ~ treatment * gender * phase * hour + (phase + hour || id),
                 data = obk.long,
                 method = "S", # p-value method
                 expand_re = TRUE)
#> Contrasts set to contr.sum for the following variables: treatment, gender, phase, hour, id
#> boundary (singular) fit: see help('isSingular')

emm_options(lmer.df = "satterthwaite")

t1 <- Sys.time()
joint_tests(fit_lmm, by = "gender")
#> gender = F:
#>  model term           df1    df2 F.ratio p.value
#>  treatment              2  10.00   1.329  0.3077
#>  phase                  2  12.49   7.693  0.0066
#>  hour                   4  16.25   7.522  0.0013
#>  treatment:phase        4  12.49   4.382  0.0194
#>  treatment:hour         8  16.25   0.331  0.9415
#>  phase:hour             8 105.73   1.044  0.4080
#>  treatment:phase:hour  16 105.73   0.517  0.9335
#> 
#> gender = M:
#>  model term           df1    df2 F.ratio p.value
#>  treatment              2  10.00   6.158  0.0181
#>  phase                  2  12.49  13.696  0.0007
#>  hour                   4  16.25   4.149  0.0168
#>  treatment:phase        4  12.49   1.763  0.1986
#>  treatment:hour         8  16.25   0.318  0.9478
#>  phase:hour             8 105.73   1.209  0.3009
#>  treatment:phase:hour  16 105.73   0.613  0.8669
Sys.time() - t1
#> Time difference of 0.5449231 secs

t2 <- Sys.time()
joint_tests(fit_lmm$full_model, by = "gender")
#> gender = F:
#>  model term           df1    df2 F.ratio p.value
#>  treatment              2  10.00   1.329  0.3077
#>  phase                  2  12.49   7.693  0.0066
#>  hour                   4  16.25   7.522  0.0013
#>  treatment:phase        4  12.49   4.382  0.0194
#>  treatment:hour         8  16.25   0.331  0.9415
#>  phase:hour             8 105.73   1.044  0.4080
#>  treatment:phase:hour  16 105.73   0.517  0.9335
#> 
#> gender = M:
#>  model term           df1    df2 F.ratio p.value
#>  treatment              2  10.00   6.158  0.0181
#>  phase                  2  12.49  13.696  0.0007
#>  hour                   4  16.25   4.149  0.0168
#>  treatment:phase        4  12.49   1.763  0.1986
#>  treatment:hour         8  16.25   0.318  0.9478
#>  phase:hour             8 105.73   1.209  0.3009
#>  treatment:phase:hour  16 105.73   0.613  0.8669
Sys.time() - t2
#> Time difference of 0.4634171 secs

Created on 2024-04-07 with reprex v2.1.0

singmann avatar Apr 07 '24 18:04 singmann