runehaubo / lmerTestR

Repository for the R-package lmerTest
48 stars 9 forks source link

multiparameter test #40

Closed mhimmelstein closed 3 years ago

mhimmelstein commented 3 years ago

I'm new to github, so forgive me if this is the wrong place to post this, if this is somehow already implemented and I just missed it, or if this is totally wrong and I've misunderstood something.

I'm teaching the lab section for an HLM course and I created a function to do a multi-parameter DF adjusted test for lmerTest::lmer() models as a wrapper for the contestMD() function by automatically creating the appropriate contrast matrix based on user-specified parameters.

It defaults to "all" which does an omnibus test of (a linear combination of) all fixed effects, but the user can specify any specific fixed parameters (including interactions) manually, and it will create the appropriate contrast matrix, then call contestMD().

I think it does what its supposed to (at least in the cases I've tested), and I figured it might be a useful addition to the package as a way of simplifying a common special case of contestMD() (again, unless something like this already implemented and I just missed it, which is very possible! Or I messed up and this isn't doing what I think it is, which is also possible!)

multipar_test <- function(mod, pars = "all", ddf = "Satterthwaite"){
  cfs <- attributes(terms(mod))$term.labels
  pars <- gsub(" ", "", pars)
  cfs <- gsub(":", "*", cfs)
  if (length(pars) == 1){
    if (pars == "all"){
      pars <- cfs
    }
  }
  if (all(pars %in% cfs)){
    contrast_mat <- matrix(0, nrow = length(pars), 
                           ncol = length(cfs) + 1)
    for (i in 1:length(pars)){
      contrast_mat[i, which(cfs %in% pars[i]) + 1] <- 1
    }
    outpt <- lmerTest::contestMD(mod, contrast_mat, ddf = ddf)
    return(outpt)
  }
  stop("Error: pars do not match model pars")
}
runehaubo commented 3 years ago

Posting suggestions here is quite alright.

However, your functions didn't work for me on an example from the package, but I think what you seek is given by contestMD(fm, L=diag(x = c(0, rep(1, length(fixef(fm)) - 1)))) as shown in the code below.

Best Rune

> library(lmerTest)
> multipar_test <- function(mod, pars = "all", ddf = "Satterthwaite"){
+   cfs <- attributes(terms(mod))$term.labels
+   pars <- gsub(" ", "", pars)
+   cfs <- gsub(":", "*", cfs)
+   if (length(pars) == 1){
+     if (pars == "all"){
+       pars <- cfs
+     }
+   }
+   if (all(pars %in% cfs)){
+     contrast_mat <- matrix(0, nrow = length(pars), 
+                            ncol = length(cfs) + 1)
+     for (i in 1:length(pars)){
+       contrast_mat[i, which(cfs %in% pars[i]) + 1] <- 1
+     }
+     outpt <- lmerTest::contestMD(mod, contrast_mat, ddf = ddf)
+     return(outpt)
+   }
+   stop("Error: pars do not match model pars")
+ }
> fm <- lmer(Informed.liking ~ Product*Information + (1|Consumer) , data=ham)
> anova(fm)
Type III Analysis of Variance Table with Satterthwaite's method
                    Sum Sq Mean Sq NumDF DenDF F value    Pr(>F)    
Product             91.807 30.6024     3   560  6.9901 0.0001271 ***
Information          6.520  6.5201     1   560  1.4893 0.2228402    
Product:Information 10.387  3.4624     3   560  0.7909 0.4992920    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
> contestMD(fm, L=diag(x = c(0, rep(1, length(fixef(fm)) - 1))))
    Sum Sq  Mean Sq NumDF DenDF  F value       Pr(>F)
1 108.7145 15.53064     7   560 3.547457 0.0009666935
> multipar_test(fm)
 Error in contestMD.lmerModLmerTest(mod, contrast_mat, ddf = ddf) : 
  ncol(L) == length(model@beta) is not TRUE