├── .Rbuildignore ├── .github ├── .gitignore └── workflows │ ├── R-CMD-check.yaml │ └── pkgdown.yaml ├── .gitignore ├── DESCRIPTION ├── JSS ├── jss.bst ├── jss.cls ├── jsslogo.jpg ├── lavaanPlot_JSS.Rmd ├── lavaanPlot_JSS.pdf └── lavaanPlot_JSS.tex ├── NAMESPACE ├── NEWS.md ├── R ├── lavaanPlot.R ├── lavaanPlot2.R └── plotExportFunctions.R ├── README.Rmd ├── README.md ├── README_files └── figure-gfm │ ├── pressure-1.png │ └── unnamed-chunk-3-1.png ├── _pkgdown.yml ├── docs ├── 404.html ├── articles │ ├── Intro_to_lavaanPlot.html │ ├── Intro_to_lavaanPlot_files │ │ ├── DiagrammeR-styles-0.2 │ │ │ └── styles.css │ │ ├── grViz-binding-1.0.9 │ │ │ └── grViz.js │ │ ├── htmlwidgets-1.5.4 │ │ │ └── htmlwidgets.js │ │ └── viz-1.8.2 │ │ │ └── viz.js │ ├── Save_and_embed.html │ ├── index.html │ └── plot.png ├── authors.html ├── deps │ ├── bootstrap-5.1.0 │ │ ├── bootstrap.bundle.min.js │ │ ├── bootstrap.bundle.min.js.map │ │ └── bootstrap.min.css │ ├── data-deps.txt │ └── jquery-3.6.0 │ │ ├── jquery-3.6.0.js │ │ ├── jquery-3.6.0.min.js │ │ └── jquery-3.6.0.min.map ├── index.html ├── link.svg ├── news │ └── index.html ├── pkgdown.js ├── pkgdown.yml ├── reference │ ├── Rplot001.png │ ├── buildCall.html │ ├── buildLabels.html │ ├── buildPaths.html │ ├── embed_plot_pdf.html │ ├── getNodes.html │ ├── index.html │ ├── lavaanPlot.html │ ├── libs │ │ ├── DiagrammeR-styles-0.2 │ │ │ └── styles.css │ │ ├── grViz-binding-1.0.9 │ │ │ └── grViz.js │ │ ├── htmlwidgets-1.5.4 │ │ │ └── htmlwidgets.js │ │ └── viz-1.8.2 │ │ │ └── viz.js │ ├── save_png.html │ └── sig_stars.html ├── search.json └── sitemap.xml ├── lavaanPlot.Rproj ├── man ├── buildCall.Rd ├── buildLabels.Rd ├── buildPaths.Rd ├── convert_graph.Rd ├── create_edges.Rd ├── create_grviz.Rd ├── create_nodes.Rd ├── embed_plot_pdf.Rd ├── extract_coefs.Rd ├── formatting.Rd ├── getNodes.Rd ├── lavaanPlot.Rd ├── lavaanPlot2.Rd ├── save_png.Rd └── sig_stars.Rd ├── tests ├── testthat.R └── testthat │ └── test-plots.R └── vignettes ├── Conditional-Formatting.R ├── Conditional-Formatting.html ├── Conditional_Formatting.R ├── Conditional_Formatting.Rmd ├── Conditional_Formatting.html ├── Improvements_to_lavaanPlot.R ├── Improvements_to_lavaanPlot.Rmd ├── Improvements_to_lavaanPlot.html ├── Intro_to_lavaanPlot.R ├── Intro_to_lavaanPlot.Rmd ├── Intro_to_lavaanPlot.html ├── Save_and_embed.R ├── Save_and_embed.Rmd ├── Save_and_embed.html ├── plot.png └── unnamed-chunk-3-1.png /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^doc$ 4 | ^Meta$ 5 | ^JSS$ 6 | ^README_files$ 7 | ^README\.md$ 8 | ^README\.Rmd$ 9 | ^\.github$ 10 | ^.github$ 11 | ^README.*$ 12 | ^_pkgdown\.yml$ 13 | ^docs$ 14 | ^pkgdown$ 15 | ^articles$ 16 | ^docs/articles$ 17 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/workflows/pkgdown.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | release: 9 | types: [published] 10 | workflow_dispatch: 11 | 12 | name: pkgdown 13 | 14 | jobs: 15 | pkgdown: 16 | runs-on: ubuntu-latest 17 | # Only restrict concurrency for non-PR jobs 18 | concurrency: 19 | group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} 20 | env: 21 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 22 | permissions: 23 | contents: write 24 | steps: 25 | - uses: actions/checkout@v3 26 | 27 | - uses: r-lib/actions/setup-pandoc@v2 28 | 29 | - uses: r-lib/actions/setup-r@v2 30 | with: 31 | use-public-rspm: true 32 | 33 | - uses: r-lib/actions/setup-r-dependencies@v2 34 | with: 35 | extra-packages: any::pkgdown, local::. 36 | needs: website 37 | 38 | - name: Build site 39 | run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) 40 | shell: Rscript {0} 41 | 42 | - name: Deploy to GitHub pages 🚀 43 | if: github.event_name != 'pull_request' 44 | uses: JamesIves/github-pages-deploy-action@v4.4.1 45 | with: 46 | clean: false 47 | branch: gh-pages 48 | folder: docs 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | inst/doc 6 | .Rproj 7 | doc 8 | Meta 9 | #docs 10 | docs 11 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: lavaanPlot 2 | Type: Package 3 | Title: Path Diagrams for 'Lavaan' Models via 'DiagrammeR' 4 | Version: 0.8.1 5 | Author: Alex Lishinski 6 | Maintainer: Alex Lishinski 7 | URL: https://github.com/alishinski/lavaanPlot, https://lavaanplot.alexlishinski.com/, http://alexlishinski.com/lavaanPlot/ 8 | Description: Plots path diagrams from models in 'lavaan' using the plotting 9 | functionality from the 'DiagrammeR' package. 'DiagrammeR' provides nice path diagrams 10 | via 'Graphviz', and these functions make it easy to generate these diagrams from a 11 | 'lavaan' path model without having to write the DOT language graph specification. 12 | License: GPL (>= 2) 13 | Encoding: UTF-8 14 | LazyData: true 15 | Imports: 16 | lavaan, 17 | DiagrammeR, 18 | stringr, 19 | magrittr, 20 | dplyr, 21 | purrr, 22 | rlang 23 | RoxygenNote: 7.2.3 24 | Suggests: 25 | knitr, 26 | rmarkdown, 27 | DiagrammeRsvg, 28 | rsvg, 29 | png, 30 | testthat (>= 3.0.0) 31 | VignetteBuilder: knitr 32 | Config/testthat/edition: 3 33 | -------------------------------------------------------------------------------- /JSS/jsslogo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alishinski/lavaanPlot/9ed0816d678e145450ca1dd534ca9a4140961dfe/JSS/jsslogo.jpg -------------------------------------------------------------------------------- /JSS/lavaanPlot_JSS.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | documentclass: jss 3 | author: 4 | - name: Alex Lishinski 5 | affiliation: University of Tennessee 6 | # use this syntax to add text on several lines 7 | address: | 8 | | First line 9 | | Second line 10 | email: \email{name@company.com} 11 | url: http://rstudio.com 12 | title: 13 | formatted: "\\pkg{lavaanPlot}: An R package for plotting structural equation models" 14 | # If you use tex in the formatted title, also supply version without 15 | plain: "lavaanPlot: An R package for plotting structural equation models" 16 | # For running headers, if needed 17 | short: "\\pkg{lavaanPlot}: SEM plotting" 18 | abstract: > 19 | The lavaan package is an excellent package for structural equation models, and the DiagrammeR package is an excellent package for producing nice looking graph diagrams. As of right now, the lavaan package has no built in plotting functions for models, and the available options from external packages don’t look as nice and aren’t as easy to use as DiagrammeR, in my opinion. Of course, you can use DiagrammeR to build path diagrams for your models, but it requires you to build the diagram specification manually. This package exists to streamline that process, allowing you to plot your lavaan models directly, without having to translate them into the DOT language specification that DiagrammeR uses. 20 | keywords: 21 | # at least one keyword must be supplied 22 | formatted: [keywords, not capitalized, "\\proglang{Java}"] 23 | plain: [keywords, not capitalized, Java] 24 | preamble: > 25 | \usepackage{amsmath} 26 | output: rticles::jss_article 27 | --- 28 | 29 | ```{r, setup, include=FALSE} 30 | options(prompt = 'R> ', continue = '+ ') 31 | ``` 32 | 33 | # Introduction 34 | 35 | This template demonstrates some of the basic LaTeX that you need to know to create a JSS article. 36 | 37 | ## Code formatting 38 | 39 | In general, don't use Markdown, but use the more precise LaTeX commands instead: 40 | 41 | * \proglang{Java} 42 | * \pkg{plyr} 43 | 44 | One exception is inline code, which can be written inside a pair of backticks (i.e., using the Markdown syntax). 45 | 46 | If you want to use LaTeX commands in headers, you need to provide a `short-title` attribute. You can also provide a custom identifier if necessary. See the header of Section \ref{r-code} for example. 47 | 48 | # \proglang{R} code {short-title="R code" #r-code} 49 | 50 | Can be inserted in regular R markdown blocks. 51 | 52 | ```{r} 53 | x <- 1:10 54 | x 55 | ``` 56 | 57 | ## Features specific to \pkg{rticles} {short-title="Features specific to rticles"} 58 | 59 | * Adding short titles to section headers is a feature specific to \pkg{rticles} (implemented via a Pandoc Lua filter). This feature is currently not supported by Pandoc and we will update this template if [it is officially supported in the future](https://github.com/jgm/pandoc/issues/4409). 60 | * Using the `\AND` syntax in the `author` field to add authors on a new line. This is a specific to the `rticles::jss_article` format. 61 | -------------------------------------------------------------------------------- /JSS/lavaanPlot_JSS.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alishinski/lavaanPlot/9ed0816d678e145450ca1dd534ca9a4140961dfe/JSS/lavaanPlot_JSS.pdf -------------------------------------------------------------------------------- /JSS/lavaanPlot_JSS.tex: -------------------------------------------------------------------------------- 1 | \documentclass[ 2 | ]{jss} 3 | 4 | \usepackage[utf8]{inputenc} 5 | 6 | \providecommand{\tightlist}{% 7 | \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} 8 | 9 | \author{ 10 | Alex Lishinski\\University of Tennessee 11 | } 12 | \title{\pkg{lavaanPlot}: An R package for plotting structural equation models} 13 | 14 | \Plainauthor{Alex Lishinski} 15 | \Plaintitle{lavaanPlot: An R package for plotting structural equation models} 16 | \Shorttitle{\pkg{lavaanPlot}: SEM plotting} 17 | 18 | \Abstract{ 19 | The lavaan package is an excellent package for structural equation 20 | models, and the DiagrammeR package is an excellent package for producing 21 | nice looking graph diagrams. As of right now, the lavaan package has no 22 | built in plotting functions for models, and the available options from 23 | external packages don't look as nice and aren't as easy to use as 24 | DiagrammeR, in my opinion. Of course, you can use DiagrammeR to build 25 | path diagrams for your models, but it requires you to build the diagram 26 | specification manually. This package exists to streamline that process, 27 | allowing you to plot your lavaan models directly, without having to 28 | translate them into the DOT language specification that DiagrammeR uses. 29 | } 30 | 31 | \Keywords{keywords, not capitalized, \proglang{Java}} 32 | \Plainkeywords{keywords, not capitalized, Java} 33 | 34 | %% publication information 35 | %% \Volume{50} 36 | %% \Issue{9} 37 | %% \Month{June} 38 | %% \Year{2012} 39 | %% \Submitdate{} 40 | %% \Acceptdate{2012-06-04} 41 | 42 | \Address{ 43 | Alex Lishinski\\ 44 | University of Tennessee\\ 45 | First line\\ 46 | Second line\\ 47 | E-mail: \email{name@company.com}\\ 48 | URL: \url{http://rstudio.com}\\~\\ 49 | } 50 | 51 | % Pandoc citation processing 52 | 53 | % Pandoc header 54 | 55 | \usepackage{amsmath} 56 | 57 | \begin{document} 58 | 59 | \hypertarget{introduction}{% 60 | \section{Introduction}\label{introduction}} 61 | 62 | This template demonstrates some of the basic LaTeX that you need to know 63 | to create a JSS article. 64 | 65 | \hypertarget{code-formatting}{% 66 | \subsection{Code formatting}\label{code-formatting}} 67 | 68 | In general, don't use Markdown, but use the more precise LaTeX commands 69 | instead: 70 | 71 | \begin{itemize} 72 | \item 73 | \proglang{Java} 74 | \item 75 | \pkg{plyr} 76 | \end{itemize} 77 | 78 | One exception is inline code, which can be written inside a pair of 79 | backticks (i.e., using the Markdown syntax). 80 | 81 | If you want to use LaTeX commands in headers, you need to provide a 82 | \texttt{short-title} attribute. You can also provide a custom identifier 83 | if necessary. See the header of Section \ref{r-code} for example. 84 | 85 | \section[R code]{\proglang{R} code}\label{r-code} 86 | 87 | Can be inserted in regular R markdown blocks. 88 | 89 | \begin{CodeChunk} 90 | \begin{CodeInput} 91 | R> x <- 1:10 92 | R> x 93 | \end{CodeInput} 94 | \begin{CodeOutput} 95 | [1] 1 2 3 4 5 6 7 8 9 10 96 | \end{CodeOutput} 97 | \end{CodeChunk} 98 | 99 | \subsection[Features specific to rticles]{Features specific to 100 | \pkg{rticles}}\label{features-specific-to} 101 | 102 | \begin{itemize} 103 | \tightlist 104 | \item 105 | Adding short titles to section headers is a feature specific to 106 | \pkg{rticles} (implemented via a Pandoc Lua filter). This feature is 107 | currently not supported by Pandoc and we will update this template if 108 | \href{https://github.com/jgm/pandoc/issues/4409}{it is officially 109 | supported in the future}. 110 | \item 111 | Using the \texttt{\textbackslash{}AND} syntax in the \texttt{author} 112 | field to add authors on a new line. This is a specific to the 113 | \texttt{rticles::jss\_article} format. 114 | \end{itemize} 115 | 116 | 117 | 118 | \end{document} 119 | 120 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(convert_graph) 4 | export(create_edges) 5 | export(create_grviz) 6 | export(create_nodes) 7 | export(embed_plot_pdf) 8 | export(extract_coefs) 9 | export(formatting) 10 | export(lavaanPlot) 11 | export(lavaanPlot2) 12 | export(save_png) 13 | importFrom(DiagrammeR,grViz) 14 | importFrom(dplyr,.data) 15 | importFrom(dplyr,bind_cols) 16 | importFrom(dplyr,bind_rows) 17 | importFrom(dplyr,filter) 18 | importFrom(dplyr,recode) 19 | importFrom(magrittr,"%>%") 20 | importFrom(purrr,map) 21 | importFrom(purrr,map2) 22 | importFrom(purrr,map_dfc) 23 | importFrom(purrr,map_int) 24 | importFrom(purrr,map_lgl) 25 | importFrom(purrr,pmap_lgl) 26 | importFrom(rlang,exec) 27 | importFrom(stringr,str_replace_all) 28 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # lavaanPlot 0.3.0 2 | 3 | * Added support for latent variables (denoted by circles) in plots 4 | 5 | * Added support for edge labels with significant coefficients 6 | 7 | # lavaanPlot 0.4.0 8 | 9 | * Added support for latent variable loading labels 10 | 11 | * Added support for covariance edges 12 | 13 | * Corrected the direction of arrows for latent variable loadings 14 | 15 | # lavaanPlot 0.5.0 16 | 17 | * Added support for covariance edge labels 18 | 19 | * Added support for significance stars 20 | 21 | # lavaanPlot 0.5.1 22 | 23 | * Fixed bug caused by . in variable names 24 | 25 | * simplified the functions using the ... argument 26 | 27 | * fixed significance stars to work with standardized and non-standardized coefficients 28 | 29 | * Changed significance stars so you can choose which parameters to use them with 30 | 31 | # lavaanPlot 0.5.2 32 | 33 | * Added digits option for coefficients 34 | 35 | * Changed coefs argument behavior so that it toggles coef values for covariances too 36 | 37 | * Plots now show residual covariances 38 | 39 | # lavaanPlot 0.6.0 40 | 41 | * added functions to save plots as images and embed plots in pdfs with Rmarkdown 42 | 43 | # lavaanPlot 0.6.2 44 | 45 | * Fixed issues with suggested packages that were causing trouble for CRAN submission 46 | 47 | # lavaanPlot 0.6.3 48 | 49 | * Added support for specifying dimensions of saved png files 50 | 51 | * Updated vignette for layout graph options 52 | 53 | * Added package tests 54 | 55 | # lavaanPlot 0.7.0 56 | 57 | * Introducing `lavaanPlot2` function, which replicates the old functionality in a more flexible platform 58 | 59 | # lavaanPlot 0.8.0 60 | 61 | * Introducing conditional formatting which allows one to apply different formatting to different sets of nodes and edges 62 | 63 | # lavaanPlot 0.8.1 64 | 65 | * Fixed bug with the standardized coefficents in `lavaanPlot2` 66 | -------------------------------------------------------------------------------- /R/lavaanPlot.R: -------------------------------------------------------------------------------- 1 | #' Extracts the paths from the lavaan model. 2 | #' 3 | #' @param fit A model fit object of class lavaan. 4 | #' @param coefs whether or not to include significant path coefficient values in diagram 5 | #' @param sig significance level for determining what significant paths are 6 | #' @param stand Should the coefficients being used be standardized coefficients 7 | #' @param covs Should model covariances be included in the diagram 8 | #' @param stars a character vector indicating which parameters should include significance stars be included for regression paths, latent paths, or covariances. Include which of the 3 you want ("regress", "latent", "covs"), default is none. 9 | #' @param digits A number indicating the desired number of digits for the coefficient values in the plot 10 | #' @importFrom stringr str_replace_all 11 | buildPaths <- function(fit, coefs = FALSE, sig = 1.00, stand = FALSE, covs = FALSE, stars = NULL, digits = 2){ 12 | if(stand){ 13 | ParTable <- lavaan::standardizedsolution(fit) 14 | ParTableAlt <- fit@ParTable 15 | } else { 16 | ParTable <- fit@ParTable 17 | ParTableAlt <- fit@ParTable 18 | } 19 | 20 | # get rid of . from variable names 21 | ParTable$lhs <- stringr::str_replace_all(fit@ParTable$lhs, pattern = "\\.", replacement = "") 22 | ParTable$rhs <- stringr::str_replace_all(fit@ParTable$rhs, pattern = "\\.", replacement = "") 23 | 24 | regress <- ParTable$op == "~" 25 | latent <- ParTable$op == "=~" 26 | #cov <- ParTable$op == "~~" & (ParTable$rhs %in% ParTable$lhs[latent | regress]) & (ParTable$rhs != ParTable$lhs) 27 | cov <- ParTable$op == "~~" & (ParTable$rhs != ParTable$lhs) 28 | 29 | 30 | zval_reg <- ParTableAlt$est[regress] / ParTableAlt$se[regress] 31 | pval_reg <- (1 - stats::pnorm(abs(zval_reg))) * 2 32 | signif_reg <- pval_reg < sig 33 | coef <- ifelse(signif_reg, round(ParTable$est[regress], digits = digits), "") 34 | 35 | zval_lat <- ParTableAlt$est[latent] / ParTableAlt$se[latent] 36 | pval_lat <- (1 - stats::pnorm(abs(zval_lat))) * 2 37 | signif_lat <- pval_lat < sig 38 | latent_coef <- ifelse(signif_lat, round(ParTable$est[latent], digits = digits), "") 39 | 40 | zval_cov <- ParTableAlt$est[cov] / ParTableAlt$se[cov] 41 | pval_cov <- (1 - stats::pnorm(abs(zval_cov))) * 2 42 | signif_cov <- pval_cov < sig 43 | cov_vals <- ifelse(signif_cov, round(ParTable$est[cov], digits = digits), "") 44 | 45 | if("regress" %in% stars){ 46 | #pval_reg <- ParTable$pvalue[regress] 47 | stars_reg <- unlist(lapply(X = pval_reg, FUN = sig_stars)) 48 | } else { 49 | stars_reg <- "" 50 | } 51 | 52 | if("latent" %in% stars){ 53 | #pval_lat <- ParTable$pvalue[latent] 54 | stars_lat <- unlist(lapply(X = pval_lat, FUN = sig_stars)) 55 | } else { 56 | stars_lat <- "" 57 | } 58 | 59 | if("covs" %in% stars){ 60 | #pval_cov <- ParTable$pvalue[cov] 61 | stars_cov <- unlist(lapply(X = pval_cov, FUN = sig_stars)) 62 | } else { 63 | stars_cov <- "" 64 | } 65 | 66 | #penwidths <- ifelse(coefs == "", 1, 2) 67 | if(any(regress)){ 68 | if(coefs){ 69 | regress_paths <- paste(paste(ParTable$rhs[regress], ParTable$lhs[regress], sep = "->"), paste("[label = '", coef, stars_reg, "']", sep = ""), collapse = " ") 70 | } else { 71 | regress_paths <- paste(paste(ParTable$rhs[regress], ParTable$lhs[regress], sep = "->"), collapse = " ") 72 | } 73 | } else { 74 | regress_paths <- "" 75 | } 76 | if(any(latent)) { 77 | if(coefs){ 78 | latent_paths <- paste(paste(ParTable$lhs[latent], ParTable$rhs[latent], sep = "->"), paste("[label = '", latent_coef, stars_lat, "']", sep = ""), collapse = " ") 79 | } else { 80 | latent_paths <- paste(paste(ParTable$lhs[latent], ParTable$rhs[latent], sep = "->"), collapse = " ") 81 | } 82 | } else { 83 | latent_paths <- "" 84 | } 85 | if(any(cov)){ 86 | if(covs){ 87 | 88 | covVals <- round(ParTable$est[cov], digits = 2) 89 | if(coefs) { 90 | cov_paths <- paste( 91 | paste( 92 | ParTable$rhs[cov], 93 | ParTable$lhs[cov], sep = " -> "), 94 | paste("[label = '", cov_vals, stars_cov, "', dir = 'both']", sep = ""), 95 | collapse = " " 96 | ) 97 | } else { 98 | cov_paths <- paste( 99 | paste( 100 | ParTable$rhs[cov], 101 | ParTable$lhs[cov], sep = " -> "), 102 | paste("[dir = 'both']", sep = ""), 103 | collapse = " " 104 | ) 105 | } 106 | 107 | 108 | } else { 109 | cov_paths <- "" 110 | } 111 | } else { 112 | cov_paths <- "" 113 | } 114 | paste(regress_paths, latent_paths, cov_paths, sep = " ") 115 | } 116 | 117 | #' Extracts the paths from the lavaan model. 118 | #' 119 | #' @param fit A model fit object of class lavaan. 120 | getNodes <- function(fit){ 121 | # remove . from variable names 122 | regress <- fit@ParTable$op == "~" 123 | latent <- fit@ParTable$op == "=~" 124 | observed_nodes <- c() 125 | latent_nodes <- c() 126 | if(any(regress)){ 127 | observed_nodes <- c(observed_nodes, unique(fit@ParTable$rhs[regress])) 128 | observed_nodes <- c(observed_nodes, unique(fit@ParTable$lhs[regress])) 129 | } 130 | if(any(latent)) { 131 | observed_nodes <- c(observed_nodes, unique(fit@ParTable$rhs[latent])) 132 | latent_nodes <- c(latent_nodes, unique(fit@ParTable$lhs[latent])) 133 | } 134 | # make sure latent variables don't show up in both 135 | observed_nodes <- setdiff(observed_nodes, latent_nodes) 136 | 137 | # remove . from variable names 138 | observed_nodes <- stringr::str_replace_all(observed_nodes, pattern = "\\.", replacement = "") 139 | latent_nodes <- stringr::str_replace_all(latent_nodes, pattern = "\\.", replacement = "") 140 | 141 | list(observeds = observed_nodes, latents = latent_nodes) 142 | } 143 | 144 | #' Generates standard significance stars 145 | #' 146 | #' @param pvals a vector of p values 147 | sig_stars <- function(pvals){ 148 | if(pvals <= 0.001){ 149 | star = "***" 150 | } else if (pvals <= 0.01){ 151 | star = "**" 152 | } else if (pvals <= 0.05){ 153 | star = "*" 154 | } else { 155 | star = "" 156 | } 157 | star 158 | } 159 | 160 | #' Adds variable labels to the Diagrammer plot function call. 161 | #' 162 | #' @param label_list A named list of variable labels. 163 | buildLabels <- function(label_list){ 164 | names(label_list) <- stringr::str_replace_all(names(label_list), pattern = "\\.", replacement = "") 165 | labs <- paste(names(label_list), " [label = ", "'", label_list, "'", "]", sep = "") 166 | paste(labs, collapse = "\n") 167 | } 168 | 169 | #' Builds the Diagrammer function call. 170 | #' 171 | #' @param model A model fit object of class lavaan. 172 | #' @param name A string of the name of the plot. 173 | #' @param labels An optional named list of variable labels fit object of class lavaan. 174 | #' @param graph_options A named list of graph options for Diagrammer syntax. 175 | #' @param node_options A named list of node options for Diagrammer syntax. 176 | #' @param edge_options A named list of edge options for Diagrammer syntax. 177 | #' @param ... additional arguments to be passed to \code{buildPaths} 178 | #' @return A string specifying the path diagram for \code{model} 179 | buildCall <- function(model = model, name = name, labels = labels, graph_options = list(overlap = "true", fontsize = "10"), node_options = list(shape = "box"), edge_options = list(color = "black"), ...){ 180 | string <- "" 181 | string <- paste(string, "digraph", name, "{") 182 | string <- paste(string, "\n") 183 | string <- paste(string, "graph", "[", paste(paste(names(graph_options), graph_options, sep = " = "), collapse = ", "), "]") 184 | string <- paste(string, "\n") 185 | string <- paste(string, "node", "[", paste(paste(names(node_options), node_options, sep = " = "), collapse = ", "), "]") 186 | string <- paste(string, "\n") 187 | nodes <- getNodes(model) 188 | string <- paste(string, "node [shape = box] \n") 189 | string <- paste(string, paste(nodes$observeds, collapse = "; ")) 190 | string <- paste(string, "\n") 191 | string <- paste(string, "node [shape = oval] \n") 192 | string <- paste(string, paste(nodes$latents, collapse = "; ")) 193 | string <- paste(string, "\n") 194 | if(!is.null(labels)){ 195 | labels_string = buildLabels(labels) 196 | string <- paste(string, labels_string) 197 | } 198 | string <- paste(string, "\n") 199 | string <- paste(string, "edge", "[", paste(paste(names(edge_options), edge_options, sep = " = "), collapse = ", "), "]") 200 | string <- paste(string, "\n") 201 | string <- paste(string, buildPaths(model, ...)) 202 | string <- paste(string, "}", sep = "\n") 203 | string 204 | } 205 | 206 | #' Plots lavaan path model with DiagrammeR 207 | #' 208 | #' @param model A model fit object of class lavaan. 209 | #' @param name A string of the name of the plot. 210 | #' @param labels An optional named list of variable labels. 211 | #' @param ... Additional arguments to be called to \code{buildCall} and \code{buildPaths} 212 | #' @return A Diagrammer plot of the path diagram for \code{model} 213 | #' @importFrom DiagrammeR grViz 214 | #' @export 215 | #' @examples 216 | #' library(lavaan) 217 | #' model <- 'mpg ~ cyl + disp + hp 218 | #' qsec ~ disp + hp + wt' 219 | #' fit <- sem(model, data = mtcars) 220 | #' lavaanPlot(model = fit, node_options = list(shape = "box", fontname = "Helvetica"), 221 | #' edge_options = list(color = "grey"), coefs = FALSE) 222 | lavaanPlot <- function(model, name = "plot", labels = NULL, ...){ 223 | plotCall <- buildCall(model = model, name = name, labels = labels, ...) 224 | grViz(plotCall) 225 | } 226 | 227 | -------------------------------------------------------------------------------- /R/plotExportFunctions.R: -------------------------------------------------------------------------------- 1 | #' Saves a plot as a png 2 | #' 3 | #' @param plot plot object created by \code{lavaanPlot} 4 | #' @param path filename to save the image 5 | #' @param width width of image in pixels, NULL for default 6 | #' @param height height of image, NULL for default 7 | #' @return no return value saves plot as png 8 | #' @export 9 | #' @importFrom magrittr "%>%" 10 | #' @examples 11 | #' library(lavaan) 12 | #' model <- 'mpg ~ cyl + disp + hp 13 | #' qsec ~ disp + hp + wt' 14 | #' fit <- sem(model, data = mtcars) 15 | #' pl <- lavaanPlot(model = fit) 16 | #' \dontrun{ 17 | #' save_png(pl, "plot.png") 18 | #' } 19 | save_png <- function(plot, path, width = NULL, height = NULL){ 20 | if (!requireNamespace("DiagrammeRsvg", quietly = TRUE)) { 21 | stop("Package \"DiagrammeRsvg\" needed for this function to work. Please install it.", 22 | call. = FALSE) 23 | } else if (!requireNamespace("rsvg", quietly = TRUE)) { 24 | stop("Package \"rsvg\" needed for this function to work. Please install it.", 25 | call. = FALSE) 26 | } else if (!requireNamespace("png", quietly = TRUE)) { 27 | stop("Package \"png\" needed for this function to work. Please install it.", 28 | call. = FALSE) 29 | } else { 30 | DiagrammeRsvg::export_svg(plot) %>% 31 | charToRaw() %>% 32 | rsvg::rsvg(width = width, height = height) %>% 33 | png::writePNG(path) 34 | } 35 | } 36 | 37 | #' Embeds a plot into an rmarkdown pdf 38 | #' 39 | #' @param plot plot object created by \code{lavaanPlot} 40 | #' @param path Filename to save the image 41 | #' @param width width of image in pixels, NULL for default 42 | #' @param height height of image, NULL for default 43 | #' @return no return value calls \code{include_graphics} to embed plot in pdf 44 | #' @export 45 | #' @importFrom magrittr "%>%" 46 | #' @examples 47 | #' library(lavaan) 48 | #' model <- 'mpg ~ cyl + disp + hp 49 | #' qsec ~ disp + hp + wt' 50 | #' fit <- sem(model, data = mtcars) 51 | #' pl <- lavaanPlot(model = fit) 52 | #' \dontrun{ 53 | #' embed_plot_pdf(pl, "plot2.pdf") 54 | #' } 55 | embed_plot_pdf <- function(plot, path, width = NULL, height = NULL){ 56 | if (!requireNamespace("DiagrammeRsvg", quietly = TRUE)) { 57 | stop("Package \"DiagrammeRsvg\" needed for this function to work. Please install it.", 58 | call. = FALSE) 59 | } else if (!requireNamespace("rsvg", quietly = TRUE)) { 60 | stop("Package \"rsvg\" needed for this function to work. Please install it.", 61 | call. = FALSE) 62 | } else if (!requireNamespace("png", quietly = TRUE)) { 63 | stop("Package \"png\" needed for this function to work. Please install it.", 64 | call. = FALSE) 65 | } else { 66 | DiagrammeRsvg::export_svg(plot) %>% 67 | charToRaw() %>% 68 | rsvg::rsvg_pdf(path, width = width, height = height) 69 | 70 | knitr::include_graphics(path) 71 | } 72 | } 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | always_allow_html: true 4 | --- 5 | 6 | ```{r setup, include=FALSE} 7 | knitr::opts_chunk$set(echo = TRUE) 8 | ``` 9 | 10 | [![CRAN status](https://www.r-pkg.org/badges/version/lavaanPlot)](https://cran.r-project.org/package=lavaanPlot) 11 | [![](https://cranlogs.r-pkg.org/badges/lavaanPlot)](https://cran.r-project.org/package=lavaanPlot) 12 | [![R-CMD-check](https://github.com/alishinski/lavaanPlot/workflows/R-CMD-check/badge.svg)](https://github.com/alishinski/lavaanPlot/actions) 13 | 14 | ## News 15 | 16 | Version 0.7.0, is introducing a new iteration of the `lavaanPlot` function, called `lavaanPlot2`. Check out a new vignette explaining some of the changes here: [Improvements to lavaanPlot](https://lavaanplot.alexlishinski.com/improvements_to_lavaanplot) 17 | 18 | Version 0.8.0, is introducing conditional formatting to the `lavaanPlot` package, using the new `formatting` function. Check out the new vignette explaining the changes here: [Conditional Formatting in LavaanPlot](https://lavaanplot.alexlishinski.com/Conditional_Formatting) 19 | 20 | ## Background 21 | 22 | The lavaan package is an excellent package for structural equation models, and the DiagrammeR package is an excellent package for producing nice looking graph diagrams. As of right now, the lavaan package has no built in plotting functions for models, and the available options from external packages don't look as nice and aren't as easy to use as DiagrammeR, in my opinion. Of course, you can use DiagrammeR to build path diagrams for your models, but it requires you to build the diagram specification manually. This package exists to streamline that process, allowing you to plot your lavaan models directly, without having to translate them into the DOT language specification that DiagrammeR uses. 23 | 24 | ## Installation 25 | 26 | You can install lavaanPlot from CRAN with: 27 | 28 | ```{r, eval = F} 29 | install.packages("lavaanPlot") 30 | ``` 31 | 32 | You can also install the development version of lavaanPlot from GitHub with: 33 | 34 | ```{r gh-installation, eval = FALSE} 35 | install.packages("devtools") 36 | devtools::install_github("alishinski/lavaanPlot") 37 | ``` 38 | 39 | ## Examples 40 | 41 | Here's a quick example using the `mtcars` data set. 42 | 43 | First fit your lavaan model. The package supports plotting lavaan regression relationships and latent variable - indicator relationships. 44 | 45 | ```{r} 46 | library(lavaan) 47 | library(lavaanPlot) 48 | 49 | model <- 'mpg ~ cyl + disp + hp 50 | qsec ~ disp + hp + wt' 51 | 52 | fit <- sem(model, data = mtcars) 53 | summary(fit) 54 | ``` 55 | 56 | Then using that model fit object, simply call the `lavaanPlot` function, specifying your desired graph parameters. 57 | 58 | ```{r} 59 | lavaanPlot(model = fit, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = F) 60 | ``` 61 | 62 | There is also functionality to save these plots as images and embed them in pdf output documents. 63 | 64 | ```{r, eval = FALSE} 65 | model <- 'mpg ~ cyl + disp + hp 66 | qsec ~ disp + hp + wt' 67 | 68 | fit <- sem(model, data = mtcars) 69 | 70 | pl <- lavaanPlot(model = fit) 71 | 72 | # Example for pdf embed 73 | embed_plot_pdf(pl, "plot2.pdf") 74 | 75 | # Example for saving to .png 76 | save_png(pl, "plot.png") 77 | ``` 78 | 79 | # Learning More 80 | 81 | To learn more, check out the vignettes. 82 | 83 | 84 | ## Citing lavaanPlot 85 | 86 | If you found lavaanPlot useful and used the plots in a publication, I ask that you please cite the package. 87 | 88 | ## Contributing 89 | 90 | I welcome any and all contributions from people using the package, so please share github issues here if there are problems you encounter or features you want to suggest. 91 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | [![CRAN 3 | status](https://www.r-pkg.org/badges/version/lavaanPlot)](https://cran.r-project.org/package=lavaanPlot) 4 | [![](https://cranlogs.r-pkg.org/badges/lavaanPlot)](https://cran.r-project.org/package=lavaanPlot) 5 | [![R-CMD-check](https://github.com/alishinski/lavaanPlot/workflows/R-CMD-check/badge.svg)](https://github.com/alishinski/lavaanPlot/actions) 6 | 7 | ## News 8 | 9 | Version 0.7.0, introduced a new iteration of the `lavaanPlot` 10 | function, called `lavaanPlot2`. Check out a new vignette explaining some 11 | of the changes here: [Improvements to 12 | lavaanPlot](https://lavaanplot.alexlishinski.com/improvements_to_lavaanplot) 13 | 14 | Version 0.8.0, is introducing conditional formatting to the `lavaanPlot` 15 | package, using the new `formatting` function. Check out the new vignette 16 | explaining the changes here: [Conditional Formatting in 17 | LavaanPlot](https://lavaanplot.alexlishinski.com/Conditional_Formatting) 18 | 19 | ## Background 20 | 21 | The lavaan package is an excellent package for structural equation 22 | models, and the DiagrammeR package is an excellent package for producing 23 | nice looking graph diagrams. As of right now, the lavaan package has no 24 | built in plotting functions for models, and the available options from 25 | external packages don’t look as nice and aren’t as easy to use as 26 | DiagrammeR, in my opinion. Of course, you can use DiagrammeR to build 27 | path diagrams for your models, but it requires you to build the diagram 28 | specification manually. This package exists to streamline that process, 29 | allowing you to plot your lavaan models directly, without having to 30 | translate them into the DOT language specification that DiagrammeR uses. 31 | 32 | ## Installation 33 | 34 | You can install lavaanPlot from CRAN with: 35 | 36 | ``` r 37 | install.packages("lavaanPlot") 38 | ``` 39 | 40 | You can also install the development version of lavaanPlot from GitHub 41 | with: 42 | 43 | ``` r 44 | install.packages("devtools") 45 | devtools::install_github("alishinski/lavaanPlot") 46 | ``` 47 | 48 | ## Examples 49 | 50 | Here’s a quick example using the `mtcars` data set. 51 | 52 | First fit your lavaan model. The package supports plotting lavaan 53 | regression relationships and latent variable - indicator relationships. 54 | 55 | ``` r 56 | library(lavaan) 57 | ``` 58 | 59 | ## This is lavaan 0.6-11 60 | ## lavaan is FREE software! Please report any bugs. 61 | 62 | ``` r 63 | library(lavaanPlot) 64 | 65 | model <- 'mpg ~ cyl + disp + hp 66 | qsec ~ disp + hp + wt' 67 | 68 | fit <- sem(model, data = mtcars) 69 | summary(fit) 70 | ``` 71 | 72 | ## lavaan 0.6-11 ended normally after 32 iterations 73 | ## 74 | ## Estimator ML 75 | ## Optimization method NLMINB 76 | ## Number of model parameters 9 77 | ## 78 | ## Number of observations 32 79 | ## 80 | ## Model Test User Model: 81 | ## 82 | ## Test statistic 18.266 83 | ## Degrees of freedom 2 84 | ## P-value (Chi-square) 0.000 85 | ## 86 | ## Parameter Estimates: 87 | ## 88 | ## Standard errors Standard 89 | ## Information Expected 90 | ## Information saturated (h1) model Structured 91 | ## 92 | ## Regressions: 93 | ## Estimate Std.Err z-value P(>|z|) 94 | ## mpg ~ 95 | ## cyl -0.987 0.738 -1.337 0.181 96 | ## disp -0.021 0.010 -2.178 0.029 97 | ## hp -0.017 0.014 -1.218 0.223 98 | ## qsec ~ 99 | ## disp -0.008 0.004 -2.122 0.034 100 | ## hp -0.023 0.004 -5.229 0.000 101 | ## wt 1.695 0.398 4.256 0.000 102 | ## 103 | ## Covariances: 104 | ## Estimate Std.Err z-value P(>|z|) 105 | ## .mpg ~~ 106 | ## .qsec 0.447 0.511 0.874 0.382 107 | ## 108 | ## Variances: 109 | ## Estimate Std.Err z-value P(>|z|) 110 | ## .mpg 8.194 2.049 4.000 0.000 111 | ## .qsec 0.996 0.249 4.000 0.000 112 | 113 | Then using that model fit object, simply call the `lavaanPlot` function, 114 | specifying your desired graph parameters. 115 | 116 | ``` r 117 | lavaanPlot(model = fit, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = F) 118 | ``` 119 | 120 |
121 | 122 | 123 | There is also functionality to save these plots as images and embed them 124 | in pdf output documents. 125 | 126 | ``` r 127 | model <- 'mpg ~ cyl + disp + hp 128 | qsec ~ disp + hp + wt' 129 | 130 | fit <- sem(model, data = mtcars) 131 | 132 | pl <- lavaanPlot(model = fit) 133 | 134 | # Example for pdf embed 135 | embed_plot_pdf(pl, "plot2.pdf") 136 | 137 | # Example for saving to .png 138 | save_png(pl, "plot.png") 139 | ``` 140 | 141 | # Learning More 142 | 143 | To learn more, check out the vignettes. 144 | 145 | ## Citing lavaanPlot 146 | 147 | If you found lavaanPlot useful and used the plots in a publication, I 148 | ask that you please cite the package. 149 | 150 | ## Contributing 151 | 152 | I welcome any and all contributions from people using the package, so 153 | please share github issues here if there are problems you encounter or 154 | features you want to suggest. 155 | -------------------------------------------------------------------------------- /README_files/figure-gfm/pressure-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alishinski/lavaanPlot/9ed0816d678e145450ca1dd534ca9a4140961dfe/README_files/figure-gfm/pressure-1.png -------------------------------------------------------------------------------- /README_files/figure-gfm/unnamed-chunk-3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alishinski/lavaanPlot/9ed0816d678e145450ca1dd534ca9a4140961dfe/README_files/figure-gfm/unnamed-chunk-3-1.png -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | url: http://alexlishinski.com/lavaanPlot/ 2 | template: 3 | bootstrap: 5 4 | 5 | -------------------------------------------------------------------------------- /docs/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Page not found (404) • lavaanPlot 9 | 10 | 11 | 12 | 13 | 14 | 18 | 19 | 20 | Skip to contents 21 | 22 | 23 |
69 |
70 |
74 | 75 | Content not found. Please use links in the navbar. 76 | 77 |
78 |
79 | 80 | 81 |
85 | 86 | 90 | 91 |
92 |
93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /docs/articles/Intro_to_lavaanPlot_files/DiagrammeR-styles-0.2/styles.css: -------------------------------------------------------------------------------- 1 | .DiagrammeR,.grViz pre { 2 | white-space: pre-wrap; /* CSS 3 */ 3 | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ 4 | white-space: -pre-wrap; /* Opera 4-6 */ 5 | white-space: -o-pre-wrap; /* Opera 7 */ 6 | word-wrap: break-word; /* Internet Explorer 5.5+ */ 7 | } 8 | 9 | .DiagrammeR g .label { 10 | font-family: Helvetica; 11 | font-size: 14px; 12 | color: #333333; 13 | } 14 | 15 | -------------------------------------------------------------------------------- /docs/articles/Intro_to_lavaanPlot_files/grViz-binding-1.0.9/grViz.js: -------------------------------------------------------------------------------- 1 | HTMLWidgets.widget({ 2 | 3 | name: 'grViz', 4 | 5 | type: 'output', 6 | 7 | initialize: function(el, width, height) { 8 | 9 | return { 10 | // TODO: add instance fields as required 11 | }; 12 | }, 13 | 14 | renderValue: function(el, x, instance) { 15 | // Use this to sort of make our diagram responsive 16 | // or at a minimum fit within the bounds set by htmlwidgets 17 | // for the parent container 18 | function makeResponsive(el){ 19 | var svg = el.getElementsByTagName("svg")[0]; 20 | if (svg) { 21 | if (svg.width) {svg.removeAttribute("width")} 22 | if (svg.height) {svg.removeAttribute("height")} 23 | svg.style.width = "100%"; 24 | svg.style.height = "100%"; 25 | } 26 | } 27 | 28 | if (x.diagram !== "") { 29 | 30 | if (typeof x.config === "undefined"){ 31 | x.config = {}; 32 | x.config.engine = "dot"; 33 | x.config.options = {}; 34 | } 35 | 36 | try { 37 | 38 | el.innerHTML = Viz(x.diagram, format="svg", engine=x.config.engine, options=x.config.options); 39 | 40 | makeResponsive(el); 41 | 42 | if (HTMLWidgets.shinyMode) { 43 | // Get widget id 44 | var id = el.id; 45 | 46 | $("#" + id + " .node").click(function(e) { 47 | // Get node id 48 | var nodeid = e.currentTarget.id; 49 | // Get node text object and make an array 50 | var node_texts = $("#" + id + " #" + nodeid + " text"); 51 | //var node_path = $("#" + nodeid + " path")[0]; 52 | var text_array = node_texts.map(function() {return $(this).text(); }).toArray(); 53 | // Build return object *obj* with node-id, node text values and node fill 54 | var obj = { 55 | id: nodeid, 56 | //fill: node_path.attributes.fill.nodeValue, 57 | //outerHMTL: node_path.outerHTML, 58 | nodeValues: text_array 59 | }; 60 | // Send *obj* to Shiny's inputs (input$[id]+_click e.g.: input$vtree_click)) 61 | Shiny.setInputValue(id + "_click", obj, {priority: "event"}); 62 | }); 63 | } 64 | 65 | // set up a container for tasks to perform after completion 66 | // one example would be add callbacks for event handling 67 | // styling 68 | if (typeof x.tasks !== "undefined") { 69 | if ((typeof x.tasks.length === "undefined") || 70 | (typeof x.tasks === "function")) { 71 | // handle a function not enclosed in array 72 | // should be able to remove once using jsonlite 73 | x.tasks = [x.tasks]; 74 | } 75 | x.tasks.map(function(t){ 76 | // for each tasks add it to the mermaid.tasks with el 77 | t.call(el); 78 | }); 79 | } 80 | } catch(e){ 81 | var p = document.createElement("pre"); 82 | p.innerText = e; 83 | el.appendChild(p); 84 | } 85 | } 86 | 87 | }, 88 | 89 | resize: function(el, width, height, instance) { 90 | } 91 | }); 92 | -------------------------------------------------------------------------------- /docs/articles/Save_and_embed.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | lavaanPlot: Saving and Embedding Plots • lavaanPlot 10 | 11 | 12 | 13 | 14 | 15 | 16 | 20 | 21 | 22 | Skip to contents 23 | 24 | 25 |
71 | 72 | 73 | 74 | 75 |
76 |
86 | 87 | 88 | 89 |

Functions for embedding plots in Rmarkdown pdfs and for saving plots 90 | as pngs

91 |

embed_plot_pdf() saves your plot as a pdf image and then 92 | inserts that image into the pdf when you render Rmardown doc.

93 |

save_png() as the name suggests, saves your plot as a 94 | png image in the local directory (or wherever you tell it to).

95 |
 96 | model <- 'mpg ~ cyl + disp + hp
 97 |           qsec ~ disp + hp + wt'
 98 | 
 99 | fit <- sem(model, data = mtcars)
100 | 
101 | pl <- lavaanPlot(model = fit)
102 | 
103 | # Example for pdf embed
104 | embed_plot_pdf(pl, "plot2.pdf", width = 500)
105 | 
106 | # Example for saving to .png
107 | save_png(pl, "plot.png", width = 500)
108 |

Now having saved the image, it can be embedded in the document with 109 | ![saved plot](plot.png)

110 |
111 |

saved plot

112 |
113 |
115 |
116 | 117 | 118 | 119 |
123 | 124 | 128 | 129 |
130 |
131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /docs/articles/index.html: -------------------------------------------------------------------------------- 1 | 2 | Articles • lavaanPlot 6 | Skip to contents 7 | 8 | 9 |
50 |
51 |
54 | 55 |
56 |

All vignettes

57 |

58 | 59 |
Conditional Formatting
60 |
61 |
Improvements to lavaanPlot
62 |
63 |
Intro to lavaanPlot
64 |
65 |
lavaanPlot: Saving and Embedding Plots
66 |
67 |
68 |
69 | 70 | 71 |
74 | 75 | 78 | 79 |
80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /docs/articles/plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alishinski/lavaanPlot/9ed0816d678e145450ca1dd534ca9a4140961dfe/docs/articles/plot.png -------------------------------------------------------------------------------- /docs/authors.html: -------------------------------------------------------------------------------- 1 | 2 | Authors and Citation • lavaanPlot 6 | Skip to contents 7 | 8 | 9 |
50 |
51 |
54 | 55 |
56 |

Authors

57 | 58 |
  • 59 |

    Alex Lishinski. Maintainer. 60 |

    61 |
  • 62 |
63 | 64 |
65 |

Citation

66 |

Source: DESCRIPTION

67 | 68 |

Lishinski A (2022). 69 | lavaanPlot: Path Diagrams for 'Lavaan' Models via 'DiagrammeR'. 70 | https://github.com/alishinski/lavaanPlot, 71 | https://lavaanplot.alexlishinski.com/. 72 |

73 |
@Manual{,
 74 |   title = {lavaanPlot: Path Diagrams for 'Lavaan' Models via 'DiagrammeR'},
 75 |   author = {Alex Lishinski},
 76 |   year = {2022},
 77 |   note = {https://github.com/alishinski/lavaanPlot,
 78 | https://lavaanplot.alexlishinski.com/},
 79 | }
80 |
81 |
83 | 84 | 85 |
88 | 89 | 92 | 93 |
94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /docs/deps/data-deps.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /docs/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /docs/news/index.html: -------------------------------------------------------------------------------- 1 | 2 | Changelog • lavaanPlot 6 | Skip to contents 7 | 8 | 9 |
50 |
51 |
55 | 56 |
57 |

lavaanPlot 0.3.0

CRAN release: 2018-01-26

58 |
  • Added support for latent variables (denoted by circles) in plots

  • 59 |
  • Added support for edge labels with significant coefficients

  • 60 |
61 |
62 |

lavaanPlot 0.4.0

63 |
  • Added support for latent variable loading labels

  • 64 |
  • Added support for covariance edges

  • 65 |
  • Corrected the direction of arrows for latent variable loadings

  • 66 |
67 |
68 |

lavaanPlot 0.5.0

69 |
  • Added support for covariance edge labels

  • 70 |
  • Added support for significance stars

  • 71 |
72 |
73 |

lavaanPlot 0.5.1

CRAN release: 2018-04-25

74 |
  • Fixed bug caused by . in variable names

  • 75 |
  • simplified the functions using the … argument

  • 76 |
  • fixed significance stars to work with standardized and non-standardized coefficients

  • 77 |
  • Changed significance stars so you can choose which parameters to use them with

  • 78 |
79 |
80 |

lavaanPlot 0.5.2

81 |
  • Added digits option for coefficients

  • 82 |
  • Changed coefs argument behavior so that it toggles coef values for covariances too

  • 83 |
  • Plots now show residual covariances

  • 84 |
85 |
86 |

lavaanPlot 0.6.0

CRAN release: 2021-02-03

87 |
  • added functions to save plots as images and embed plots in pdfs with Rmarkdown
  • 88 |
89 |
90 |

lavaanPlot 0.6.2

CRAN release: 2021-08-13

91 |
  • Fixed issues with suggested packages that were causing trouble for CRAN submission
  • 92 |
93 |
94 |

lavaanPlot 0.6.3

95 |
  • Added support for specifying dimensions of saved png files

  • 96 |
  • Updated vignette for layout graph options

  • 97 |
  • Added package tests

  • 98 |
99 |
100 |

lavaanPlot 0.7.0

101 |
  • Introducing lavaanPlot2 function, which replicates the old functionality in a more flexible platform
  • 102 |
103 |
104 |

lavaanPlot 0.8.0

105 |
  • Introducing conditional formatting which allows one to apply different formatting to different sets of nodes and edges
  • 106 |
107 |
109 | 110 | 111 |
114 | 115 | 118 | 119 |
120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /docs/pkgdown.js: -------------------------------------------------------------------------------- 1 | /* http://gregfranko.com/blog/jquery-best-practices/ */ 2 | (function($) { 3 | $(function() { 4 | 5 | $('nav.navbar').headroom(); 6 | 7 | Toc.init({ 8 | $nav: $("#toc"), 9 | $scope: $("main h2, main h3, main h4, main h5, main h6") 10 | }); 11 | 12 | if ($('#toc').length) { 13 | $('body').scrollspy({ 14 | target: '#toc', 15 | offset: $("nav.navbar").outerHeight() + 1 16 | }); 17 | } 18 | 19 | // Activate popovers 20 | $('[data-bs-toggle="popover"]').popover({ 21 | container: 'body', 22 | html: true, 23 | trigger: 'focus', 24 | placement: "top", 25 | sanitize: false, 26 | }); 27 | 28 | $('[data-bs-toggle="tooltip"]').tooltip(); 29 | 30 | /* Clipboard --------------------------*/ 31 | 32 | function changeTooltipMessage(element, msg) { 33 | var tooltipOriginalTitle=element.getAttribute('data-original-title'); 34 | element.setAttribute('data-original-title', msg); 35 | $(element).tooltip('show'); 36 | element.setAttribute('data-original-title', tooltipOriginalTitle); 37 | } 38 | 39 | if(ClipboardJS.isSupported()) { 40 | $(document).ready(function() { 41 | var copyButton = ""; 42 | 43 | $("div.sourceCode").addClass("hasCopyButton"); 44 | 45 | // Insert copy buttons: 46 | $(copyButton).prependTo(".hasCopyButton"); 47 | 48 | // Initialize tooltips: 49 | $('.btn-copy-ex').tooltip({container: 'body'}); 50 | 51 | // Initialize clipboard: 52 | var clipboard = new ClipboardJS('[data-clipboard-copy]', { 53 | text: function(trigger) { 54 | return trigger.parentNode.textContent.replace(/\n#>[^\n]*/g, ""); 55 | } 56 | }); 57 | 58 | clipboard.on('success', function(e) { 59 | changeTooltipMessage(e.trigger, 'Copied!'); 60 | e.clearSelection(); 61 | }); 62 | 63 | clipboard.on('error', function() { 64 | changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); 65 | }); 66 | 67 | }); 68 | } 69 | 70 | /* Search marking --------------------------*/ 71 | var url = new URL(window.location.href); 72 | var toMark = url.searchParams.get("q"); 73 | var mark = new Mark("main#main"); 74 | if (toMark) { 75 | mark.mark(toMark, { 76 | accuracy: { 77 | value: "complementary", 78 | limiters: [",", ".", ":", "/"], 79 | } 80 | }); 81 | } 82 | 83 | /* Search --------------------------*/ 84 | /* Adapted from https://github.com/rstudio/bookdown/blob/2d692ba4b61f1e466c92e78fd712b0ab08c11d31/inst/resources/bs4_book/bs4_book.js#L25 */ 85 | // Initialise search index on focus 86 | var fuse; 87 | $("#search-input").focus(async function(e) { 88 | if (fuse) { 89 | return; 90 | } 91 | 92 | $(e.target).addClass("loading"); 93 | var response = await fetch($("#search-input").data("search-index")); 94 | var data = await response.json(); 95 | 96 | var options = { 97 | keys: ["what", "text", "code"], 98 | ignoreLocation: true, 99 | threshold: 0.1, 100 | includeMatches: true, 101 | includeScore: true, 102 | }; 103 | fuse = new Fuse(data, options); 104 | 105 | $(e.target).removeClass("loading"); 106 | }); 107 | 108 | // Use algolia autocomplete 109 | var options = { 110 | autoselect: true, 111 | debug: true, 112 | hint: false, 113 | minLength: 2, 114 | }; 115 | var q; 116 | async function searchFuse(query, callback) { 117 | await fuse; 118 | 119 | var items; 120 | if (!fuse) { 121 | items = []; 122 | } else { 123 | q = query; 124 | var results = fuse.search(query, { limit: 20 }); 125 | items = results 126 | .filter((x) => x.score <= 0.75) 127 | .map((x) => x.item); 128 | if (items.length === 0) { 129 | items = [{dir:"Sorry 😿",previous_headings:"",title:"No results found.",what:"No results found.",path:window.location.href}]; 130 | } 131 | } 132 | callback(items); 133 | } 134 | $("#search-input").autocomplete(options, [ 135 | { 136 | name: "content", 137 | source: searchFuse, 138 | templates: { 139 | suggestion: (s) => { 140 | if (s.title == s.what) { 141 | return `${s.dir} >
${s.title}
`; 142 | } else if (s.previous_headings == "") { 143 | return `${s.dir} >
${s.title}
> ${s.what}`; 144 | } else { 145 | return `${s.dir} >
${s.title}
> ${s.previous_headings} > ${s.what}`; 146 | } 147 | }, 148 | }, 149 | }, 150 | ]).on('autocomplete:selected', function(event, s) { 151 | window.location.href = s.path + "?q=" + q + "#" + s.id; 152 | }); 153 | }); 154 | })(window.jQuery || window.$) 155 | 156 | 157 | -------------------------------------------------------------------------------- /docs/pkgdown.yml: -------------------------------------------------------------------------------- 1 | pandoc: '2.18' 2 | pkgdown: 2.0.6 3 | pkgdown_sha: ~ 4 | articles: 5 | Conditional_Formatting: Conditional_Formatting.html 6 | Improvements_to_lavaanPlot: Improvements_to_lavaanPlot.html 7 | Intro_to_lavaanPlot: Intro_to_lavaanPlot.html 8 | Save_and_embed: Save_and_embed.html 9 | last_built: 2022-09-12T18:33Z 10 | 11 | -------------------------------------------------------------------------------- /docs/reference/Rplot001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alishinski/lavaanPlot/9ed0816d678e145450ca1dd534ca9a4140961dfe/docs/reference/Rplot001.png -------------------------------------------------------------------------------- /docs/reference/buildCall.html: -------------------------------------------------------------------------------- 1 | 2 | Builds the Diagrammer function call. — buildCall • lavaanPlot 6 | Skip to contents 7 | 8 | 9 |
50 |
51 |
56 | 57 |
58 |

Builds the Diagrammer function call.

59 |
60 | 61 |
62 |

Usage

63 |
buildCall(
 64 |   model = model,
 65 |   name = name,
 66 |   labels = labels,
 67 |   graph_options = list(overlap = "true", fontsize = "10"),
 68 |   node_options = list(shape = "box"),
 69 |   edge_options = list(color = "black"),
 70 |   ...
 71 | )
72 |
73 | 74 |
75 |

Arguments

76 |
model
77 |

A model fit object of class lavaan.

78 | 79 | 80 |
name
81 |

A string of the name of the plot.

82 | 83 | 84 |
labels
85 |

An optional named list of variable labels fit object of class lavaan.

86 | 87 | 88 |
graph_options
89 |

A named list of graph options for Diagrammer syntax.

90 | 91 | 92 |
node_options
93 |

A named list of node options for Diagrammer syntax.

94 | 95 | 96 |
edge_options
97 |

A named list of edge options for Diagrammer syntax.

98 | 99 | 100 |
...
101 |

additional arguments to be passed to buildPaths

102 | 103 |
104 |
105 |

Value

106 | 107 | 108 |

A string specifying the path diagram for model

109 | 110 | 111 |
112 | 113 |
115 | 116 | 117 |
120 | 121 | 124 | 125 |
126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /docs/reference/buildLabels.html: -------------------------------------------------------------------------------- 1 | 2 | Adds variable labels to the Diagrammer plot function call. — buildLabels • lavaanPlot 6 | Skip to contents 7 | 8 | 9 |
50 |
51 |
56 | 57 |
58 |

Adds variable labels to the Diagrammer plot function call.

59 |
60 | 61 |
62 |

Usage

63 |
buildLabels(label_list)
64 |
65 | 66 |
67 |

Arguments

68 |
label_list
69 |

A named list of variable labels.

70 | 71 |
72 | 73 |
75 | 76 | 77 |
80 | 81 | 84 | 85 |
86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /docs/reference/buildPaths.html: -------------------------------------------------------------------------------- 1 | 2 | Extracts the paths from the lavaan model. — buildPaths • lavaanPlot 6 | Skip to contents 7 | 8 | 9 |
50 |
51 |
56 | 57 |
58 |

Extracts the paths from the lavaan model.

59 |
60 | 61 |
62 |

Usage

63 |
buildPaths(
 64 |   fit,
 65 |   coefs = FALSE,
 66 |   sig = 1,
 67 |   stand = FALSE,
 68 |   covs = FALSE,
 69 |   stars = NULL,
 70 |   digits = 2
 71 | )
72 |
73 | 74 |
75 |

Arguments

76 |
fit
77 |

A model fit object of class lavaan.

78 | 79 | 80 |
coefs
81 |

whether or not to include significant path coefficient values in diagram

82 | 83 | 84 |
sig
85 |

significance level for determining what significant paths are

86 | 87 | 88 |
stand
89 |

Should the coefficients being used be standardized coefficients

90 | 91 | 92 |
covs
93 |

Should model covariances be included in the diagram

94 | 95 | 96 |
stars
97 |

a character vector indicating which parameters should include significance stars be included for regression paths, latent paths, or covariances. Include which of the 3 you want ("regress", "latent", "covs"), default is none.

98 | 99 | 100 |
digits
101 |

A number indicating the desired number of digits for the coefficient values in the plot

102 | 103 |
104 | 105 |
107 | 108 | 109 |
112 | 113 | 116 | 117 |
118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /docs/reference/embed_plot_pdf.html: -------------------------------------------------------------------------------- 1 | 2 | Embeds a plot into an rmarkdown pdf — embed_plot_pdf • lavaanPlot 6 | Skip to contents 7 | 8 | 9 |
50 |
51 |
56 | 57 |
58 |

Embeds a plot into an rmarkdown pdf

59 |
60 | 61 |
62 |

Usage

63 |
embed_plot_pdf(plot, path, width = NULL, height = NULL)
64 |
65 | 66 |
67 |

Arguments

68 |
plot
69 |

plot object created by lavaanPlot

70 | 71 | 72 |
path
73 |

Filename to save the image

74 | 75 | 76 |
width
77 |

width of image in pixels, NULL for default

78 | 79 | 80 |
height
81 |

height of image, NULL for default

82 | 83 |
84 |
85 |

Value

86 | 87 | 88 |

no return value calls include_graphics to embed plot in pdf

89 |
90 | 91 |
92 |

Examples

93 |
library(lavaan)
 94 | #> This is lavaan 0.6-11
 95 | #> lavaan is FREE software! Please report any bugs.
 96 | model <- 'mpg ~ cyl + disp + hp
 97 |           qsec ~ disp + hp + wt'
 98 | fit <- sem(model, data = mtcars)
 99 | pl <- lavaanPlot(model = fit)
100 | if (FALSE) {
101 | embed_plot_pdf(pl, "plot2.pdf")
102 | }
103 | 
104 |
105 |
107 | 108 | 109 |
112 | 113 | 116 | 117 |
118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /docs/reference/getNodes.html: -------------------------------------------------------------------------------- 1 | 2 | Extracts the paths from the lavaan model. — getNodes • lavaanPlot 6 | Skip to contents 7 | 8 | 9 |
50 |
51 |
56 | 57 |
58 |

Extracts the paths from the lavaan model.

59 |
60 | 61 |
62 |

Usage

63 |
getNodes(fit)
64 |
65 | 66 |
67 |

Arguments

68 |
fit
69 |

A model fit object of class lavaan.

70 | 71 |
72 | 73 |
75 | 76 | 77 |
80 | 81 | 84 | 85 |
86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /docs/reference/index.html: -------------------------------------------------------------------------------- 1 | 2 | Function reference • lavaanPlot 6 | Skip to contents 7 | 8 | 9 |
50 |
51 |
54 | 55 |
56 |

All functions

57 | 58 | 59 | 60 | 61 |
62 | 63 | 64 | 65 | 66 |
67 | 68 | buildCall() 69 |
70 |
Builds the Diagrammer function call.
71 |
72 | 73 | buildLabels() 74 |
75 |
Adds variable labels to the Diagrammer plot function call.
76 |
77 | 78 | buildPaths() 79 |
80 |
Extracts the paths from the lavaan model.
81 |
82 | 83 | convert_graph() 84 |
85 |
Uses the diagrammeR functions to turn the ndf and edf into dot
86 |
87 | 88 | create_edges() 89 |
90 |
Creates edge data frame and adds formatting
91 |
92 | 93 | create_grviz() 94 |
95 |
Creates the grViz dot language code for plotting
96 |
97 | 98 | create_nodes() 99 |
100 |
Creates node data frame and adds formatting
101 |
102 | 103 | embed_plot_pdf() 104 |
105 |
Embeds a plot into an rmarkdown pdf
106 |
107 | 108 | extract_coefs() 109 |
110 |
Creates a data frame of the parameter table from lavaan model
111 |
112 | 113 | formatting() 114 |
115 |
Enables conditional formatting for different parts of the model
116 |
117 | 118 | getNodes() 119 |
120 |
Extracts the paths from the lavaan model.
121 |
122 | 123 | lavaanPlot() 124 |
125 |
Plots lavaan path model with DiagrammeR
126 |
127 | 128 | lavaanPlot2() 129 |
130 |
Plots lavaan path model with DiagrammeR
131 |
132 | 133 | save_png() 134 |
135 |
Saves a plot as a png
136 |
137 | 138 | sig_stars() sig_stars() 139 |
140 |
Generates standard significance stars
141 |
142 |
143 | 144 | 145 |
148 | 149 | 152 | 153 |
154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /docs/reference/lavaanPlot.html: -------------------------------------------------------------------------------- 1 | 2 | Plots lavaan path model with DiagrammeR — lavaanPlot • lavaanPlot 6 | Skip to contents 7 | 8 | 9 |
50 |
51 |
56 | 57 |
58 |

Plots lavaan path model with DiagrammeR

59 |
60 | 61 |
62 |

Usage

63 |
lavaanPlot(model, name = "plot", labels = NULL, ...)
64 |
65 | 66 |
67 |

Arguments

68 |
model
69 |

A model fit object of class lavaan.

70 | 71 | 72 |
name
73 |

A string of the name of the plot.

74 | 75 | 76 |
labels
77 |

An optional named list of variable labels.

78 | 79 | 80 |
...
81 |

Additional arguments to be called to buildCall and buildPaths

82 | 83 |
84 |
85 |

Value

86 | 87 | 88 |

A Diagrammer plot of the path diagram for model

89 | 90 | 91 |
92 | 93 |
94 |

Examples

95 |
library(lavaan)
 96 | model <- 'mpg ~ cyl + disp + hp
 97 |           qsec ~ disp + hp + wt'
 98 | fit <- sem(model, data = mtcars)
 99 | lavaanPlot(model = fit, node_options = list(shape = "box", fontname = "Helvetica"),
100 |  edge_options = list(color = "grey"), coefs = FALSE)
101 | 
102 |
103 |
104 |
106 | 107 | 108 |
111 | 112 | 115 | 116 |
117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /docs/reference/libs/DiagrammeR-styles-0.2/styles.css: -------------------------------------------------------------------------------- 1 | .DiagrammeR,.grViz pre { 2 | white-space: pre-wrap; /* CSS 3 */ 3 | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ 4 | white-space: -pre-wrap; /* Opera 4-6 */ 5 | white-space: -o-pre-wrap; /* Opera 7 */ 6 | word-wrap: break-word; /* Internet Explorer 5.5+ */ 7 | } 8 | 9 | .DiagrammeR g .label { 10 | font-family: Helvetica; 11 | font-size: 14px; 12 | color: #333333; 13 | } 14 | 15 | -------------------------------------------------------------------------------- /docs/reference/libs/grViz-binding-1.0.9/grViz.js: -------------------------------------------------------------------------------- 1 | HTMLWidgets.widget({ 2 | 3 | name: 'grViz', 4 | 5 | type: 'output', 6 | 7 | initialize: function(el, width, height) { 8 | 9 | return { 10 | // TODO: add instance fields as required 11 | }; 12 | }, 13 | 14 | renderValue: function(el, x, instance) { 15 | // Use this to sort of make our diagram responsive 16 | // or at a minimum fit within the bounds set by htmlwidgets 17 | // for the parent container 18 | function makeResponsive(el){ 19 | var svg = el.getElementsByTagName("svg")[0]; 20 | if (svg) { 21 | if (svg.width) {svg.removeAttribute("width")} 22 | if (svg.height) {svg.removeAttribute("height")} 23 | svg.style.width = "100%"; 24 | svg.style.height = "100%"; 25 | } 26 | } 27 | 28 | if (x.diagram !== "") { 29 | 30 | if (typeof x.config === "undefined"){ 31 | x.config = {}; 32 | x.config.engine = "dot"; 33 | x.config.options = {}; 34 | } 35 | 36 | try { 37 | 38 | el.innerHTML = Viz(x.diagram, format="svg", engine=x.config.engine, options=x.config.options); 39 | 40 | makeResponsive(el); 41 | 42 | if (HTMLWidgets.shinyMode) { 43 | // Get widget id 44 | var id = el.id; 45 | 46 | $("#" + id + " .node").click(function(e) { 47 | // Get node id 48 | var nodeid = e.currentTarget.id; 49 | // Get node text object and make an array 50 | var node_texts = $("#" + id + " #" + nodeid + " text"); 51 | //var node_path = $("#" + nodeid + " path")[0]; 52 | var text_array = node_texts.map(function() {return $(this).text(); }).toArray(); 53 | // Build return object *obj* with node-id, node text values and node fill 54 | var obj = { 55 | id: nodeid, 56 | //fill: node_path.attributes.fill.nodeValue, 57 | //outerHMTL: node_path.outerHTML, 58 | nodeValues: text_array 59 | }; 60 | // Send *obj* to Shiny's inputs (input$[id]+_click e.g.: input$vtree_click)) 61 | Shiny.setInputValue(id + "_click", obj, {priority: "event"}); 62 | }); 63 | } 64 | 65 | // set up a container for tasks to perform after completion 66 | // one example would be add callbacks for event handling 67 | // styling 68 | if (typeof x.tasks !== "undefined") { 69 | if ((typeof x.tasks.length === "undefined") || 70 | (typeof x.tasks === "function")) { 71 | // handle a function not enclosed in array 72 | // should be able to remove once using jsonlite 73 | x.tasks = [x.tasks]; 74 | } 75 | x.tasks.map(function(t){ 76 | // for each tasks add it to the mermaid.tasks with el 77 | t.call(el); 78 | }); 79 | } 80 | } catch(e){ 81 | var p = document.createElement("pre"); 82 | p.innerText = e; 83 | el.appendChild(p); 84 | } 85 | } 86 | 87 | }, 88 | 89 | resize: function(el, width, height, instance) { 90 | } 91 | }); 92 | -------------------------------------------------------------------------------- /docs/reference/save_png.html: -------------------------------------------------------------------------------- 1 | 2 | Saves a plot as a png — save_png • lavaanPlot 6 | Skip to contents 7 | 8 | 9 |
50 |
51 |
56 | 57 |
58 |

Saves a plot as a png

59 |
60 | 61 |
62 |

Usage

63 |
save_png(plot, path, width = NULL, height = NULL)
64 |
65 | 66 |
67 |

Arguments

68 |
plot
69 |

plot object created by lavaanPlot

70 | 71 | 72 |
path
73 |

filename to save the image

74 | 75 | 76 |
width
77 |

width of image in pixels, NULL for default

78 | 79 | 80 |
height
81 |

height of image, NULL for default

82 | 83 |
84 |
85 |

Value

86 | 87 | 88 |

no return value saves plot as png

89 |
90 | 91 |
92 |

Examples

93 |
library(lavaan)
 94 | model <- 'mpg ~ cyl + disp + hp
 95 |           qsec ~ disp + hp + wt'
 96 | fit <- sem(model, data = mtcars)
 97 | pl <- lavaanPlot(model = fit)
 98 | if (FALSE) {
 99 | save_png(pl, "plot.png")
100 | }
101 | 
102 |
103 |
105 | 106 | 107 |
110 | 111 | 114 | 115 |
116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /docs/reference/sig_stars.html: -------------------------------------------------------------------------------- 1 | 2 | Generates standard significance stars — sig_stars • lavaanPlot 8 | Skip to contents 9 | 10 | 11 |
52 |
53 |
58 | 59 |
60 |

Generates standard significance stars

61 |

Generates standard significance stars

62 |
63 | 64 |
65 |

Usage

66 |
sig_stars(pvals)
67 | 
68 | sig_stars(pvals)
69 |
70 | 71 |
72 |

Arguments

73 |
pvals
74 |

a vector of p values

75 | 76 |
77 | 78 |
80 | 81 | 82 |
85 | 86 | 89 | 90 |
91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /docs/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /404.html 5 | 6 | 7 | /articles/Conditional_Formatting.html 8 | 9 | 10 | /articles/Improvements_to_lavaanPlot.html 11 | 12 | 13 | /articles/Intro_to_lavaanPlot.html 14 | 15 | 16 | /articles/Save_and_embed.html 17 | 18 | 19 | /articles/index.html 20 | 21 | 22 | /authors.html 23 | 24 | 25 | /index.html 26 | 27 | 28 | /news/index.html 29 | 30 | 31 | /reference/buildCall.html 32 | 33 | 34 | /reference/buildLabels.html 35 | 36 | 37 | /reference/buildPaths.html 38 | 39 | 40 | /reference/convert_graph.html 41 | 42 | 43 | /reference/create_edges.html 44 | 45 | 46 | /reference/create_grviz.html 47 | 48 | 49 | /reference/create_nodes.html 50 | 51 | 52 | /reference/embed_plot_pdf.html 53 | 54 | 55 | /reference/extract_coefs.html 56 | 57 | 58 | /reference/formatting.html 59 | 60 | 61 | /reference/getNodes.html 62 | 63 | 64 | /reference/index.html 65 | 66 | 67 | /reference/lavaanPlot.html 68 | 69 | 70 | /reference/lavaanPlot2.html 71 | 72 | 73 | /reference/save_png.html 74 | 75 | 76 | /reference/sig_stars.html 77 | 78 | 79 | -------------------------------------------------------------------------------- /lavaanPlot.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageCheckArgs: --as-cran 22 | PackageRoxygenize: rd,collate,namespace,vignette 23 | -------------------------------------------------------------------------------- /man/buildCall.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/lavaanPlot.R 3 | \name{buildCall} 4 | \alias{buildCall} 5 | \title{Builds the Diagrammer function call.} 6 | \usage{ 7 | buildCall( 8 | model = model, 9 | name = name, 10 | labels = labels, 11 | graph_options = list(overlap = "true", fontsize = "10"), 12 | node_options = list(shape = "box"), 13 | edge_options = list(color = "black"), 14 | ... 15 | ) 16 | } 17 | \arguments{ 18 | \item{model}{A model fit object of class lavaan.} 19 | 20 | \item{name}{A string of the name of the plot.} 21 | 22 | \item{labels}{An optional named list of variable labels fit object of class lavaan.} 23 | 24 | \item{graph_options}{A named list of graph options for Diagrammer syntax.} 25 | 26 | \item{node_options}{A named list of node options for Diagrammer syntax.} 27 | 28 | \item{edge_options}{A named list of edge options for Diagrammer syntax.} 29 | 30 | \item{...}{additional arguments to be passed to \code{buildPaths}} 31 | } 32 | \value{ 33 | A string specifying the path diagram for \code{model} 34 | } 35 | \description{ 36 | Builds the Diagrammer function call. 37 | } 38 | -------------------------------------------------------------------------------- /man/buildLabels.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/lavaanPlot.R 3 | \name{buildLabels} 4 | \alias{buildLabels} 5 | \title{Adds variable labels to the Diagrammer plot function call.} 6 | \usage{ 7 | buildLabels(label_list) 8 | } 9 | \arguments{ 10 | \item{label_list}{A named list of variable labels.} 11 | } 12 | \description{ 13 | Adds variable labels to the Diagrammer plot function call. 14 | } 15 | -------------------------------------------------------------------------------- /man/buildPaths.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/lavaanPlot.R 3 | \name{buildPaths} 4 | \alias{buildPaths} 5 | \title{Extracts the paths from the lavaan model.} 6 | \usage{ 7 | buildPaths( 8 | fit, 9 | coefs = FALSE, 10 | sig = 1, 11 | stand = FALSE, 12 | covs = FALSE, 13 | stars = NULL, 14 | digits = 2 15 | ) 16 | } 17 | \arguments{ 18 | \item{fit}{A model fit object of class lavaan.} 19 | 20 | \item{coefs}{whether or not to include significant path coefficient values in diagram} 21 | 22 | \item{sig}{significance level for determining what significant paths are} 23 | 24 | \item{stand}{Should the coefficients being used be standardized coefficients} 25 | 26 | \item{covs}{Should model covariances be included in the diagram} 27 | 28 | \item{stars}{a character vector indicating which parameters should include significance stars be included for regression paths, latent paths, or covariances. Include which of the 3 you want ("regress", "latent", "covs"), default is none.} 29 | 30 | \item{digits}{A number indicating the desired number of digits for the coefficient values in the plot} 31 | } 32 | \description{ 33 | Extracts the paths from the lavaan model. 34 | } 35 | -------------------------------------------------------------------------------- /man/convert_graph.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/lavaanPlot2.R 3 | \name{convert_graph} 4 | \alias{convert_graph} 5 | \title{Uses the diagrammeR functions to turn the ndf and edf into dot} 6 | \usage{ 7 | convert_graph(ndf, edf, graph_options) 8 | } 9 | \arguments{ 10 | \item{ndf}{A node data frame created by \code{create_nodes}} 11 | 12 | \item{edf}{An edge data frame created by \code{create_edges}} 13 | 14 | \item{graph_options}{a named list of graphviz graph attributes} 15 | } 16 | \value{ 17 | DOT specification of model 18 | } 19 | \description{ 20 | Uses the diagrammeR functions to turn the ndf and edf into dot 21 | } 22 | -------------------------------------------------------------------------------- /man/create_edges.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/lavaanPlot2.R 3 | \name{create_edges} 4 | \alias{create_edges} 5 | \title{Creates edge data frame and adds formatting} 6 | \usage{ 7 | create_edges( 8 | coefs, 9 | ndf, 10 | edge_options, 11 | coef_labels = FALSE, 12 | stand = FALSE, 13 | stars = NULL, 14 | sig = 1 15 | ) 16 | } 17 | \arguments{ 18 | \item{coefs}{a coefficient table from lavaan model created by \code{extract_coefs}} 19 | 20 | \item{ndf}{A node data frame created by \code{create_nodes}} 21 | 22 | \item{edge_options}{a named list of graphviz edge attributes, or a data frame of edge options created by \code{formatting}, or a list of such data frames containing 1 set of edge options and one set of custom options} 23 | 24 | \item{coef_labels}{whether to label edges with coefficient values} 25 | 26 | \item{stand}{Should the coefficients being used be standardized coefficients} 27 | 28 | \item{stars}{a character vector indicating which parameters should include significance stars be included for regression paths, latent paths, or covariances. Include which of the 3 you want ("regress", "latent", "covs"), default is none.} 29 | 30 | \item{sig}{significance level for determining what significant paths are} 31 | } 32 | \value{ 33 | an edge data frame 34 | } 35 | \description{ 36 | Creates edge data frame and adds formatting 37 | } 38 | -------------------------------------------------------------------------------- /man/create_grviz.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/lavaanPlot2.R 3 | \name{create_grviz} 4 | \alias{create_grviz} 5 | \title{Creates the grViz dot language code for plotting} 6 | \usage{ 7 | create_grviz( 8 | model, 9 | labels = labels, 10 | include = include, 11 | graph_options = graph_options, 12 | node_options = node_options, 13 | edge_options = edge_options, 14 | stand = stand, 15 | ... 16 | ) 17 | } 18 | \arguments{ 19 | \item{model}{A model fit object of class lavaan.} 20 | 21 | \item{labels}{An optional named list of variable labels.} 22 | 23 | \item{include}{which parameters to include in the plot. Default is all regression and latent relationships. "covs" will also include covariances, while "all will also include error variances.} 24 | 25 | \item{graph_options}{a named list of graphviz graph attributes} 26 | 27 | \item{node_options}{a named list of graphviz node attributes} 28 | 29 | \item{edge_options}{a named list of graphviz edge attributes} 30 | 31 | \item{stand}{Should the coefficients being used be standardized coefficients} 32 | 33 | \item{...}{Additional arguments to be passed to \code{create_edges}} 34 | } 35 | \value{ 36 | A string specifying the path diagram for \code{model} 37 | } 38 | \description{ 39 | Creates the grViz dot language code for plotting 40 | } 41 | -------------------------------------------------------------------------------- /man/create_nodes.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/lavaanPlot2.R 3 | \name{create_nodes} 4 | \alias{create_nodes} 5 | \title{Creates node data frame and adds formatting} 6 | \usage{ 7 | create_nodes(coefs, labels = NULL, node_options) 8 | } 9 | \arguments{ 10 | \item{coefs}{a coefficient table from lavaan model created by \code{extract_coefs}} 11 | 12 | \item{labels}{An optional list of labels} 13 | 14 | \item{node_options}{a named list of graphviz node attributes, or a data frame of node options created by \code{formatting},} 15 | } 16 | \value{ 17 | an edge data frame 18 | } 19 | \description{ 20 | Creates node data frame and adds formatting 21 | } 22 | -------------------------------------------------------------------------------- /man/embed_plot_pdf.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plotExportFunctions.R 3 | \name{embed_plot_pdf} 4 | \alias{embed_plot_pdf} 5 | \title{Embeds a plot into an rmarkdown pdf} 6 | \usage{ 7 | embed_plot_pdf(plot, path, width = NULL, height = NULL) 8 | } 9 | \arguments{ 10 | \item{plot}{plot object created by \code{lavaanPlot}} 11 | 12 | \item{path}{Filename to save the image} 13 | 14 | \item{width}{width of image in pixels, NULL for default} 15 | 16 | \item{height}{height of image, NULL for default} 17 | } 18 | \value{ 19 | no return value calls \code{include_graphics} to embed plot in pdf 20 | } 21 | \description{ 22 | Embeds a plot into an rmarkdown pdf 23 | } 24 | \examples{ 25 | library(lavaan) 26 | model <- 'mpg ~ cyl + disp + hp 27 | qsec ~ disp + hp + wt' 28 | fit <- sem(model, data = mtcars) 29 | pl <- lavaanPlot(model = fit) 30 | \dontrun{ 31 | embed_plot_pdf(pl, "plot2.pdf") 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /man/extract_coefs.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/lavaanPlot2.R 3 | \name{extract_coefs} 4 | \alias{extract_coefs} 5 | \title{Creates a data frame of the parameter table from lavaan model} 6 | \usage{ 7 | extract_coefs(model, include = NULL, stand = FALSE) 8 | } 9 | \arguments{ 10 | \item{model}{A fitted model of class lavaan} 11 | 12 | \item{include}{which parameters to include in the plot. Default is all regression and latent relationships. "covs" will also include covariances, while "all" will also include error variances.} 13 | 14 | \item{stand}{Should the coefficients being used be standardized coefficients} 15 | } 16 | \value{ 17 | a data frame with lavaan model parameters 18 | } 19 | \description{ 20 | Creates a data frame of the parameter table from lavaan model 21 | } 22 | -------------------------------------------------------------------------------- /man/formatting.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/lavaanPlot2.R 3 | \name{formatting} 4 | \alias{formatting} 5 | \title{Enables conditional formatting for different parts of the model} 6 | \usage{ 7 | formatting(..., type, groups) 8 | } 9 | \arguments{ 10 | \item{...}{lists of node or edge options for each of the groups} 11 | 12 | \item{type}{type of conditional formatting being used, node, edge, or custom; custom only works with edges} 13 | 14 | \item{groups}{character vector of the names of custom groups, with nodes and edges default values are set and you need to match the order: for nodes: c("latent", "obs"), for edges: c("regress", "latent", "covs"). For custom groups of edges, you must match names that you pre-multiply with coefficients in your model specification.} 15 | } 16 | \value{ 17 | a formatting data frame that can work with the create_nodes and create_edges functions 18 | } 19 | \description{ 20 | Enables conditional formatting for different parts of the model 21 | } 22 | -------------------------------------------------------------------------------- /man/getNodes.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/lavaanPlot.R 3 | \name{getNodes} 4 | \alias{getNodes} 5 | \title{Extracts the paths from the lavaan model.} 6 | \usage{ 7 | getNodes(fit) 8 | } 9 | \arguments{ 10 | \item{fit}{A model fit object of class lavaan.} 11 | } 12 | \description{ 13 | Extracts the paths from the lavaan model. 14 | } 15 | -------------------------------------------------------------------------------- /man/lavaanPlot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/lavaanPlot.R 3 | \name{lavaanPlot} 4 | \alias{lavaanPlot} 5 | \title{Plots lavaan path model with DiagrammeR} 6 | \usage{ 7 | lavaanPlot(model, name = "plot", labels = NULL, ...) 8 | } 9 | \arguments{ 10 | \item{model}{A model fit object of class lavaan.} 11 | 12 | \item{name}{A string of the name of the plot.} 13 | 14 | \item{labels}{An optional named list of variable labels.} 15 | 16 | \item{...}{Additional arguments to be called to \code{buildCall} and \code{buildPaths}} 17 | } 18 | \value{ 19 | A Diagrammer plot of the path diagram for \code{model} 20 | } 21 | \description{ 22 | Plots lavaan path model with DiagrammeR 23 | } 24 | \examples{ 25 | library(lavaan) 26 | model <- 'mpg ~ cyl + disp + hp 27 | qsec ~ disp + hp + wt' 28 | fit <- sem(model, data = mtcars) 29 | lavaanPlot(model = fit, node_options = list(shape = "box", fontname = "Helvetica"), 30 | edge_options = list(color = "grey"), coefs = FALSE) 31 | } 32 | -------------------------------------------------------------------------------- /man/lavaanPlot2.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/lavaanPlot2.R 3 | \name{lavaanPlot2} 4 | \alias{lavaanPlot2} 5 | \title{Plots lavaan path model with DiagrammeR} 6 | \usage{ 7 | lavaanPlot2( 8 | model, 9 | labels = NULL, 10 | include = NULL, 11 | gr_viz = NULL, 12 | graph_options = NULL, 13 | node_options = NULL, 14 | edge_options = NULL, 15 | stand = FALSE, 16 | ... 17 | ) 18 | } 19 | \arguments{ 20 | \item{model}{A model fit object of class lavaan.} 21 | 22 | \item{labels}{An optional named list of variable labels.} 23 | 24 | \item{include}{which parameters to include in the plot. Default is all regression and latent relationships. "covs" will also include covariances, while "all will also include error variances.} 25 | 26 | \item{gr_viz}{pass a gr_viz model generated from \code{create_grviz} to create plot from that directly} 27 | 28 | \item{graph_options}{a named list of graphviz graph attributes} 29 | 30 | \item{node_options}{a named list of graphviz node attributes} 31 | 32 | \item{edge_options}{a named list of graphviz edge attributes} 33 | 34 | \item{stand}{Should the coefficients being used be standardized coefficients} 35 | 36 | \item{...}{Additional arguments to be passed to create_grviz for creating edges} 37 | } 38 | \value{ 39 | A Diagrammer plot of the path diagram for \code{model} 40 | } 41 | \description{ 42 | Plots lavaan path model with DiagrammeR 43 | } 44 | -------------------------------------------------------------------------------- /man/save_png.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plotExportFunctions.R 3 | \name{save_png} 4 | \alias{save_png} 5 | \title{Saves a plot as a png} 6 | \usage{ 7 | save_png(plot, path, width = NULL, height = NULL) 8 | } 9 | \arguments{ 10 | \item{plot}{plot object created by \code{lavaanPlot}} 11 | 12 | \item{path}{filename to save the image} 13 | 14 | \item{width}{width of image in pixels, NULL for default} 15 | 16 | \item{height}{height of image, NULL for default} 17 | } 18 | \value{ 19 | no return value saves plot as png 20 | } 21 | \description{ 22 | Saves a plot as a png 23 | } 24 | \examples{ 25 | library(lavaan) 26 | model <- 'mpg ~ cyl + disp + hp 27 | qsec ~ disp + hp + wt' 28 | fit <- sem(model, data = mtcars) 29 | pl <- lavaanPlot(model = fit) 30 | \dontrun{ 31 | save_png(pl, "plot.png") 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /man/sig_stars.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/lavaanPlot.R, R/lavaanPlot2.R 3 | \name{sig_stars} 4 | \alias{sig_stars} 5 | \title{Generates standard significance stars} 6 | \usage{ 7 | sig_stars(pvals) 8 | 9 | sig_stars(pvals) 10 | } 11 | \arguments{ 12 | \item{pvals}{a vector of p values} 13 | } 14 | \description{ 15 | Generates standard significance stars 16 | 17 | Generates standard significance stars 18 | } 19 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(lavaanPlot) 3 | 4 | test_check("lavaanPlot") 5 | -------------------------------------------------------------------------------- /vignettes/Conditional-Formatting.R: -------------------------------------------------------------------------------- 1 | ## ----setup, include = FALSE--------------------------------------------------- 2 | knitr::opts_chunk$set( 3 | collapse = TRUE, 4 | comment = "#>" 5 | ) 6 | 7 | library(lavaanPlot) 8 | library(lavaan) 9 | library(tidyverse) 10 | 11 | ## ----------------------------------------------------------------------------- 12 | HS.model <- ' visual =~ x1 + x2 + x3 13 | textual =~ x4 + x5 + x6 14 | speed =~ x7 + x8 + x9 15 | ' 16 | 17 | fit2 <- cfa(HS.model, data=HolzingerSwineford1939) 18 | summary(fit2) 19 | labels2 = c(visual = "Visual Ability", textual = "Textual Ability", speed = "Speed Ability") 20 | 21 | ## ----------------------------------------------------------------------------- 22 | lavaanPlot2(fit2, include = "covs", labels = labels2, 23 | graph_options = list(label = "my first graph with signficance stars"), 24 | node_options = list( fontname = "Helvetica"), 25 | edge_options = list(color = "grey"), 26 | stars = c("latent"), 27 | coef_labels = TRUE) 28 | 29 | 30 | ## ----------------------------------------------------------------------------- 31 | n_opts <- formatting(list(shape = "polygon", sides = "6", color = "orange"), list(shape = "polygon", sides = "8",color = "blue"), type = "node") 32 | 33 | lavaanPlot2(fit2, include = "covs", labels = labels2, 34 | graph_options = list(label = "my first graph with signficance stars"), 35 | node_options = n_opts, 36 | edge_options = list(color = "grey"), 37 | stars = c("latent"), 38 | coef_labels = TRUE) 39 | 40 | ## ----------------------------------------------------------------------------- 41 | e_opts <- formatting(list(color = "orange"),list(color = "red", penwidth = 6), list(color = "blue"), type = "edge") 42 | 43 | lavaanPlot2(fit2, include = "covs", labels = labels2, 44 | graph_options = list(label = "my first graph with signficance stars"), 45 | node_options = n_opts, 46 | edge_options = e_opts, 47 | stars = c("latent"), 48 | coef_labels = TRUE) 49 | 50 | ## ----------------------------------------------------------------------------- 51 | HS.model <- ' visual =~ A*x1 + x2 + x3 52 | textual =~ x4 + x5 + B*x6 53 | speed =~ x7 + x8 + x9 54 | ' 55 | 56 | fit2 <- cfa(HS.model, data=HolzingerSwineford1939) 57 | 58 | ## ----------------------------------------------------------------------------- 59 | c_opts <- formatting(list(color = "yellow", penwidth = 8), list(color = "blue", penwidth = 10), type = "custom", groups = c("A", "B")) 60 | 61 | lavaanPlot2(fit2, include = "covs", labels = labels2, 62 | graph_options = list(label = "my first graph with signficance stars"), 63 | node_options = n_opts, 64 | edge_options = list(e_opts, c_opts), 65 | stars = c("latent"), 66 | coef_labels = TRUE) 67 | 68 | -------------------------------------------------------------------------------- /vignettes/Conditional_Formatting.R: -------------------------------------------------------------------------------- 1 | ## ----setup, include = FALSE--------------------------------------------------- 2 | knitr::opts_chunk$set( 3 | collapse = TRUE, 4 | comment = "#>" 5 | ) 6 | 7 | library(lavaanPlot) 8 | library(lavaan) 9 | 10 | ## ----------------------------------------------------------------------------- 11 | HS.model <- ' visual =~ x1 + x2 + x3 12 | textual =~ x4 + x5 + x6 13 | speed =~ x7 + x8 + x9 14 | ' 15 | 16 | fit2 <- cfa(HS.model, data=HolzingerSwineford1939) 17 | summary(fit2) 18 | labels2 = c(visual = "Visual Ability", textual = "Textual Ability", speed = "Speed Ability") 19 | 20 | ## ----------------------------------------------------------------------------- 21 | lavaanPlot2(fit2, include = "covs", labels = labels2, 22 | graph_options = list(label = "my first graph with signficance stars"), 23 | node_options = list( fontname = "Helvetica"), 24 | edge_options = list(color = "grey"), 25 | stars = c("latent"), 26 | coef_labels = TRUE) 27 | 28 | 29 | ## ----------------------------------------------------------------------------- 30 | n_opts <- formatting(list(shape = "polygon", sides = "6", color = "orange"), list(shape = "polygon", sides = "8",color = "blue"), type = "node") 31 | 32 | lavaanPlot2(fit2, include = "covs", labels = labels2, 33 | graph_options = list(label = "my first graph with signficance stars"), 34 | node_options = n_opts, 35 | edge_options = list(color = "grey"), 36 | stars = c("latent"), 37 | coef_labels = TRUE) 38 | 39 | ## ----------------------------------------------------------------------------- 40 | e_opts <- formatting(list(color = "orange"),list(color = "red", penwidth = 6), list(color = "blue"), type = "edge") 41 | 42 | lavaanPlot2(fit2, include = "covs", labels = labels2, 43 | graph_options = list(label = "my first graph with signficance stars"), 44 | node_options = n_opts, 45 | edge_options = e_opts, 46 | stars = c("latent"), 47 | coef_labels = TRUE) 48 | 49 | ## ----------------------------------------------------------------------------- 50 | HS.model <- ' visual =~ A*x1 + x2 + x3 51 | textual =~ x4 + x5 + B*x6 52 | speed =~ x7 + x8 + x9 53 | ' 54 | 55 | fit2 <- cfa(HS.model, data=HolzingerSwineford1939) 56 | 57 | ## ----------------------------------------------------------------------------- 58 | c_opts <- formatting(list(color = "yellow", penwidth = 8), list(color = "blue", penwidth = 10), type = "custom", groups = c("A", "B")) 59 | 60 | lavaanPlot2(fit2, include = "covs", labels = labels2, 61 | graph_options = list(label = "my first graph with signficance stars"), 62 | node_options = n_opts, 63 | edge_options = list(e_opts, c_opts), 64 | stars = c("latent"), 65 | coef_labels = TRUE) 66 | 67 | -------------------------------------------------------------------------------- /vignettes/Conditional_Formatting.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Conditional Formatting" 3 | author: "Alex Lishinski" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Conditional Formatting} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | 12 | ```{r setup, include = FALSE} 13 | knitr::opts_chunk$set( 14 | collapse = TRUE, 15 | comment = "#>" 16 | ) 17 | 18 | library(lavaanPlot) 19 | library(lavaan) 20 | ``` 21 | 22 | As a part of the new improvements to the package, a feature that I've long wanted to add was conditional formatting. By conditional formatting, I mean formatting different parts of the plot differently, like perhaps changing the shape of only latent variable nodes, or changing the color of covariance edges separately from latent variable or regression edges. Well, I'm pleased to introduce this functionality into the package for version 0.8.0!! 23 | 24 | ## Conditional formatting in LavaanPlot 25 | 26 | Conditional formatting means applying different node or edge options to different groups of nodes or edges respectively. For the context of structural equation models there are some natural groupings of nodes and edges. For nodes it is often helpful to distinguish latent from observed values, and for edges it is often helpful to distinguish regression, latent, and covariance relationships. 27 | 28 | The way that I have implemented conditional formatting in `lavaanPlot` involves a new helper function called `formatting`. In the old version of the package, for both the original `lavaanPlot` and the new `lavaanPlot2`, formatting options were specified through the `node_options` and `edge_options` argument (through the `graph_options` argument too, but I won't discuss that here because it doesn't lend itself to conditional formatting). You would specify a named list of attribute-value pairs for these arguments to give your formatting choices, and these would apply to the whole graph. Not anymore. 29 | 30 | Now with the `formatting` helper function you can create sets of node and edge attributes for specific parts of the graph. You can do this for the natural groupings of nodes and edges mentioned below, and you can also do it for custom groupings of edges. 31 | 32 | ## `formatting` function 33 | 34 | The `formatting` function works as follows. You supply lists of formatting you want to apply to the portions of the graph, and you pass the resulting list to `lavaanPlot2`. 35 | 36 | There are a few main scenarios to think about. 37 | 38 | Here's a good example latent variable model: 39 | 40 | ```{r} 41 | HS.model <- ' visual =~ x1 + x2 + x3 42 | textual =~ x4 + x5 + x6 43 | speed =~ x7 + x8 + x9 44 | ' 45 | 46 | fit2 <- cfa(HS.model, data=HolzingerSwineford1939) 47 | summary(fit2) 48 | labels2 = c(visual = "Visual Ability", textual = "Textual Ability", speed = "Speed Ability") 49 | ``` 50 | 51 | And here's the old way of doing things without conditional formatting: 52 | 53 | ```{r} 54 | lavaanPlot2(fit2, include = "covs", labels = labels2, 55 | graph_options = list(label = "my first graph with signficance stars"), 56 | node_options = list( fontname = "Helvetica"), 57 | edge_options = list(color = "grey"), 58 | stars = c("latent"), 59 | coef_labels = TRUE) 60 | 61 | ``` 62 | 63 | ### Contitional formatting for nodes 64 | 65 | Now here's an example where we're separately customizing the formatting of the latent and observed variable nodes. The `formatting` function creates our differentiated formatting, and we specify that we're doing node formatting, so it then receives our formatting lists in order of latent, followed by observed variables. 66 | 67 | ```{r} 68 | n_opts <- formatting(list(shape = "polygon", sides = "6", color = "orange"), list(shape = "polygon", sides = "8",color = "blue"), type = "node") 69 | 70 | lavaanPlot2(fit2, include = "covs", labels = labels2, 71 | graph_options = list(label = "my first graph with signficance stars"), 72 | node_options = n_opts, 73 | edge_options = list(color = "grey"), 74 | stars = c("latent"), 75 | coef_labels = TRUE) 76 | ``` 77 | 78 | ### Conditional formatting for edges 79 | 80 | Here's an example with the node formatting, along with some differentiated edge formatting for the regression, latent, covariance groups. 81 | 82 | ```{r} 83 | e_opts <- formatting(list(color = "orange"),list(color = "red", penwidth = 6), list(color = "blue"), type = "edge") 84 | 85 | lavaanPlot2(fit2, include = "covs", labels = labels2, 86 | graph_options = list(label = "my first graph with signficance stars"), 87 | node_options = n_opts, 88 | edge_options = e_opts, 89 | stars = c("latent"), 90 | coef_labels = TRUE) 91 | ``` 92 | 93 | 94 | ### Conditional formatting for Custom sets of edges 95 | 96 | And finally we can add on another layer of edge formatting, on top of the standard groupings of edges used above, with our own custom selected edges, by specifying parameter labels in the model specification. To add labels, simply pre-multiply a text string with the name of the variable. 97 | 98 | ```{r} 99 | HS.model <- ' visual =~ A*x1 + x2 + x3 100 | textual =~ x4 + x5 + B*x6 101 | speed =~ x7 + x8 + x9 102 | ' 103 | 104 | fit2 <- cfa(HS.model, data=HolzingerSwineford1939) 105 | ``` 106 | 107 | Then we can specify a set of options for the custom parameter labels, and make a list of the two different sets of edge options. 108 | 109 | ```{r} 110 | c_opts <- formatting(list(color = "yellow", penwidth = 8), list(color = "blue", penwidth = 10), type = "custom", groups = c("A", "B")) 111 | 112 | lavaanPlot2(fit2, include = "covs", labels = labels2, 113 | graph_options = list(label = "my first graph with signficance stars"), 114 | node_options = n_opts, 115 | edge_options = list(e_opts, c_opts), 116 | stars = c("latent"), 117 | coef_labels = TRUE) 118 | ``` 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /vignettes/Improvements_to_lavaanPlot.R: -------------------------------------------------------------------------------- 1 | ## ----setup, include = FALSE--------------------------------------------------- 2 | # knitr::opts_chunk$set( 3 | # collapse = TRUE, 4 | # comment = "#>" 5 | # ) 6 | 7 | ## ----------------------------------------------------------------------------- 8 | library(lavaan) 9 | library(lavaanPlot) 10 | 11 | model <- 'mpg ~ cyl + disp + hp 12 | qsec ~ disp + hp + wt' 13 | 14 | fit <- sem(model, data = mtcars) 15 | summary(fit) 16 | 17 | HS.model <- ' visual =~ x1 + x2 + x3 18 | textual =~ x4 + x5 + x6 19 | speed =~ x7 + x8 + x9 20 | ' 21 | 22 | fit2 <- cfa(HS.model, data=HolzingerSwineford1939) 23 | summary(fit2) 24 | 25 | labels2 = c(visual = "Visual Ability", textual = "Textual Ability", speed = "Speed Ability") 26 | 27 | ## ----------------------------------------------------------------------------- 28 | lavaanPlot2(fit) 29 | 30 | ## ----------------------------------------------------------------------------- 31 | labels <- c(mpg = "Miles Per Gallon", cyl = "Cylinders", disp = "Displacement", hp = "Horsepower", qsec = "Speed", wt = "Weight") 32 | 33 | lavaanPlot2(fit, labels = labels) 34 | 35 | ## ----------------------------------------------------------------------------- 36 | lavaanPlot2(fit, labels = labels, graph_options = list(label = "my first graph", rankdir = "LR"), node_options = list( fontname = "Helvetica"), edge_options = list(color = "grey")) 37 | 38 | ## ----------------------------------------------------------------------------- 39 | lavaanPlot2(fit, include = "covs", labels = labels, graph_options = list(label = "Including covariates"), node_options = list( fontname = "Helvetica"), edge_options = list(color = "grey")) 40 | 41 | ## ----------------------------------------------------------------------------- 42 | lavaanPlot2(fit, include = "all", labels = labels, graph_options = list(label = "including error variances"), node_options = list( fontname = "Helvetica"), edge_options = list(color = "grey")) 43 | 44 | ## ----------------------------------------------------------------------------- 45 | lavaanPlot2(fit, include = "covs", coef_labels = TRUE, labels = labels, graph_options = list(label = "including coefficient labels"), node_options = list(fontname = "Helvetica"), edge_options = list(color = "grey")) 46 | 47 | ## ----------------------------------------------------------------------------- 48 | lavaanPlot2(fit, include = "covs", labels = labels, graph_options = list(label = "my first graph with significance stars"), node_options = list( fontname = "Helvetica"), edge_options = list(color = "grey"), stars = c("regress"), coef_labels = TRUE) 49 | 50 | ## ----------------------------------------------------------------------------- 51 | lavaanPlot2(fit2, include = "covs", labels = labels2, graph_options = list(label = "my first graph with signficance stars"), node_options = list( fontname = "Helvetica"), edge_options = list(color = "grey"), stars = c("latent"), coef_labels = TRUE) 52 | 53 | ## ----------------------------------------------------------------------------- 54 | lavaanPlot2(fit2, include = "covs", labels = labels2, graph_options = list(label = "my first graph, which is being used to illustrate how to use the new code in the lavaanPlot package"), node_options = list( fontname = "Helvetica"), edge_options = list(color = "grey"), stars = c("covs"), coef_labels = TRUE) 55 | 56 | -------------------------------------------------------------------------------- /vignettes/Improvements_to_lavaanPlot.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Improvements to lavaanPlot" 3 | author: "Alex Lishinski" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Improvements to lavaanPlot} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | 12 | ```{r setup, include = FALSE} 13 | # knitr::opts_chunk$set( 14 | # collapse = TRUE, 15 | # comment = "#>" 16 | # ) 17 | ``` 18 | 19 | I've been working on some improvements to the lavaanPlot package, in order to take advantage of updates to the diagrammeR package. 20 | 21 | I'll spare you all the details, but diagrammeR has introduced a way of building graph plots using node and edge defining dataframes, which enable a more extensible way of customizing plots. I am trying to bring the advantages of this flexibility to the `lavaanPlot` package to enable more customization. The old way that the package was set up is solid, but it's difficult to add new features, and the goal of the new approach is to unlock the full customization options that the graphViz software and the DOT language have to offer. 22 | 23 | I've tried to keep things from the old approach to the extent that I could, but there are some new elements of the user interface for this new version of the package. I'm not finished with everything I set out to accomplish yet, but I'm writing this vignette to introduce the new version of the package so people can give it a try and find issues that I can fix. I'm releasing this as version 0.7.0, with the goal of fixing issues and fully fleshing out the functionality that I'd like the package to have over a couple more iterations of the package to get ready for a fully matured 1.0.0 release, where hopefully then I can fully deprecate the old code. 24 | 25 | Here are some examples with the new code, the function being called `lavaanPlot2`. 26 | 27 | Starting with a basic model using `mtcars` which only contains observed variable relationships and no latent variable relationships. 28 | 29 | ```{r} 30 | library(lavaan) 31 | library(lavaanPlot) 32 | 33 | model <- 'mpg ~ cyl + disp + hp 34 | qsec ~ disp + hp + wt' 35 | 36 | fit <- sem(model, data = mtcars) 37 | summary(fit) 38 | 39 | HS.model <- ' visual =~ x1 + x2 + x3 40 | textual =~ x4 + x5 + x6 41 | speed =~ x7 + x8 + x9 42 | ' 43 | 44 | fit2 <- cfa(HS.model, data=HolzingerSwineford1939) 45 | summary(fit2) 46 | 47 | labels2 = c(visual = "Visual Ability", textual = "Textual Ability", speed = "Speed Ability") 48 | ``` 49 | 50 | You can still plot the model using no additional options: 51 | 52 | ```{r} 53 | lavaanPlot2(fit) 54 | ``` 55 | 56 | You can still add labels to the plot with the `labels` argument, although it now uses a named character vector instead of a list: 57 | 58 | ```{r} 59 | labels <- c(mpg = "Miles Per Gallon", cyl = "Cylinders", disp = "Displacement", hp = "Horsepower", qsec = "Speed", wt = "Weight") 60 | 61 | lavaanPlot2(fit, labels = labels) 62 | ``` 63 | 64 | Graph options, node options, and edge options are supplied via named lists, as previously: 65 | 66 | ```{r} 67 | lavaanPlot2(fit, labels = labels, graph_options = list(label = "my first graph", rankdir = "LR"), node_options = list( fontname = "Helvetica"), edge_options = list(color = "grey")) 68 | ``` 69 | 70 | A change to the interface is how one can indicate which model paths to include in the plot, using the `include` argument. The default option will include just regression and latent variable relationships, `include = covs` will include model covariances, whereas `include = all` will also include error variances. 71 | 72 | ```{r} 73 | lavaanPlot2(fit, include = "covs", labels = labels, graph_options = list(label = "Including covariates"), node_options = list( fontname = "Helvetica"), edge_options = list(color = "grey")) 74 | ``` 75 | 76 | ```{r} 77 | lavaanPlot2(fit, include = "all", labels = labels, graph_options = list(label = "including error variances"), node_options = list( fontname = "Helvetica"), edge_options = list(color = "grey")) 78 | ``` 79 | 80 | Coefficient labels can still be included on the edges, and selectively for the different parts of the plot, using the `coef_lablels` argument: 81 | 82 | ```{r} 83 | lavaanPlot2(fit, include = "covs", coef_labels = TRUE, labels = labels, graph_options = list(label = "including coefficient labels"), node_options = list(fontname = "Helvetica"), edge_options = list(color = "grey")) 84 | ``` 85 | 86 | And significance stars can be added to these coefficient labels using the stars argument, just as with `lavaanPlot`: 87 | 88 | ```{r} 89 | lavaanPlot2(fit, include = "covs", labels = labels, graph_options = list(label = "my first graph with significance stars"), node_options = list( fontname = "Helvetica"), edge_options = list(color = "grey"), stars = c("regress"), coef_labels = TRUE) 90 | ``` 91 | 92 | ```{r} 93 | lavaanPlot2(fit2, include = "covs", labels = labels2, graph_options = list(label = "my first graph with signficance stars"), node_options = list( fontname = "Helvetica"), edge_options = list(color = "grey"), stars = c("latent"), coef_labels = TRUE) 94 | ``` 95 | 96 | ```{r} 97 | lavaanPlot2(fit2, include = "covs", labels = labels2, graph_options = list(label = "my first graph, which is being used to illustrate how to use the new code in the lavaanPlot package"), node_options = list( fontname = "Helvetica"), edge_options = list(color = "grey"), stars = c("covs"), coef_labels = TRUE) 98 | ``` 99 | 100 | The next stage of development is to allow for subset formatting, where different formatting is applied to sets of nodes or edges. The most obvious cases for this are to allow different formatting for the sets of latent vs observed nodes, and the regression, latent, covariance, and error variance edges. Ideally though I want to enable users to be able to apply different formatting to arbitrary subsets of nodes or edges as they see fit. 101 | -------------------------------------------------------------------------------- /vignettes/Intro_to_lavaanPlot.R: -------------------------------------------------------------------------------- 1 | ## ----------------------------------------------------------------------------- 2 | library(lavaan) 3 | library(lavaanPlot) 4 | 5 | model <- 'mpg ~ cyl + disp + hp 6 | qsec ~ disp + hp + wt' 7 | 8 | fit <- sem(model, data = mtcars) 9 | summary(fit) 10 | 11 | ## ----------------------------------------------------------------------------- 12 | lavaanPlot(model = fit, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = FALSE) 13 | 14 | ## ----------------------------------------------------------------------------- 15 | labels <- list(mpg = "Miles Per Gallon", cyl = "Cylinders", disp = "Displacement", hp = "Horsepower", qsec = "Speed", wt = "Weight") 16 | 17 | lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = FALSE) 18 | 19 | ## ----------------------------------------------------------------------------- 20 | HS.model <- ' visual =~ x1 + x2 + x3 21 | textual =~ x4 + x5 + x6 22 | speed =~ x7 + x8 + x9 23 | ' 24 | 25 | fit <- cfa(HS.model, data=HolzingerSwineford1939) 26 | 27 | lavaanPlot(model = fit, edge_options = list(color = "grey")) 28 | 29 | ## ----------------------------------------------------------------------------- 30 | model <- 'mpg ~ cyl + disp + hp 31 | qsec ~ disp + hp + wt' 32 | 33 | fit <- sem(model, data = mtcars) 34 | summary(fit) 35 | 36 | lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE) 37 | 38 | ## ----------------------------------------------------------------------------- 39 | # significant standardized paths only 40 | lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, sig = .05) 41 | 42 | ## ----------------------------------------------------------------------------- 43 | # All paths unstandardized 44 | lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, stand = TRUE) 45 | 46 | ## ----------------------------------------------------------------------------- 47 | HS.model <- ' visual =~ x1 + x2 + x3 48 | textual =~ x4 + x5 + x6 49 | speed =~ x7 + x8 + x9 50 | ' 51 | 52 | fit <- cfa(HS.model, data=HolzingerSwineford1939) 53 | 54 | labels = list(visual = "Visual Ability", textual = "Textual Ability", speed = "Speed Ability") 55 | 56 | # Show coefs 57 | lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE) 58 | 59 | # Significant paths 60 | lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, sig = .05) 61 | 62 | # All paths standardized 63 | lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, stand = TRUE) 64 | 65 | ## ----------------------------------------------------------------------------- 66 | HS.model <- ' visual =~ x1 + x2 + x3 67 | textual =~ x4 + x5 + x6 68 | speed =~ x7 + x8 + x9 69 | ' 70 | 71 | fit <- cfa(HS.model, data=HolzingerSwineford1939) 72 | 73 | labels = list(visual = "Visual Ability", textual = "Textual Ability", speed = "Speed Ability") 74 | 75 | # significant standardized paths only 76 | lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE) 77 | 78 | ## ----------------------------------------------------------------------------- 79 | lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = "covs") 80 | 81 | lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = "latent") 82 | 83 | ## ----------------------------------------------------------------------------- 84 | lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = TRUE, digits = 1) 85 | 86 | ## ----------------------------------------------------------------------------- 87 | lavaanPlot(model = fit, labels = labels, graph_options = list(rankdir = "LR"), node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = TRUE, digits = 1) 88 | 89 | ## ----------------------------------------------------------------------------- 90 | lavaanPlot(model = fit, labels = labels, graph_options = list(rankdir = "RL"), node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = TRUE, digits = 1) 91 | 92 | ## ----------------------------------------------------------------------------- 93 | lavaanPlot(model = fit, labels = labels, graph_options = list(rankdir = "BT"), node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = TRUE, digits = 1) 94 | 95 | ## ----------------------------------------------------------------------------- 96 | lavaanPlot(model = fit, labels = labels, graph_options = list(layout = "neato"), node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = TRUE, digits = 1) 97 | 98 | ## ----------------------------------------------------------------------------- 99 | lavaanPlot(model = fit, labels = labels, graph_options = list(layout = "circo"), node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = TRUE, digits = 1) 100 | 101 | ## ----------------------------------------------------------------------------- 102 | lavaanPlot(model = fit, labels = labels, graph_options = list(layout = "twopi"), node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = TRUE, digits = 1) 103 | 104 | -------------------------------------------------------------------------------- /vignettes/Intro_to_lavaanPlot.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Intro to lavaanPlot" 3 | author: "Alex Lishinski" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Intro to lavaanPlot} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | 12 | ## Introduction 13 | 14 | The lavaan package is an excellent package for structural equation models, and the DiagrammeR package is an excellent package for producing nice looking graph diagrams. As of right now, the lavaan package has no built in plotting functions for models, and the available options from external packages don't look as nice and aren't as easy to use as DiagrammeR, in my opinion. Of course, you can use DiagrammeR to build path diagrams for your models, but it requires you to build the diagram specification manually. This package exists to streamline that process, allowing you to plot your lavaan models directly, without having to translate them into the DOT language specification that DiagrammeR uses. 15 | 16 | ## Package example 17 | 18 | The package is very straightforward to use, simply call the `lavaanPlot` function with your lavaan model, adding whatever graph, node and edge attributes you want as a named list (graph attributes are specified as a standard default value that shows you what the other attribute lists should look like). For your reference, the available attributes can be found here: 19 | 20 | https://rich-iannone.github.io/DiagrammeR/graphviz_and_mermaid.html#node-attributes 21 | https://rich-iannone.github.io/DiagrammeR/graphviz_and_mermaid.html#edge-attributes 22 | 23 | Here's a quick example using the `mtcars` data set. 24 | 25 | First fit your lavaan model. The package supports plotting lavaan regression relationships and latent variable - indicator relationships. 26 | 27 | ```{r} 28 | library(lavaan) 29 | library(lavaanPlot) 30 | 31 | model <- 'mpg ~ cyl + disp + hp 32 | qsec ~ disp + hp + wt' 33 | 34 | fit <- sem(model, data = mtcars) 35 | summary(fit) 36 | ``` 37 | 38 | Then using that model fit object, simply call the `lavaanPlot` function, specifying your desired graph parameters. 39 | 40 | ```{r} 41 | lavaanPlot(model = fit, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = FALSE) 42 | ``` 43 | ## Plot customization options 44 | 45 | You can also specify different variable labels using the a named list and the `labels` argument. 46 | 47 | ```{r} 48 | labels <- list(mpg = "Miles Per Gallon", cyl = "Cylinders", disp = "Displacement", hp = "Horsepower", qsec = "Speed", wt = "Weight") 49 | 50 | lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = FALSE) 51 | ``` 52 | 53 | An example showing latent variable relationships: 54 | 55 | ```{r} 56 | HS.model <- ' visual =~ x1 + x2 + x3 57 | textual =~ x4 + x5 + x6 58 | speed =~ x7 + x8 + x9 59 | ' 60 | 61 | fit <- cfa(HS.model, data=HolzingerSwineford1939) 62 | 63 | lavaanPlot(model = fit, edge_options = list(color = "grey")) 64 | ``` 65 | 66 | You can label the plot edges with the coefficient values using `coefs = TRUE`. 67 | 68 | ```{r} 69 | model <- 'mpg ~ cyl + disp + hp 70 | qsec ~ disp + hp + wt' 71 | 72 | fit <- sem(model, data = mtcars) 73 | summary(fit) 74 | 75 | lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE) 76 | ``` 77 | 78 | By default it will show all paths, but you can also specify whatever significance level you want using the `sig` argument to only show significant paths. 79 | 80 | ```{r} 81 | # significant standardized paths only 82 | lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, sig = .05) 83 | ``` 84 | 85 | You can also show standardized paths only with the `stand` argument. 86 | 87 | ```{r} 88 | # All paths unstandardized 89 | lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, stand = TRUE) 90 | ``` 91 | 92 | Same works for latent variable loadings 93 | 94 | ```{r} 95 | HS.model <- ' visual =~ x1 + x2 + x3 96 | textual =~ x4 + x5 + x6 97 | speed =~ x7 + x8 + x9 98 | ' 99 | 100 | fit <- cfa(HS.model, data=HolzingerSwineford1939) 101 | 102 | labels = list(visual = "Visual Ability", textual = "Textual Ability", speed = "Speed Ability") 103 | 104 | # Show coefs 105 | lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE) 106 | 107 | # Significant paths 108 | lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, sig = .05) 109 | 110 | # All paths standardized 111 | lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, stand = TRUE) 112 | ``` 113 | 114 | You can also include double-sided edges to represent model covariances if you want: 115 | 116 | ```{r} 117 | HS.model <- ' visual =~ x1 + x2 + x3 118 | textual =~ x4 + x5 + x6 119 | speed =~ x7 + x8 + x9 120 | ' 121 | 122 | fit <- cfa(HS.model, data=HolzingerSwineford1939) 123 | 124 | labels = list(visual = "Visual Ability", textual = "Textual Ability", speed = "Speed Ability") 125 | 126 | # significant standardized paths only 127 | lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE) 128 | ``` 129 | 130 | You can include significance stars as well using the `stars` option. 131 | You can choose stars for regression paths, latent paths, or covariances. Specify which of the 3 you want ("regress", "latent", "covs"). 132 | 133 | ```{r} 134 | lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = "covs") 135 | 136 | lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = "latent") 137 | ``` 138 | You can change the number of decimal places in the coefficient value labels as well with the `digits` option. 139 | 140 | ```{r} 141 | lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = TRUE, digits = 1) 142 | ``` 143 | 144 | ## Graph Options 145 | 146 | ### Orientations with `rankdir` 147 | 148 | You can also do additional options to modify the layout of your plots in certain ways. 149 | 150 | The graph option `rankdir` allows you to change the overall orientation of the plot between TB (top-bottom; default), BT (bottom-top), RL (right-left) and LR (left-right): 151 | 152 | ```{r} 153 | lavaanPlot(model = fit, labels = labels, graph_options = list(rankdir = "LR"), node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = TRUE, digits = 1) 154 | ``` 155 | 156 | ```{r} 157 | lavaanPlot(model = fit, labels = labels, graph_options = list(rankdir = "RL"), node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = TRUE, digits = 1) 158 | ``` 159 | 160 | 161 | 162 | ```{r} 163 | lavaanPlot(model = fit, labels = labels, graph_options = list(rankdir = "BT"), node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = TRUE, digits = 1) 164 | ``` 165 | ### Layouts with `layout` 166 | 167 | The graph option `layout` allows you to change the layout engine used to generate the plot between dot (the default), neato, circo, twopi, plus some others, see: https://graphviz.org/docs/layouts/. Your mileage may vary as to whether any of these work for a given graph. 168 | 169 | ```{r} 170 | lavaanPlot(model = fit, labels = labels, graph_options = list(layout = "neato"), node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = TRUE, digits = 1) 171 | ``` 172 | 173 | ```{r} 174 | lavaanPlot(model = fit, labels = labels, graph_options = list(layout = "circo"), node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = TRUE, digits = 1) 175 | ``` 176 | 177 | ```{r} 178 | lavaanPlot(model = fit, labels = labels, graph_options = list(layout = "twopi"), node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = TRUE, digits = 1) 179 | ``` 180 | -------------------------------------------------------------------------------- /vignettes/Save_and_embed.R: -------------------------------------------------------------------------------- 1 | ## ----setup, include = FALSE, eval = FALSE------------------------------------- 2 | # library(lavaan) 3 | # library(lavaanPlot) 4 | # library(rsvg) 5 | # library(magrittr) 6 | # library(DiagrammeRsvg) 7 | 8 | ## ---- eval = FALSE------------------------------------------------------------ 9 | # model <- 'mpg ~ cyl + disp + hp 10 | # qsec ~ disp + hp + wt' 11 | # 12 | # fit <- sem(model, data = mtcars) 13 | # 14 | # pl <- lavaanPlot(model = fit) 15 | # 16 | # # Example for pdf embed 17 | # embed_plot_pdf(pl, "plot2.pdf", width = 500) 18 | # 19 | # # Example for saving to .png 20 | # save_png(pl, "plot.png", width = 500) 21 | 22 | -------------------------------------------------------------------------------- /vignettes/Save_and_embed.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "lavaanPlot: Saving and Embedding Plots" 3 | author: "Alex Lishinski" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{lavaanPlot: Saving and Embedding Plots} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | 12 | ```{r setup, include = FALSE, eval = FALSE} 13 | library(lavaan) 14 | library(lavaanPlot) 15 | library(rsvg) 16 | library(magrittr) 17 | library(DiagrammeRsvg) 18 | ``` 19 | 20 | Functions for embedding plots in Rmarkdown pdfs and for saving plots as pngs 21 | 22 | 23 | `embed_plot_pdf()` saves your plot as a pdf image and then inserts that image into the pdf when you render Rmardown doc. 24 | 25 | `save_png()` as the name suggests, saves your plot as a png image in the local directory (or wherever you tell it to). 26 | 27 | ```{r, eval = FALSE} 28 | model <- 'mpg ~ cyl + disp + hp 29 | qsec ~ disp + hp + wt' 30 | 31 | fit <- sem(model, data = mtcars) 32 | 33 | pl <- lavaanPlot(model = fit) 34 | 35 | # Example for pdf embed 36 | embed_plot_pdf(pl, "plot2.pdf", width = 500) 37 | 38 | # Example for saving to .png 39 | save_png(pl, "plot.png", width = 500) 40 | ``` 41 | 42 | Now having saved the image, it can be embedded in the document with `![saved plot](plot.png)` 43 | 44 | 45 | ![saved plot](plot.png) 46 | -------------------------------------------------------------------------------- /vignettes/plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alishinski/lavaanPlot/9ed0816d678e145450ca1dd534ca9a4140961dfe/vignettes/plot.png -------------------------------------------------------------------------------- /vignettes/unnamed-chunk-3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alishinski/lavaanPlot/9ed0816d678e145450ca1dd534ca9a4140961dfe/vignettes/unnamed-chunk-3-1.png --------------------------------------------------------------------------------