Learn R Programming

semPlot (version 1.0.1)

semPaths: Plot path diagram for SEM models.

Description

This function creates a path diagram of a SEM model (or general linear model), which is then plotted using qgraph. Currently many different SEM programs and packages are supported. Please see my website (www.sachaepskamp.com) for more details on which packages are supported and what is supported for each package.

Usage

semPaths(object, what = "paths", whatLabels, style, layout = "tree", 
  intercepts = TRUE, residuals = TRUE, thresholds = TRUE, intStyle = "multi", 
  rotation = 1, curve, curvature = 1, nCharNodes = 3, nCharEdges = 3, sizeMan = 5,
   sizeLat = 8,  sizeInt = 2, sizeMan2, sizeLat2, sizeInt2, shapeMan, shapeLat, 
  shapeInt = "triangle", ask, mar, title, title.color = "black", title.adj = 0.1, 
  title.line = -1, title.cex = 0.8, include, combineGroups = FALSE, manifests, 
  latents, groups, color, residScale, gui = FALSE, allVars = FALSE, edge.color, 
  reorder = TRUE, structural = FALSE, ThreshAtSide = FALSE, thresholdColor, 
  thresholdSize = 0.5, fixedStyle = 2, freeStyle = 1, 
  as.expression = character(0), optimizeLatRes = FALSE, inheritColor = TRUE, 
  levels, nodeLabels, edgeLabels, pastel = FALSE, rainbowStart = 0, intAtSide, 
  springLevels = FALSE, nDigits = 2, exoVar, exoCov = TRUE, centerLevels = TRUE, 
  panelGroups = FALSE, layoutSplit = FALSE, measurementLayout = "tree", subScale, 
  subScale2, subRes = 4, subLinks, modelOpts = list(), curveAdjacent = '<->', 
  edge.label.cex = 0.6,  cardinal = "none", equalizeManifests = FALSE, 
  covAtResiduals = TRUE, bifactor, optimPoints = 1:8 * (pi/4), ...)

Arguments

object
A "semPlotModel" object or any of the input types that can be used in semPlotModel directly.
what
What should the edges indicate in the path diagram? This function uses grepl to allow fuzzy matching and is not case sensitive. E.g., par will also match Parameters. [object Object
whatLabels
What should the edge labels indicate in the path diagram? This function uses grepl to allow fuzzy matching and is not case sensitive. E.g., par will also match Parameters. Default de
style
The style to use. Currently only indicates what the (residual) variances look like. Use "ram", "mx" or "OpenMx" for double headed selfloops and "lisrel" for single headed edges with no node as origin. De
layout
A string indicating how the nodes should be placed. Similar to the 'layout' argument in qgraph. Can be one of the following strings. [object Object],[object Object],[object Object],[object Object],[o
intercepts
Logical, should intercepts be included in the path diagram?
residuals
Logical, should residuals (and variances) be included in the path diagram?
thresholds
Logical, should thresholds be included in the path diagram?
intStyle
Style of the intercepts. "multi" plots a separate unit vector node for each intercept and "single" plots a single unit vector node. Currently, "single" is not well supported and might lead to unexpected results.
rotation
An integer indicating the rotation of the layout when "tree" or "tree2" layout is used. 1, 2, 3 and 4 indicate that exogenous variables are placed at the top, left side, bottom and right side respectively.
curve
The curvature of the edges. In tree layouts this argument only curves the edges that are between nodes on the same level. e.g., correlations between exogenous manifest variables.
curvature
Sets the strength of scaling in curvature for curved edges at the same horizontal level in tree layouts. The curve will be set to curve + curvature * n / max(n), where n is the number of nodes in between the two connected nodes.
nCharNodes
Number of characters to abbreviate node labels to (using abbreviate). Set to 0 to omit abbreviation.
nCharEdges
Number of characters to abbreviate edge labels to (using abbreviate). Set to 0 to omit abbreviation.
sizeMan
Width of the manifest nodes, sent to the 'vsize' argument in qgraph.
sizeLat
Width of the latent nodes, sent to the 'vsize' argument in qgraph.
sizeInt
Width of the unit vector nodes, sent to the 'vsize' argument in qgraph.
sizeMan2
Height of the manifest nodes, sent to the 'vsize2' argument in qgraph.
sizeLat2
Height of the latent nodes, sent to the 'vsize2' argument in qgraph.
sizeInt2
Height of the unit vector nodes, sent to the 'vsize2' argument in qgraph.
shapeMan
Shape of the manifest nodes, sent to the 'shape' argument in qgraph. Defaults to "square" or "rectangle" if width and height differ.
shapeLat
Shape of the latent nodes, sent to the 'shape' argument in qgraph. Defaults to "circle" or "ellipse" if width and height differ.
shapeInt
Shape of the constant nodes, sent to the 'shape' argument in qgraph. Defaults to "triangle".
ask
Specifies the 'ask' parameter in par. Defaults to TRUE if multiple groups are in the model.
mar
Same as the 'mar' argument in qgraph. By default this argument is based on the values of 'rotation', 'style' and 'title'.
title
Logical, should titles be plotted of the group names above each plot?
title.color
Color of the titles.
title.adj
Adjustment of title as used by 'adj' in par.
title.line
Line of title as used by 'line' in title.
title.cex
Size of title as used by 'cex.main' in par.
include
Integer vector indicating which groups should be included in the output. e.g., to only plot a diagram for the first group use include = 1.
combineGroups
Logical. If TRUE all groups are combined in the same path diagram.
manifests
A character vector in which every element is the name of a manifest variable in the model. This argument can be used to overwrite the order in which nodes are plotted in the graph if reorder = FALSE
latents
A character vector in which every element is the name of a latent variable in the model. This argument can be used to overwrite the order in which nodes are plotted in the graph if reorder = FALSE
groups
Groups nodes that should be colored the same, similar to the 'groups' argument in qgraph with a few exceptions. Should be a list containing in each element the names (instead of numbers as in qgraph) o
color
Controls the color of nodes. Similar to 'color' in qgraph. A color vector indicating the color for each group, a single color character indicating the color for all nodes or a color vector indicating t
residScale
The size of residual edges if style = "lisrel". Defaults to two times the value of 'sizeMan'.
gui
Not yet implemented.
allVars
Logical. If TRUE all variables are plotted in the path diagrams for each group. If FALSE only variables are plotted that are used in the group.
edge.color
A value indicating the color of all edges or a vector indicating the color of each edge. Useful for manually overwriting edge colors.
reorder
Logical. Should manifest variables be reordered to be near latent factors they are most connected to in the "tree" layout? If FALSE manifest variables are placed in the order they appear in the Pars.
structural
Logical. Set this to FALSE to only show the structural model (omit all manifest variables.)
ThreshAtSide
Logical. If TRUE, thresholds are plotted as small lines at the side of manifest nodes, otherwise they are plotted as lines inside the nodes.
thresholdColor
Color of the threshold lines. Defaults to "black"
thresholdSize
Size of threshold bars relative to the size of the node.
fixedStyle
A vector of length one or two specifying the color and line type (same as 'lty' in par) of fixed parameters. Can be both character and numeric. If one of the elements encodes a color it is used to overw
freeStyle
Same as 'fixedStyle' but for free parameters instead.
as.expression
A character vector indicating which labels should be treated as an expression, so that mathematical notation and Greek letters can be used in the path diagram. If this vector contains "nodes"
optimizeLatRes
Logical. If this is TRUE, the angle of the incoming residuals on latent variables is attempted to be optimally chosen so its position conflicts with the least amount of connected edges.
inheritColor
Logical, should uncolored nodes obtain a mix of connected colored nodes? Defaults to TRUE.
levels
A numeric vector usually of length 4. Controls the relative vertical position of variable levels (exogenous and endogenous latents and manifests) under default rotation in tree and circle layouts. This can be used to control the spacing between these leve
nodeLabels
A vector or list to manually overwrite the node labels. Can include expressions.
edgeLabels
A vector or list to manually overwrite the edge labels. Can include expressions.
pastel
Logical, should default colors (for groups or edge equality constraints) be chosen from pastel colors? If TRUE then rainbow_hcl is used.
rainbowStart
A number between 0 and 1 indicating the offset used in rainbow functions for default node coloring.
exoVar
Should variances of truely exogenous variables (no incomming directed edge) be plotted? Defaults to TRUE unless style = "lisrel".
intAtSide
Logical to control if intercepts should be plotted to the side of manifest nodes or at the bottom/top. Defaults only to FALSE if 'residuals=FALSE'.
springLevels
Logical indicating if the placement on horizontal levels with tree3 layout should be determined by a force embedded algorithm.
nDigits
Number of digits to round numeric values to.
exoCov
Should covariances between truely exogenous variables (no incomming directed edge) be plotted? Defaults to TRUE.
centerLevels
Only used if layout is set to "tree2", should each level be centered? Defaults to TRUE
panelGroups
Logical to automatically create a panel plot of multiple group models. Defaults to FALSE.
layoutSplit
Logical that can be used to split computing of layout between structural and measurment models. This is very useful in more complicated models where the structural part is best shown by using a spring layout.
measurementLayout
Logical indicating the layout algorithm to use for measurement models if layoutSplit = TRUE (the structural model will obtain a layout given by the layout argument).
subScale
Width of submodels (measurment models) if layoutSplit = TRUE.
subScale2
Height of submodels (measurment models) if layoutSplit = TRUE.
subRes
Integer indicating the resolution of which measurment models can be rotated around their corresponding latent variable. The default, 4, indicates that they can be placed only to polar coordinates. Set to 360 to allow every angle of rotation.
subLinks
Vector of variables to link to. Currently not well supported so avoid using this argument.
modelOpts
A lists containing arguments sent to semPlotModel in case the input is not of class semPlotModel.
curveAdjacent
What edges between adjacent horizontal nodes be curved? Can be '<->' or 'cov' to indicate bidirectional covariances, '->' or 'reg' for directed regressions or a vector containing both.
edge.label.cex
Controls the font size of the edge labels. Same as in qgraph except that the default is now 0.8.
cardinal
Should edges in a tree layout connect to the four cardinal points of one of the borders of the node rather than point to the center of the node? Can be set to TRUE or "all" to enamble this behavior for all edges and FALSE
equalizeManifests
Logical. Should the distances between manifest nodes in the tree1 layout be equalized? Defaults to TRUE
covAtResiduals
Logical, should covariances be drawn at the start of residuals when style="lisrel" is used? Defaults to TRUE.
bifactor
A string vector containing the name(s) of the general bifactor(s). This will automatically create a bifactor plot.
optimPoints
A vector of radians residuals can optimize to if optimizeLatRes = TRUE
...
Arguments sent to the qgraph function. These arguments can further control the output of the graph. Some usefull arguments in drawing path diagrams are: [object Object],[object Object],[object Object

Value

  • A "qgraph" object as returned by qgraph. This object can be used to alter the graph (such as manually redefining the layout) and to plot the graph again with different arguments.

    If there are multiple groups a list is returned with a "qgraph" object for each path diagram that has been produced.

Details

The default "tree" layout under default rotation places the nodes in one of four horizontal levels. At the top the exogenous manifest variables, under that the exogenous latent variables, under that the endogenous latent variables and at the bottom the endogenous manifest variables. If one of these kinds of variables does not exist its level is omitted. Afterwards, the rotation argument will rotate the graph and the "circle" layout will make the layout circular using these levels as nested circles.

If not manually set (see semPlotModel-edit), semPath will automatically try to set the endogenous and exogenous variables, such that the resulting layout looks good. A latent variable is identified as exogenous if it is not on the right hand side of a directed edge (-> or ~>) with another latent variable as node of origin. A manifest variable is set as exogenous if it is only connected, in any way, to exogenous latent variables and if it is not the right hand side (dependent variable) of a regression edge (~>). If all variables are set to exogenous this way, they are all set to endogenous for consistency in the layouts. Afterwards, manifest variables only used in formative measurement models (only outgoing directed edges to latents) are set to exogenous again so that MIMIC models are displayed properly.

Intercepts are placed on the same level as the variable, either on the left or right side of the node (pointing outward from the center). Residuals for manifest variables are placed at the top or bottom (for exogenous and endogenous manifests respectively). Residuals of latents are placed at the bottom or top respectively for exogenous and endogenous variables, but is switched if the latent is not connected to a manifest. Residuals for the leftmost and rightmost latent are placed at the left and right side respectively, or diagonal if the latent is connected to an intercept.

The "tree2" and "circle2" layouts call the layout.reingold.tilford function from the igraph package. As roots are used the first available variables of the following list:

  • Intercepts of exogenous manifests
  • Exogenous manifest
  • Intercepts of exogenous latents
  • Exogenous latents
  • Interceots of endogenous latents
  • Endogenous latents
  • Intercepts of endogenous manifests
  • The endogenous manifest with the most outgoing edges (this should not be possible by default, but can be manually set)
  • The most connected endogenous manigest.
To compute an optimal layout layout.reingold.tilford is run on a slightly altered version of the path diagram. In this version, the direction of edges from all intercepts that are not roots is reversed, the direction of all edges leading to exogenous manifests is reversed and all bidirectional edges are removed.

References

Fruchterman, T. & Reingold, E. (1991). Graph drawing by force-directed placement. Software - Pract. Exp. 21, 1129-1164.

Reingold, E and Tilford, J (1981). Tidier drawing of trees. IEEE Trans. on Softw. Eng., SE-7(2):223-228.

Csardi G, Nepusz T (2006). The igraph software package for complex network research, InterJournal, Complex Systems 1695. http://igraph.sf.net

See Also

qgraph semPlotModel semPlotModel-class semCors lisrelModel semSyntax

Examples

Run this code
# Regression analysis with interaction effects ----------------------------

# A silly dataset:
X <- rnorm(100)
Y <- rnorm(100)
Z <- rnorm(1)*X + rnorm(1)*Y + rnorm(1)*X*Y
DF <- data.frame(X,Y,Z)

# Regression including interaction:
res <- lm(Z ~ X*Y, data = DF)

# Path diagram:
semPaths(res, intAtSide=TRUE)

# Standardized estimates:
semPaths(res,"std","hide", intAtSide=TRUE)

# Simple CFA -------------------------------------------
library("lavaan")
example(cfa)

semPaths(fit, 'std', 'est', curveAdjacent = TRUE, style = "lisrel")


# MIMIC model ----------------------------------------------------
## Lavaan
library("lavaan")

# Example 5.8 from mplus user guide:
Data <- read.table("http://www.statmodel.com/usersguide/chap5/ex5.8.dat")
names(Data) <- c(paste("y", 1:6, sep=""),
                 paste("x", 1:3, sep=""))

# Model:
model.Lavaan <- 'f1 =~ y1 + y2 + y3
f2 =~ y4 + y5 + y6
f1 + f2 ~ x1 + x2 + x3 '

# Run Lavaan:
library("lavaan")
fit <- lavaan:::cfa(model.Lavaan, data=Data, std.lv=TRUE)

# Plot path diagram:
semPaths(fit,title=FALSE)

# Omit exogenous covariances:
semPaths(fit,title=FALSE, exoVar = FALSE, exoCov = FALSE)

# Standardized parameters:
semPaths(fit,"std", edge.label.cex = 0.5, exoVar = FALSE, 
  exoCov = FALSE)
## Mplus

# Same model, now using mplus output:
outfile <- tempfile(fileext=".out")
download.file("http://www.statmodel.com/usersguide/chap5/ex5.8.out",outfile)

# Plot model:
semPaths(outfile,intercepts=FALSE)
# Note that mplus did not report the fixed variances of the exogenous variables.




# Thresholds  -----------------------------------------------------
## Lavaan

# Example 5.8 from mplus user guide:
Data <- read.table("http://www.statmodel.com/usersguide/chap5/ex5.2.dat")
names(Data) <- c("u1","u2","u3","u4","u5","u6")
Data <- as.data.frame(lapply(Data, ordered))

# Lavaan model:
model <- ' f1 =~ u1 + u2 + u3; f2 =~ u4 + u5 + u6 '

# Run Lavaan:
fit <- lavaan::cfa(model, data=Data)

# Plot path diagram:
semPaths(fit,intercepts=FALSE)

## Mplus

# Same model, now using mplus output:
outfile <- tempfile(fileext=".out")
download.file("http://www.statmodel.com/usersguide/chap5/ex5.2.out",outfile)

# Plot model:
semPaths(outfile)




# OpenMx ----------------------------------------------------------
# To isntall OpenMx see:
# http://openmx.psyc.virginia.edu/

library("OpenMx")

# Example from mxRun help page:
# Create and run the 1-factor CFA on the openmx.psyc.virginia.edu front page
data(demoOneFactor)  # load the demoOneFactor dataframe
manifests <- names(demoOneFactor) # set the manifest to the 5 demo variables
latents   <- c("G")  # define 1 latent variable
model <- mxModel("One Factor", type="RAM",
  manifestVars = manifests,
	latentVars   = latents,
	mxPath(from=latents  , to=manifests),
	mxPath(from=manifests, arrows=2),
	mxPath(from=latents  , arrows=2, free=FALSE, values=1.0),
	mxData(cov(demoOneFactor), type="cov", numObs=500)
)
model <- mxRun(model) #run model, returning the result

# Plot with colors from OpenMx front page:
semPaths(model, color = list(
              lat = rgb(245, 253, 118, maxColorValue = 255), 
              man = rgb(155, 253, 175, maxColorValue = 255)),
          mar = c(10, 5, 10, 5))

## Factor Analysis:
source("http://openmx.psyc.virginia.edu/svn/trunk/demo/TwoFactorModel_PathCov.R")
semPaths(twoFactorFit, layout = "tree2")





# Multi-group analysis -------------------------------------------
## LISREL:
# Download measurment invariance example:
modFile <- tempfile(fileext=".OUT")
download.file("http://sachaepskamp.com/files/mi1.OUT",modFile)
layout(t(1:2))
semPaths(modFile,"eq",ask=FALSE, intAtSide = TRUE, mar = c(8, 1, 5, 1))
# Color indicates equality constraints.

Run the code above in your browser using DataLab