lavaanExtra

lavaanExtra: Convenience Functions for Package lavaan - Published in JOSS (2023)

https://github.com/rempsyc/lavaanextra

Science Score: 100.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
    Found CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
    Found 4 DOI reference(s) in README and JOSS metadata
  • Academic publication links
    Links to: joss.theoj.org
  • Committers with academic emails
    1 of 5 committers (20.0%) from academic institutions
  • Institutional organization owner
  • JOSS paper metadata
    Published in Journal of Open Source Software

Keywords

convenience-functions lavaan psychology r rstats statistics structural-equation-modeling
Last synced: 6 months ago · JSON representation ·

Repository

Convenience Functions for Package `lavaan`

Basic Info
Statistics
  • Stars: 20
  • Watchers: 3
  • Forks: 3
  • Open Issues: 6
  • Releases: 9
Topics
convenience-functions lavaan psychology r rstats statistics structural-equation-modeling
Created over 3 years ago · Last pushed 6 months ago
Metadata Files
Readme Changelog Contributing Funding License Citation

README.Rmd

---
output: github_document
---



```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.path = "man/figures/README-",
  out.width = "100%"
)
```

# lavaanExtra: Convenience functions for `lavaan`

```{r version, echo = FALSE, message = FALSE, warning = FALSE}
flextable::set_flextable_defaults(background.color = "white")

library(lavaan)
library(lavaanExtra)
```


[![R-CMD-check](https://github.com/rempsyc/lavaanExtra/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/rempsyc/lavaanExtra/actions/workflows/R-CMD-check.yaml)
[![CRAN status](https://www.r-pkg.org/badges/version/lavaanExtra)](https://cran.r-project.org/package=lavaanExtra)
[![r-universe](https://rempsyc.r-universe.dev/badges/lavaanExtra)](https://rempsyc.r-universe.dev/lavaanExtra)
[![Last-commit](https://img.shields.io/github/last-commit/rempsyc/lavaanExtra)](https://github.com/rempsyc/lavaanExtra/commits/main)
[![Codecov test coverage](https://codecov.io/gh/rempsyc/lavaanExtra/branch/main/graph/badge.svg)](https://app.codecov.io/gh/rempsyc/lavaanExtra?branch=main)
[![lifecycle](https://img.shields.io/badge/lifecycle-maturing-blue.svg)](https://lifecycle.r-lib.org/articles/stages.html)
[![downloads](https://cranlogs.r-pkg.org/badges/lavaanExtra)](https://shinyus.ipub.com/cranview/)
[![total](https://cranlogs.r-pkg.org/badges/grand-total/lavaanExtra)](https://shinyus.ipub.com/cranview/)
[![DOI](https://joss.theoj.org/papers/10.21105/joss.05701/status.svg)](https://doi.org/10.21105/joss.05701)
[![sponsors](https://img.shields.io/github/sponsors/rempsyc)](https://github.com/sponsors/rempsyc)
[![followers](https://img.shields.io/github/followers/rempsyc?style=social)](https://github.com/rempsyc?tab=followers)
[![stars](https://img.shields.io/github/stars/rempsyc/lavaanExtra?style=social)](https://github.com/rempsyc/lavaanExtra/stargazers)


Affords an alternative, vector-based syntax to `lavaan`, as well as other convenience functions such as naming paths and defining indirect links automatically. Also offers convenience formatting optimized for a publication and script sharing workflow.

## Installation

You can install the `lavaanExtra` package directly from CRAN:
``` r
install.packages("lavaanExtra")
```

Or the development version from the r-universe (note that there is a 24-hour delay with GitHub):
``` r
install.packages("lavaanExtra", repos = c(
  rempsyc = "https://rempsyc.r-universe.dev",
  CRAN = "https://cloud.r-project.org"))
```

Or from GitHub, for the very latest version:
``` r
# If not already installed, install package `remotes` with `install.packages("remotes")`
remotes::install_github("rempsyc/lavaanExtra")
```

To see all the available functions, use:
``` r
help(package = "lavaanExtra")
```

**Dependencies:** Because `lavaanExtra` is a package of convenience functions relying on several external packages, it uses (inspired by the [`easystats`](https://easystats.github.io/easystats/) packages) a minimalist philosophy of only installing packages that you need when you need them through `rlang::check_installed()`. Should you wish to specifically install all suggested dependencies at once (you can view the full list by clicking on the CRAN badge on this page), you can run the following (be warned that this may take a long time, as some of the suggested packages are only used in the vignettes or examples):
``` r
install.packages("lavaanExtra", dependencies = TRUE)
```

## Why use `lavaanExtra`?

1. **Reusable code**. Don't repeat yourself anymore when you only want to change a few things when comparing and fitting models.
2. **Shorter code**. Because of point 1, you can have shorter code, since you write it once and simply reuse it. For items with similar patterns, you can also use `paste0()` with appropriate item numbers instead of typing each one every time.
3. **Less error-prone code**. Because of point 1, you can have less risk of human errors since you don't have possibly multiple different version of the same thing (which makes it easier to correct too).
4. **Better control over your code**. Because of point 1, you are in control of the whole flow. You change it once, and it will change it everywhere else in the script, without having to change it manually for each model.
5. **More readable code**. Because of point 1, other people (but also yourself) only have to process the information the first time to make sure it's been specified correctly, and not every time you check the new models.
6. **Prettier code**. Because it will format the model for you in a pretty way, every time. You don't have to worry about manually making your model good-looking and readable anymore.
7. **More accessible code**. You don't have to remember the exact syntax (although it is recommended) for it to work. It uses intuitive variable names that most people can understand. This benefit is most apparent for beginners, but it also saves precious typing time for veterans.

## Overview

```{r headers, results = "asis", echo = FALSE}
section.1 <- "CFA example"
section.2 <- "SEM example"
section.3 <- "Final note"

cute_cat <- function(x, header.level = 1) {
  cat(rep("#", header.level), " ", x, sep = "")
}

cute_TOC <- function(section) {
  cat("[", section, "]",
    "(#", tolower(gsub(" ", "-", gsub(",", "", section))), ")",
    "",
    "\n \n",
    sep = ""
  )
}

invisible(lapply(
  list(
    section.1, section.2, section.3
  ),
  cute_TOC
))
```

## CFA example

```{r cfaplot}
# Load libraries
library(lavaan)
library(lavaanExtra)

# Define latent variables
latent <- list(
  visual = c("x1", "x2", "x3"),
  textual = c("x4", "x5", "x6"),
  speed = c("x7", "x8", "x9")
)

# If you have many items, you can also use the `paste0` function:
x <- paste0("x", 1:9)
latent <- list(
  visual = x[1:3],
  textual = x[4:6],
  speed = x[7:9]
)

# Write the model, and check it
cfa.model <- write_lavaan(latent = latent)
cat(cfa.model)

# Fit the model fit and plot with `lavaanExtra::cfa_fit_plot`
# to get the factor loadings visually (optionally as PDF)
fit.cfa <- cfa_fit_plot(cfa.model, HolzingerSwineford1939)
```



```{r cfa2, results='hide'}
# Get nice fit indices with the `rempsyc::nice_table` integration
nice_fit(fit.cfa, nice_table = TRUE)
```

```{r cfa2.save, include=FALSE}
table_temp <- nice_fit(fit.cfa, nice_table = TRUE) |>
  flextable::autofit()
flextable::save_as_image(table_temp,
  path = "man/figures/README-cfa2-1.png",
  expand = 0, res = 300
)
```



## SEM example

Note that latent variables have been defined above, so we can reuse them as is, without having to redefine them. 

```{r saturated}
# Define our other variables
M <- "visual"
IV <- c("ageyr", "grade")
DV <- c("speed", "textual")

# Define our lavaan lists
mediation <- list(speed = M, textual = M, visual = IV)
regression <- list(speed = IV, textual = IV)
covariance <- list(speed = "textual", ageyr = "grade")

# Define indirect effects object
indirect <- list(IV = IV, M = M, DV = DV)

# Write the model, and check it
model <- write_lavaan(
  mediation = mediation,
  regression = regression,
  covariance = covariance,
  indirect = indirect,
  latent = latent,
  label = TRUE
)
cat(model)

fit.sem <- sem(model, data = HolzingerSwineford1939)
```

```{r saturated2, results='hide'}
# Get regression parameters and make pretty with `rempsyc::nice_table`
lavaan_reg(fit.sem, nice_table = TRUE, highlight = TRUE)
```

```{r saturated2.save, include=FALSE}
table_temp <- lavaan_reg(fit.sem, nice_table = TRUE, highlight = TRUE) |>
  flextable::autofit()
flextable::save_as_image(table_temp,
  path = "man/figures/README-saturated-1.png",
  expand = 0, res = 300
)
```



```{r correlation, results='hide'}
# Get covariances/correlations and make them pretty with
# the `rempsyc::nice_table` integration
lavaan_cor(fit.sem, nice_table = TRUE)
```

```{r covariance.save, include=FALSE}
table_temp <- lavaan_cor(fit.sem, nice_table = TRUE) |>
  flextable::autofit()
flextable::save_as_image(table_temp,
  path = "man/figures/README-covariance-1.png",
  expand = 0, res = 300
)
```



```{r path2, results='hide'}
# Get nice fit indices with the `rempsyc::nice_table` integration
fit_table <- nice_fit(list(fit.cfa, fit.sem), nice_table = TRUE)
fit_table
```

```{r path2.save, include=FALSE}
table_temp <- nice_fit(list(fit.cfa, fit.sem), nice_table = TRUE) |>
  flextable::autofit()
flextable::save_as_image(table_temp,
  path = "man/figures/README-path2-1.png",
  expand = 0, res = 300
)
```



```{r indirect2, results='hide'}
# Save fit table to Word!
flextable::save_as_docx(fit_table, path = "fit_table.docx")
# Note that it will also render to PDF in an `rmarkdown` document
# with `output: pdf_document`, but using `latex_engine: xelatex`
# is necessary when including Unicode symbols in tables like with
# the `nice_fit()` function.

# Let's get the user-defined (e.g., indirect) effects only and make it pretty
# with the `rempsyc::nice_table` integration
lavaan_defined(fit.sem, nice_table = TRUE)
```

```{r indirect2.save, include=FALSE}
table_temp <- lavaan_defined(fit.sem, nice_table = TRUE) |>
  flextable::autofit()
flextable::save_as_image(table_temp,
  path = "man/figures/README-indirect2-1.png",
  expand = 0, res = 300
)
```



```{r, echo=FALSE}
unlink("fit_table.docx")
```

```{r plot, eval = FALSE}
# Plot our model
nice_lavaanPlot(fit.sem)
```



```{r plot2}
# Alternative way to plot
mylayout <- data.frame(
  IV = c("", "x1", "grade", "", "ageyr", "", ""),
  M = c("", "x2", "", "visual", "", "", ""),
  DV = c("", "x3", "textual", "", "speed", "", ""),
  DV.items = c(paste0("x", 4:6), "", paste0("x", 7:9))
) |>
  as.matrix()
mylayout
```

```{r plot3, eval = FALSE}
nice_tidySEM(fit.sem, layout = mylayout, label_location = 0.7)

ggplot2::ggsave("my_semPlot.pdf", width = 6, height = 6, limitsize = FALSE)
```



## Final note
This is an experimental package in a *very* early stage. Any feedback or feature request is appreciated, and the package will likely change and evolve over time based on community feedback. Feel free to open an issue or discussion to share your questions or concerns. And of course, please have a look at the other tutorials to discover even more cool features: https://lavaanExtra.remi-theriault.com/articles/

## Support me and this package

Thank you for your support. You can support me and this package here: https://github.com/sponsors/rempsyc

Owner

  • Name: Rémi Thériault
  • Login: rempsyc
  • Kind: user
  • Location: New York, NY
  • Company: New York University

Postdoc @ Center for Conflict and Cooperation NYU New York University

JOSS Publication

lavaanExtra: Convenience Functions for Package lavaan
Published
October 11, 2023
Volume 8, Issue 90, Page 5701
Authors
Rémi Thériault ORCID
Department of Psychology, Université du Québec à Montréal, Québec, Canada
Editor
Arfon Smith ORCID
Tags
psychology statistics visualization structural equation modeling

Citation (CITATION.cff)

cff-version: "1.2.0"
authors:
- family-names: Thériault
  given-names: Rémi
  orcid: "https://orcid.org/0000-0003-4315-6788"
doi: 10.5281/zenodo.8421873
message: If you use this software, please cite our article in the
  Journal of Open Source Software.
preferred-citation:
  authors:
  - family-names: Thériault
    given-names: Rémi
    orcid: "https://orcid.org/0000-0003-4315-6788"
  date-published: 2023-10-11
  doi: 10.21105/joss.05701
  issn: 2475-9066
  issue: 90
  journal: Journal of Open Source Software
  publisher:
    name: Open Journals
  start: 5701
  title: "lavaanExtra: Convenience Functions for Package lavaan"
  type: article
  url: "https://joss.theoj.org/papers/10.21105/joss.05701"
  volume: 8
title: "lavaanExtra: Convenience Functions for Package *lavaan*"

GitHub Events

Total
  • Issues event: 3
  • Watch event: 2
  • Delete event: 2
  • Issue comment event: 7
  • Push event: 20
  • Pull request event: 5
  • Create event: 5
Last Year
  • Issues event: 3
  • Watch event: 2
  • Delete event: 2
  • Issue comment event: 7
  • Push event: 20
  • Pull request event: 5
  • Create event: 5

Committers

Last synced: 7 months ago

All Time
  • Total Commits: 382
  • Total Committers: 5
  • Avg Commits per committer: 76.4
  • Development Distribution Score (DDS): 0.021
Past Year
  • Commits: 0
  • Committers: 0
  • Avg Commits per committer: 0.0
  • Development Distribution Score (DDS): 0.0
Top Committers
Name Email Commits
rempsyc r****t@m****a 374
James Uanhoro 4****o 4
Buedenbender 3****r 2
RemPsyc R****c 1
Ethan Bass e****s@g****m 1
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 6 months ago

All Time
  • Total issues: 29
  • Total pull requests: 12
  • Average time to close issues: 18 days
  • Average time to close pull requests: about 5 hours
  • Total issue authors: 8
  • Total pull request authors: 5
  • Average comments per issue: 2.48
  • Average comments per pull request: 3.25
  • Merged pull requests: 9
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 2
  • Pull requests: 4
  • Average time to close issues: 6 months
  • Average time to close pull requests: about 4 hours
  • Issue authors: 2
  • Pull request authors: 1
  • Average comments per issue: 0.5
  • Average comments per pull request: 1.5
  • Merged pull requests: 2
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • TDJorgensen (17)
  • rempsyc (3)
  • Buedenbender (3)
  • barracuda156 (1)
  • mzyphur (1)
  • CharlyMarie (1)
  • AlexGareau (1)
  • jamesuanhoro (1)
Pull Request Authors
  • Copilot (4)
  • jamesuanhoro (4)
  • Buedenbender (2)
  • ethanbass (2)
  • maelle (1)
Top Labels
Issue Labels
bug (3) enhancement (2) help wanted (1) documentation (1)
Pull Request Labels
bug (2) enhancement (2) documentation (1)

Dependencies

DESCRIPTION cran
  • R >= 3.5 depends
  • lavaan * imports
  • DiagrammeRsvg * suggests
  • flextable * suggests
  • knitr * suggests
  • lavaanPlot * suggests
  • markdown * suggests
  • png * suggests
  • rempsyc * suggests
  • rlang * suggests
  • rmarkdown * suggests
  • rsvg * suggests
  • testthat >= 3.0.0 suggests
  • webshot * suggests
.github/workflows/R-CMD-check.yaml actions
  • actions/checkout v2 composite
  • r-lib/actions/check-r-package v2 composite
  • r-lib/actions/setup-pandoc v2 composite
  • r-lib/actions/setup-r v2 composite
  • r-lib/actions/setup-r-dependencies v2 composite
.github/workflows/pkgdown.yaml actions
  • JamesIves/github-pages-deploy-action 4.1.4 composite
  • actions/checkout v2 composite
  • r-lib/actions/setup-pandoc v2 composite
  • r-lib/actions/setup-r v2 composite
  • r-lib/actions/setup-r-dependencies v2 composite
.github/workflows/test-coverage.yaml actions
  • actions/checkout v2 composite
  • r-lib/actions/setup-r v2 composite
  • r-lib/actions/setup-r-dependencies v2 composite
.github/workflows/check-no-suggests.yaml actions
  • actions/checkout v3 composite
  • r-lib/actions/check-r-package v2 composite
  • r-lib/actions/setup-pandoc v2 composite
  • r-lib/actions/setup-r v2 composite
  • r-lib/actions/setup-r-dependencies v2 composite
.github/workflows/lint.yaml actions
  • actions/checkout v3 composite
  • r-lib/actions/setup-r v2 composite
  • r-lib/actions/setup-r-dependencies v2 composite
.github/workflows/pkgdown-no-suggests.yaml actions
  • actions/checkout v3 composite
  • r-lib/actions/setup-pandoc v2 composite
  • r-lib/actions/setup-r v2 composite
  • r-lib/actions/setup-r-dependencies v2 composite
.github/workflows/revdep.yaml actions
  • actions/cache v2 composite
  • actions/checkout v2 composite
  • actions/upload-artifact v2 composite
  • r-lib/actions/setup-pandoc v2 composite
  • r-lib/actions/setup-r v2 composite