lavaan.printer

Shu Fai Cheung

Introduction

This article illustrates how to use the two main functions of lavaan.printer:

These are the packages used in this article:

library(lavaan)
#> This is lavaan 0.6-18
#> lavaan is FREE software! Please report any bugs.
library(lavaan.printer)

For What Scenarios?

These two functions are not for end-users. They are for package developers, and are intended to be used internally by print-methods or similar functions for the objects in other packages which generate customized parameter tables.

Scenarios

Create a List of Data frames

In the simplest case, parameterEstimates_table_list() can be used to generate the usual parameter estimates results of lavaan, but as a list of data frames, each corresponding to a section in the output (e.g., regression coefficients, factor loadings). Arguments for to lavaan::parameterEstimates() can be used when calling parameterEstimates_table_list():

# Adapted from the example of cfa()
model_cfa <- "visual  =~ x1 + x2 + x3
              textual =~ x4 + x5 + x6"
fit <- cfa(model_cfa,
           data = HolzingerSwineford1939,
           group = "school")
est <- parameterEstimates_table_list(fit,
                                     rsquare = TRUE)

Because it is intended to be used inside a print function, it does not have a print method itself. Call print_parameterEstimates_table_list() instead:

print_parameterEstimates_table_list(est)
#> 
#> Parameter Estimates Settings:
#>                                              
#>  Standard errors:                  Standard  
#>  Information:                      Expected  
#>  Information saturated (h1) model: Structured
#> 
#> Group 1 [Pasteur]:
#> Latent Variables:
#>             Estimate  S.E.      Z P(>|z|)  CI.Lo CI.Up
#>  visual =~                                            
#>   x1           1.000                                  
#>   x2           0.373 0.121  3.081   0.002  0.136 0.610
#>   x3           0.541 0.141  3.843   0.000  0.265 0.817
#>  textual =~                                           
#>   x4           1.000                                  
#>   x5           1.187 0.102 11.640   0.000  0.987 1.387
#>   x6           0.870 0.076 11.372   0.000  0.720 1.020
#> 
#> Group 1 [Pasteur]:
#> Covariances:
#>             Estimate  S.E.      Z P(>|z|)  CI.Lo CI.Up
#>  visual ~~                                            
#>   textual      0.485 0.106  4.568   0.000  0.277 0.693
#> 
#> Group 1 [Pasteur]:
#> Intercepts:
#>             Estimate  S.E.      Z P(>|z|)  CI.Lo CI.Up
#>  .x1           4.941 0.095 52.249   0.000  4.756 5.127
#>  .x2           5.984 0.098 60.949   0.000  5.792 6.176
#>  .x3           2.487 0.093 26.778   0.000  2.305 2.669
#>  .x4           2.823 0.092 30.689   0.000  2.642 3.003
#>  .x5           3.995 0.105 38.183   0.000  3.790 4.200
#>  .x6           1.922 0.079 24.321   0.000  1.767 2.077
#>   visual       0.000                                  
#>   textual      0.000                                  
#> 
#> Group 1 [Pasteur]:
#> Variances:
#>             Estimate  S.E.      Z P(>|z|)  CI.Lo CI.Up
#>  .x1           0.244 0.258  0.947   0.344 -0.262 0.750
#>  .x2           1.344 0.158  8.498   0.000  1.034 1.653
#>  .x3           1.009 0.138  7.317   0.000  0.739 1.279
#>  .x4           0.424 0.069  6.105   0.000  0.288 0.560
#>  .x5           0.445 0.086  5.161   0.000  0.276 0.614
#>  .x6           0.297 0.051  5.864   0.000  0.197 0.396
#>   visual       1.151 0.300  3.835   0.000  0.563 1.739
#>   textual      0.896 0.150  5.967   0.000  0.602 1.190
#> 
#> Group 1 [Pasteur]:
#> R-Squares:
#>             Estimate  S.E.      Z P(>|z|)  CI.Lo CI.Up
#>   x1           0.825                                  
#>   x2           0.107                                  
#>   x3           0.250                                  
#>   x4           0.679                                  
#>   x5           0.740                                  
#>   x6           0.696                                  
#> 
#> Group 2 [Grant-White]:
#> Latent Variables:
#>             Estimate  S.E.      Z P(>|z|)  CI.Lo CI.Up
#>  visual =~                                            
#>   x1           1.000                                  
#>   x2           0.813 0.175  4.657   0.000  0.471 1.155
#>   x3           1.045 0.204  5.110   0.000  0.644 1.446
#>  textual =~                                           
#>   x4           1.000                                  
#>   x5           0.981 0.086 11.351   0.000  0.812 1.151
#>   x6           0.963 0.084 11.402   0.000  0.797 1.128
#> 
#> Group 2 [Grant-White]:
#> Covariances:
#>             Estimate  S.E.      Z P(>|z|)  CI.Lo CI.Up
#>  visual ~~                                            
#>   textual      0.377 0.096  3.941   0.000  0.189 0.564
#> 
#> Group 2 [Grant-White]:
#> Intercepts:
#>             Estimate  S.E.      Z P(>|z|)  CI.Lo CI.Up
#>  .x1           4.930 0.095 51.696   0.000  4.743 5.117
#>  .x2           6.200 0.092 67.416   0.000  6.020 6.380
#>  .x3           1.996 0.086 23.195   0.000  1.827 2.164
#>  .x4           3.317 0.093 35.625   0.000  3.135 3.500
#>  .x5           4.712 0.096 48.986   0.000  4.524 4.901
#>  .x6           2.469 0.094 26.277   0.000  2.285 2.653
#>   visual       0.000                                  
#>   textual      0.000                                  
#> 
#> Group 2 [Grant-White]:
#> Variances:
#>             Estimate  S.E.      Z P(>|z|)  CI.Lo CI.Up
#>  .x1           0.792 0.132  6.017   0.000  0.534 1.050
#>  .x2           0.878 0.124  7.104   0.000  0.636 1.120
#>  .x3           0.498 0.114  4.386   0.000  0.276 0.721
#>  .x4           0.310 0.065  4.776   0.000  0.183 0.437
#>  .x5           0.429 0.073  5.900   0.000  0.287 0.572
#>  .x6           0.402 0.069  5.818   0.000  0.267 0.537
#>   visual       0.527 0.155  3.399   0.001  0.223 0.830
#>   textual      0.947 0.153  6.196   0.000  0.648 1.247
#> 
#> Group 2 [Grant-White]:
#> R-Squares:
#>             Estimate  S.E.      Z P(>|z|)  CI.Lo CI.Up
#>   x1           0.399                                  
#>   x2           0.284                                  
#>   x3           0.536                                  
#>   x4           0.753                                  
#>   x5           0.680                                  
#>   x6           0.686

The output looks similar to the lavaan output, except for some minor changes in column names (e.g., CI.Lo and CI.Up instead of ci.lower and ci.upper) to shorten the width of the print, to make room for additional columns developer may want to add. This is intentional: mimicking the lavaan style to minimize the need for the users to learn anything new in reading the output.

These options are available in print_parameterEstimates_table_list():

This is an example of these arguments:

print_parameterEstimates_table_list(est,
                                    nd = 2,
                                    by_group = FALSE,
                                    drop_cols = "Z",
                                    na_str = "--")
#> 
#> Parameter Estimates Settings:
#>                                              
#>  Standard errors:                  Standard  
#>  Information:                      Expected  
#>  Information saturated (h1) model: Structured
#> 
#> Latent Variables:
#> Group 1 [Pasteur]:
#>             Estimate S.E. P(>|z|) CI.Lo CI.Up
#>  visual =~                                   
#>   x1            1.00   --      --    --    --
#>   x2            0.37 0.12    0.00  0.14  0.61
#>   x3            0.54 0.14    0.00  0.27  0.82
#>  textual =~                                  
#>   x4            1.00   --      --    --    --
#>   x5            1.19 0.10    0.00  0.99  1.39
#>   x6            0.87 0.08    0.00  0.72  1.02
#> 
#> Latent Variables:
#> Group 2 [Grant-White]:
#>             Estimate S.E. P(>|z|) CI.Lo CI.Up
#>  visual =~                                   
#>   x1            1.00   --      --    --    --
#>   x2            0.81 0.17    0.00  0.47  1.16
#>   x3            1.04 0.20    0.00  0.64  1.45
#>  textual =~                                  
#>   x4            1.00   --      --    --    --
#>   x5            0.98 0.09    0.00  0.81  1.15
#>   x6            0.96 0.08    0.00  0.80  1.13
#> 
#> Covariances:
#> Group 1 [Pasteur]:
#>             Estimate S.E. P(>|z|) CI.Lo CI.Up
#>  visual ~~                                   
#>   textual       0.49 0.11    0.00  0.28  0.69
#> 
#> Covariances:
#> Group 2 [Grant-White]:
#>             Estimate S.E. P(>|z|) CI.Lo CI.Up
#>  visual ~~                                   
#>   textual       0.38 0.10    0.00  0.19  0.56
#> 
#> Intercepts:
#> Group 1 [Pasteur]:
#>             Estimate S.E. P(>|z|) CI.Lo CI.Up
#>  .x1            4.94 0.09    0.00  4.76  5.13
#>  .x2            5.98 0.10    0.00  5.79  6.18
#>  .x3            2.49 0.09    0.00  2.31  2.67
#>  .x4            2.82 0.09    0.00  2.64  3.00
#>  .x5            4.00 0.10    0.00  3.79  4.20
#>  .x6            1.92 0.08    0.00  1.77  2.08
#>   visual        0.00   --      --    --    --
#>   textual       0.00   --      --    --    --
#> 
#> Intercepts:
#> Group 2 [Grant-White]:
#>             Estimate S.E. P(>|z|) CI.Lo CI.Up
#>  .x1            4.93 0.10    0.00  4.74  5.12
#>  .x2            6.20 0.09    0.00  6.02  6.38
#>  .x3            2.00 0.09    0.00  1.83  2.16
#>  .x4            3.32 0.09    0.00  3.13  3.50
#>  .x5            4.71 0.10    0.00  4.52  4.90
#>  .x6            2.47 0.09    0.00  2.28  2.65
#>   visual        0.00   --      --    --    --
#>   textual       0.00   --      --    --    --
#> 
#> Variances:
#> Group 1 [Pasteur]:
#>             Estimate S.E. P(>|z|) CI.Lo CI.Up
#>  .x1            0.24 0.26    0.34 -0.26  0.75
#>  .x2            1.34 0.16    0.00  1.03  1.65
#>  .x3            1.01 0.14    0.00  0.74  1.28
#>  .x4            0.42 0.07    0.00  0.29  0.56
#>  .x5            0.44 0.09    0.00  0.28  0.61
#>  .x6            0.30 0.05    0.00  0.20  0.40
#>   visual        1.15 0.30    0.00  0.56  1.74
#>   textual       0.90 0.15    0.00  0.60  1.19
#> 
#> Variances:
#> Group 2 [Grant-White]:
#>             Estimate S.E. P(>|z|) CI.Lo CI.Up
#>  .x1            0.79 0.13    0.00  0.53  1.05
#>  .x2            0.88 0.12    0.00  0.64  1.12
#>  .x3            0.50 0.11    0.00  0.28  0.72
#>  .x4            0.31 0.06    0.00  0.18  0.44
#>  .x5            0.43 0.07    0.00  0.29  0.57
#>  .x6            0.40 0.07    0.00  0.27  0.54
#>   visual        0.53 0.15    0.00  0.22  0.83
#>   textual       0.95 0.15    0.00  0.65  1.25
#> 
#> R-Squares:
#> Group 1 [Pasteur]:
#>             Estimate S.E. P(>|z|) CI.Lo CI.Up
#>  x1             0.82   --      --    --    --
#>  x2             0.11   --      --    --    --
#>  x3             0.25   --      --    --    --
#>  x4             0.68   --      --    --    --
#>  x5             0.74   --      --    --    --
#>  x6             0.70   --      --    --    --
#> 
#> R-Squares:
#> Group 2 [Grant-White]:
#>             Estimate S.E. P(>|z|) CI.Lo CI.Up
#>  x1             0.40   --      --    --    --
#>  x2             0.28   --      --    --    --
#>  x3             0.54   --      --    --    --
#>  x4             0.75   --      --    --    --
#>  x5             0.68   --      --    --    --
#>  x6             0.69   --      --    --    --

Insert a Column Computed From Another Column

Suppose we would like to insert a column of symbols (e.g., "*" and "**") into the parameter estimates table based on the pvalue column, to denote whether a parameter is significant,

This is the function:

add_sig <- function(object,
                    breaks = c(1, .05, .01, .001, -Inf),
                    labels = c("***", "** ", "*  ", "  ")) {
    tmp <- object[, "pvalue", drop = TRUE]
    if (!is.null(tmp)) {
        tmp[is.na(tmp)] <- 1
        tmp2 <- cut(tmp,
                    breaks = breaks,
                    labels = labels)
        i <- match("pvalue", colnames(object))
        out <- data.frame(object[, 1:i],
                          Sig = tmp2,
                          object[, seq(i + 1, ncol(object))])
      }
    out
  }

This can be done by the argument est_funs:

model_cfa <- "visual  =~ x1 + x2 + x3
              textual =~ x4 + x5 + x6"
fit <- cfa(model_cfa,
           data = HolzingerSwineford1939[1:100, ])
#> Warning: lavaan->lav_object_post_check():  
#>    some estimated ov variances are negative
est <- parameterEstimates_table_list(fit,
                                     est_funs = list(add_sig))
print_parameterEstimates_table_list(est)
#> 
#> Parameter Estimates Settings:
#>                                              
#>  Standard errors:                  Standard  
#>  Information:                      Expected  
#>  Information saturated (h1) model: Structured
#> 
#> Latent Variables:
#>             Estimate  S.E.      Z P(>|z|) Sig  CI.Lo CI.Up
#>  visual =~                                                
#>   x1           1.000                                      
#>   x2           0.163 0.118  1.379   0.168     -0.068 0.394
#>   x3           0.355 0.192  1.849   0.065     -0.021 0.732
#>  textual =~                                               
#>   x4           1.000                                      
#>   x5           1.202 0.129  9.322   0.000 ***  0.950 1.455
#>   x6           0.707 0.081  8.694   0.000 ***  0.548 0.867
#> 
#> Covariances:
#>             Estimate  S.E.      Z P(>|z|) Sig  CI.Lo CI.Up
#>  visual ~~                                                
#>   textual      0.430 0.123  3.485   0.000 ***  0.188 0.672
#> 
#> Variances:
#>             Estimate  S.E.      Z P(>|z|) Sig  CI.Lo CI.Up
#>  .x1          -0.257 0.793 -0.324   0.746     -1.810 1.297
#>  .x2           1.341 0.190  7.055   0.000 ***  0.969 1.714
#>  .x3           1.022 0.175  5.828   0.000 ***  0.678 1.366
#>  .x4           0.331 0.076  4.372   0.000 ***  0.183 0.479
#>  .x5           0.405 0.103  3.929   0.000 ***  0.203 0.607
#>  .x6           0.241 0.046  5.291   0.000 ***  0.152 0.331
#>   visual       1.622 0.814  1.992   0.046 *    0.026 3.219
#>   textual      0.812 0.166  4.899   0.000 ***  0.487 1.137

Note that est_funs must be a list, even if only one function is supplied.

Further Information

There are other ways to customize the output when calling parameterEstimates_table_list(). For example:

Please refer to the help page of parameterEstimates_table_list() for details.

Issues

If you have any suggestions and found any bugs, please feel feel to open a GitHub issue. Thanks.