Matrix dropping the column names inconsistently in R

I have a small function called foo. When I run it with m0, it correctly shows the column names. But when I use it with m1, foo omits all column names.

Is there a fix for that?

library(lme4)
library(Matrix)

sng <- read.csv('https://raw.githubusercontent.com/rnorouzian/e/master/sng.csv')
m0 <- lmer(y ~ A * B * C + (A * B * C  | group), data = sng)
m1 <- lmer(y ~ A * B * C + (A * B * C  || group), data = sng)

foo <- function(fit){
vc <- VarCorr(fit)
as.matrix(Matrix::bdiag(vc))
}
# EXAMPLES OF USE:
foo(m0)   # SHOWS COLUMNAMES FINE :-)
foo(m1)   # OMITS COLUMNNAMES ALL :-(

2 answers

  • answered 2020-09-30 22:28 Duck

    Try this approach. It looks like an issue with the output matrix and the length of the list in VarCorr(). Here the code:

    library(lme4)
    library(Matrix)
    #Data and models
    sng <- read.csv('https://raw.githubusercontent.com/rnorouzian/e/master/sng.csv')
    m0 <- lmer(y ~ A * B * C + (A * B * C  | group), data = sng)
    m1 <- lmer(y ~ A * B * C + (A * B * C  || group), data = sng)
    #Function
    foo <- function(fit){
      vc <- VarCorr(fit)
      if(length(vc)==1)
      {
        y <- as.matrix(Matrix::bdiag(vc))
      } else
      {
        z <- do.call(rbind,vc)
        y <- as.matrix(Matrix::bdiag(vc))
        dimnames(y)[[1]] <- rownames(z)
        dimnames(y)[[2]] <- rownames(z)
      }
      return(y)
    }
    #Apply
    foo(m0)
    foo(m1)
    

    Outputs:

    foo(m0)
                   (Intercept)             A             B              C            A:B
    (Intercept)  3.55516422891  0.2559261707 -0.0472493899  0.00321219209 -0.02924403667
    A            0.25592617067  4.0133838788  0.0772138992 -0.03546219301 -0.22207717925
    B           -0.04724938991  0.0772138992  6.4063596371 -1.16254872282 -0.42778740468
    C            0.00321219209 -0.0354621930 -1.1625487228  4.78167840574 -0.05459620260
    A:B         -0.02924403667 -0.2220771793 -0.4277874047 -0.05459620260  0.04574366496
    A:C         -0.03399653992 -0.2008053942  0.3219439970 -0.42927661072 -0.00100945652
    B:C         -0.02404787917  0.0212759619 -0.1454033407 -0.43345150872  0.02116923485
    A:B:C        0.00586240974  0.0206112404  0.0140531649  0.04266309961 -0.00336982403
                           A:C            B:C           A:B:C
    (Intercept) -0.03399653992 -0.02404787917  0.005862409744
    A           -0.20080539424  0.02127596189  0.020611240433
    B            0.32194399704 -0.14540334071  0.014053164881
    C           -0.42927661072 -0.43345150872  0.042663099613
    A:B         -0.00100945652  0.02116923485 -0.003369824029
    A:C          0.05859594675  0.02996839148 -0.004072087992
    B:C          0.02996839148  0.05038262309 -0.004808881907
    A:B:C       -0.00407208799 -0.00480888191  0.000590970743
    
    foo(m1)
                (Intercept)           A           B         C A:B            A:C          B:C A:B:C
    (Intercept)  3.29966179 0.000000000 0.000000000 0.0000000   0 0.00000000e+00 0.0000000000     0
    A            0.00000000 0.914972854 0.000000000 0.0000000   0 0.00000000e+00 0.0000000000     0
    B            0.00000000 0.000000000 0.467647434 0.0000000   0 0.00000000e+00 0.0000000000     0
    C            0.00000000 0.000000000 0.000000000 1.1369602   0 0.00000000e+00 0.0000000000     0
    A:B          0.00000000 0.000000000 0.000000000 0.0000000   0 0.00000000e+00 0.0000000000     0
    A:C          0.00000000 0.000000000 0.000000000 0.0000000   0 6.72771167e-08 0.0000000000     0
    B:C          0.00000000 0.000000000 0.000000000 0.0000000   0 0.00000000e+00 0.0013880372     0
    A:B:C        0.00000000 0.000000000 0.000000000 0.0000000   0 0.00000000e+00 0.0000000000     0
    

  • answered 2020-10-01 00:01 akrun

    After constructing the matrix, we check if the dimnames are NULL. In that case, get the dimnames attributes from the 'VarCorr' object and assign those as dimnames to the output matrix

    foo <- function(fit){
         vc <- VarCorr(fit)
         out <- as.matrix(Matrix::bdiag(vc))
         if(is.null(unlist(dimnames(out)))) {
           nm <- unlist(lapply(vc, function(x) attributes(x)$dimnames[1]))
          dimnames(out) <- list(nm, nm)
         }
         out
         }
         
    

    -testing

    foo(m0)
                  (Intercept)           A           B            C          A:B          A:C          B:C         A:B:C
    (Intercept)  3.7562550486  0.02806147 -0.07385379 -0.188350388  0.072254892 -0.045056715 -0.023888893  0.0003069446
    A            0.0280614731  3.99805818 -0.04527522 -0.091514845 -0.230125332 -0.198148495  0.032987776  0.0205313838
    B           -0.0738537902 -0.04527522  6.58615173 -1.351344388 -0.457616613  0.340081875 -0.154002255  0.0156069012
    C           -0.1883503881 -0.09151484 -1.35134439  4.748865101 -0.004621977 -0.396069722 -0.396633305  0.0362619475
    A:B          0.0722548916 -0.23012533 -0.45761661 -0.004621977  0.049207775 -0.005718505  0.017880341 -0.0031794465
    A:C         -0.0450567147 -0.19814850  0.34008188 -0.396069722 -0.005718505  0.053356862  0.023347554 -0.0032476293
    B:C         -0.0238888932  0.03298778 -0.15400225 -0.396633305  0.017880341  0.023347554  0.045604619 -0.0040810919
    A:B:C        0.0003069446  0.02053138  0.01560690  0.036261947 -0.003179446 -0.003247629 -0.004081092  0.0005059711
    foo(m1)
    
    (Intercept)         A         B        C          A:B         A:C         B:C A:B:C
    (Intercept)     2.26533 0.0000000 0.0000000 0.000000 0.000000e+00 0.00000e+00 0.000000000     0
    A               0.00000 0.8446554 0.0000000 0.000000 0.000000e+00 0.00000e+00 0.000000000     0
    B               0.00000 0.0000000 0.4905843 0.000000 0.000000e+00 0.00000e+00 0.000000000     0
    C               0.00000 0.0000000 0.0000000 1.169259 0.000000e+00 0.00000e+00 0.000000000     0
    A:B             0.00000 0.0000000 0.0000000 0.000000 4.816447e-08 0.00000e+00 0.000000000     0
    A:C             0.00000 0.0000000 0.0000000 0.000000 0.000000e+00 7.71255e-09 0.000000000     0
    B:C             0.00000 0.0000000 0.0000000 0.000000 0.000000e+00 0.00000e+00 0.001425746     0
    A:B:C           0.00000 0.0000000 0.0000000 0.000000 0.000000e+00 0.00000e+00 0.000000000     0