<h1>Brief explanation</h1>
<p>This is the second part in a series on three articles about Structural Equation Modelling (SEM). This time I am glad to announce <a href="http://t-redactyl.io/">Jodie Burchell</a> as a co-writer!</p>
<p>In <a href="http://pacha.hk/sem_r_part_1.html">Structural Equation Modelling in R (Part 1)</a> I explained the basics of CFA. SEM was explained as a general case of CFA that was going be explained later, so here we go.</p>
<h1>Structural Equation Modeling</h1>
<p>SEM models or causal models arise from confirmatory models. A confimatory model becomes a causal model if all latent variables are defined by observed variables.</p>
<p>Bollen (1989) proposed a SEM model to study an aspect of democracy. In his work he analyzes the relationship between freedom of the press, freedom of political opposition and fairness of elections among other variables such as industrialization (details <a href="https://www.rdocumentation.org/packages/lavaan/versions/0.5-22/topics/PoliticalDemocracy">here</a>).</p>
<p>We can represent Bollen's model in a diagram:</p>
<div>
</div>
<p><code>help(&quot;PoliticalDemocracy&quot;)</code> provides a description of the variables within the dataset but it is recommended to read <a href="http://www.jstor.org/stable/2094588?seq=1#fndtn-page_scan_tab_contents">Political Democracy and the Timing of Development</a> by K.A. Bollen.</p>
<p>In this model, <span>\(\newcommand{\R}{\mathbb{R}} x_2\)</span>, <span>\(x_2\)</span> and <span>\(x_3\)</span> are the gross national product (GNP) per capita in 1960, the inanimate energy consumption per capita in 1960, and the percentage of the labor force in industry in 1960 respectively. Variables <span>\(y_1\)</span> to <span>\(y_8\)</span> represent: </p>
<ul><li>Expert ratings of the freedom of the press in 1960</li>
<li>The freedom of political opposition in 1960</li>
<li>The fairness of elections in 1960</li>
<li>The effectiveness of the elected legislature in 1960</li>
<li>Expert ratings of the freedom of the press in 1965</li>
<li>The freedom of political opposition in 1965</li>
<li>The fairness of elections in 1965</li>
<li>The effectiveness of the elected legislature in 1965</li>
</ul><p>Finally, <span>\(z_1\)</span>, <span>\(z_2\)</span> and <span>\(z_3\)</span> represent the degree of industrialization in 1960, political democracy in 1960, and political democracy in 1965 respectively. </p>
<p>As in the case of CFA double-headed arrows represent an association, but in this case between the <span>\(y_i\)</span>'s single-headed arrows represent direct effects, and <span>\(\varepsilon_i\)</span>, <span>\(\delta_i\)</span>, <span>\(\zeta_i\)</span> represent error terms.</p>
<p>Here the error terms help us to understand an SEM model as a net of regressions. In R notation <span>\(ind60 \sim x_1 + x_2 + x_3\)</span> would be a short form of writing <span>\(ind60 = \lambda_1 x_1 + \lambda_2 x_2 + \lambda_3 x_3 + \zeta_1\)</span> where each <span>\(\lambda_i\)</span> is a regression coefficient that can be estimated using ML, OLS or a variety of methods.</p>
<h1>Using Lavaan to obtain parameters estimates</h1>
<p>First we load the needed packages to perform the analysis:</p>
<div><pre><span></span><span># Needed packages to perform the analysis</span>
load <span>&lt;-</span> <span>function</span><span>(</span>pkg<span>){</span>
  new.pkg <span>&lt;-</span> pkg<span>[</span><span>!</span><span>(</span>pkg <span>%in%</span> installed.packages<span>()[,</span> <span>&quot;Package&quot;</span><span>])]</span>
  <span>if</span> <span>(</span><span>length</span><span>(</span>new.pkg<span>))</span>
    install.packages<span>(</span>new.pkg<span>,</span> dependencies <span>=</span> <span>TRUE</span><span>)</span>
  <span>sapply</span><span>(</span>pkg<span>,</span> <span>require</span><span>,</span> character.only <span>=</span> <span>TRUE</span><span>)</span>
<span>}</span> 

packages <span>&lt;-</span> <span>c</span><span>(</span><span>&quot;lavaan&quot;</span><span>,</span><span>&quot;semPlot&quot;</span><span>,</span><span>&quot;semTools&quot;</span><span>,</span><span>&quot;nonnest2&quot;</span><span>,</span><span>&quot;htmlTable&quot;</span><span>)</span>
<span>load</span><span>(</span>packages<span>)</span>
</pre></div>
<p>Then we fit the model using the <code>sem()</code> function:</p>
<div><pre><span></span><span># 1.2. Specify the model</span>
Bollen.model <span>&lt;-</span> <span>'# measurement model</span>
<span> ind60 =~ x1 + x2 + x3</span>
<span> dem60 =~ y1 + y2 + y3 + y4</span>
<span> dem65 =~ y5 + y6 + y7 + y8</span>
<span> # regressions</span>
<span> dem60 ~ ind60</span>
<span> dem65 ~ ind60 + dem60</span>
<span> # residual correlations</span>
<span> y1 ~~ y5</span>
<span> y2 ~~ y4 + y6</span>
<span> y3 ~~ y7</span>
<span> y4 ~~ y8</span>
<span> y6 ~~ y8'</span>

<span># 1.3. Fit the model</span>
fit <span>&lt;-</span> sem<span>(</span>Bollen.model<span>,</span> data <span>=</span> PoliticalDemocracy<span>)</span>
</pre></div>
<p>Then we obtain a model summary, confidence intervals and goodness of fit indicators:</p>
<div><pre><span></span><span># 2.1. Display summary output</span>
<span>summary</span><span>(</span>fit<span>,</span> fit.measures<span>=</span><span>FALSE</span><span>)</span>
</pre></div>
<div><pre><span></span>lavaan (0.5-22) converged normally after  68 iterations

  Number of observations                            75

  Estimator                                         ML
  Minimum Function Test Statistic               38.125
  Degrees of freedom                                35
  P-value (Chi-square)                           0.329

Parameter Estimates:

  Information                                 Expected
  Standard Errors                             Standard

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)
  ind60 =~                                            
    x1                1.000                           
    x2                2.180    0.139   15.742    0.000
    x3                1.819    0.152   11.967    0.000
  dem60 =~                                            
    y1                1.000                           
    y2                1.257    0.182    6.889    0.000
    y3                1.058    0.151    6.987    0.000
    y4                1.265    0.145    8.722    0.000
  dem65 =~                                            
    y5                1.000                           
    y6                1.186    0.169    7.024    0.000
    y7                1.280    0.160    8.002    0.000
    y8                1.266    0.158    8.007    0.000

Regressions:
                   Estimate  Std.Err  z-value  P(>|z|)
  dem60 ~                                             
    ind60             1.483    0.399    3.715    0.000
  dem65 ~                                             
    ind60             0.572    0.221    2.586    0.010
    dem60             0.837    0.098    8.514    0.000

Covariances:
                   Estimate  Std.Err  z-value  P(>|z|)
 .y1 ~~                                               
   .y5                0.624    0.358    1.741    0.082
 .y2 ~~                                               
   .y4                1.313    0.702    1.871    0.061
   .y6                2.153    0.734    2.934    0.003
 .y3 ~~                                               
   .y7                0.795    0.608    1.308    0.191
 .y4 ~~                                               
   .y8                0.348    0.442    0.787    0.431
 .y6 ~~                                               
   .y8                1.356    0.568    2.386    0.017

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)
   .x1                0.082    0.019    4.184    0.000
   .x2                0.120    0.070    1.718    0.086
   .x3                0.467    0.090    5.177    0.000
   .y1                1.891    0.444    4.256    0.000
   .y2                7.373    1.374    5.366    0.000
   .y3                5.067    0.952    5.324    0.000
   .y4                3.148    0.739    4.261    0.000
   .y5                2.351    0.480    4.895    0.000
   .y6                4.954    0.914    5.419    0.000
   .y7                3.431    0.713    4.814    0.000
   .y8                3.254    0.695    4.685    0.000
    ind60             0.448    0.087    5.173    0.000
   .dem60             3.956    0.921    4.295    0.000
   .dem65             0.172    0.215    0.803    0.422
</pre></div>
<div><pre><span></span><span># 2.2. Obtain confidence intervals for the estimated coefficients</span>
parameterEstimates<span>(</span>fit<span>,</span> ci <span>=</span> <span>TRUE</span><span>,</span> level <span>=</span> <span>0.95</span><span>)</span>
</pre></div>
<div><pre><span></span>     lhs op   rhs   est    se      z pvalue ci.lower ci.upper
1  ind60 =~    x1 1.000 0.000     NA     NA    1.000    1.000
2  ind60 =~    x2 2.180 0.139 15.742  0.000    1.909    2.452
3  ind60 =~    x3 1.819 0.152 11.967  0.000    1.521    2.116
4  dem60 =~    y1 1.000 0.000     NA     NA    1.000    1.000
5  dem60 =~    y2 1.257 0.182  6.889  0.000    0.899    1.614
6  dem60 =~    y3 1.058 0.151  6.987  0.000    0.761    1.354
7  dem60 =~    y4 1.265 0.145  8.722  0.000    0.981    1.549
8  dem65 =~    y5 1.000 0.000     NA     NA    1.000    1.000
9  dem65 =~    y6 1.186 0.169  7.024  0.000    0.855    1.517
10 dem65 =~    y7 1.280 0.160  8.002  0.000    0.966    1.593
11 dem65 =~    y8 1.266 0.158  8.007  0.000    0.956    1.576
12 dem60  ~ ind60 1.483 0.399  3.715  0.000    0.701    2.265
13 dem65  ~ ind60 0.572 0.221  2.586  0.010    0.139    1.006
14 dem65  ~ dem60 0.837 0.098  8.514  0.000    0.645    1.030
15    y1 ~~    y5 0.624 0.358  1.741  0.082   -0.079    1.326
16    y2 ~~    y4 1.313 0.702  1.871  0.061   -0.063    2.689
17    y2 ~~    y6 2.153 0.734  2.934  0.003    0.715    3.591
18    y3 ~~    y7 0.795 0.608  1.308  0.191   -0.396    1.986
19    y4 ~~    y8 0.348 0.442  0.787  0.431   -0.519    1.215
20    y6 ~~    y8 1.356 0.568  2.386  0.017    0.242    2.470
21    x1 ~~    x1 0.082 0.019  4.184  0.000    0.043    0.120
22    x2 ~~    x2 0.120 0.070  1.718  0.086   -0.017    0.256
23    x3 ~~    x3 0.467 0.090  5.177  0.000    0.290    0.643
24    y1 ~~    y1 1.891 0.444  4.256  0.000    1.020    2.762
25    y2 ~~    y2 7.373 1.374  5.366  0.000    4.680   10.066
26    y3 ~~    y3 5.067 0.952  5.324  0.000    3.202    6.933
27    y4 ~~    y4 3.148 0.739  4.261  0.000    1.700    4.596
28    y5 ~~    y5 2.351 0.480  4.895  0.000    1.410    3.292
29    y6 ~~    y6 4.954 0.914  5.419  0.000    3.162    6.746
30    y7 ~~    y7 3.431 0.713  4.814  0.000    2.034    4.829
31    y8 ~~    y8 3.254 0.695  4.685  0.000    1.893    4.615
32 ind60 ~~ ind60 0.448 0.087  5.173  0.000    0.279    0.618
33 dem60 ~~ dem60 3.956 0.921  4.295  0.000    2.151    5.762
34 dem65 ~~ dem65 0.172 0.215  0.803  0.422   -0.249    0.593
</pre></div>
<div><pre><span></span><span># 2.3 Obtain goodness of fit indicators of the model</span>
fitMeasures<span>(</span>fit<span>,</span> <span>c</span><span>(</span><span>&quot;chisq&quot;</span><span>,</span> <span>&quot;rmsea&quot;</span><span>,</span> <span>&quot;srmr&quot;</span><span>,</span> <span>&quot;gfi&quot;</span><span>,</span> <span>&quot;ecvi&quot;</span><span>))</span>
</pre></div>
<div><pre><span></span> chisq  rmsea   srmr    gfi   ecvi 
38.125  0.035  0.044  0.923  1.335 
</pre></div>
<div><pre><span></span>reliability<span>(</span>fit<span>)</span>
</pre></div>
<div><pre><span></span>           ind60     dem60     dem65     total
alpha  0.9023348 0.8587945 0.8827394 0.9149416
omega  0.9437375 0.8375193 0.8556193 0.9134989
omega2 0.9437375 0.8375193 0.8556193 0.9134989
omega3 0.9436896 0.8411801 0.8575540 0.9192058
avevar 0.8588015 0.5996707 0.6408647 0.6320779
</pre></div>
<h1>Exporting lavaan output to tables</h1>
<p>Lavaan produces a lot of potential pieces of output, but I suggest that at minimum that you export the above model summary, confidence intervals and goodness of fit indicators as part of your final tables:</p>
<div><pre><span></span>htmlTable<span>(</span>txtRound<span>(</span>parameterEstimates<span>(</span>fit<span>,</span> ci <span>=</span> <span>TRUE</span><span>,</span> level <span>=</span> <span>0.95</span><span>),</span> digits<span>=</span><span>3</span><span>,</span> excl.cols<span>=</span><span>c</span><span>(</span><span>1</span><span>,</span><span>3</span><span>)),</span> align<span>=</span><span>&quot;l|r|r|r|r|r|r|r|r|r&quot;</span><span>)</span>
</pre></div>
<table><tr> lhs
op
rhs
est
se
z
pvalue
ci.lower
ci.upper
</tr><tr><td>1</td>
<td>ind60</td>
<td>=~</td>
<td>x1</td>
<td>1.000</td>
<td>0.000</td>
<td></td>
<td></td>
<td>1.000</td>
<td>1.000</td>
</tr><tr><td>2</td>
<td>ind60</td>
<td>=~</td>
<td>x2</td>
<td>2.180</td>
<td>0.139</td>
<td>15.742</td>
<td>0.000</td>
<td>1.909</td>
<td>2.452</td>
</tr><tr><td>3</td>
<td>ind60</td>
<td>=~</td>
<td>x3</td>
<td>1.819</td>
<td>0.152</td>
<td>11.967</td>
<td>0.000</td>
<td>1.521</td>
<td>2.116</td>
</tr><tr><td>4</td>
<td>dem60</td>
<td>=~</td>
<td>y1</td>
<td>1.000</td>
<td>0.000</td>
<td></td>
<td></td>
<td>1.000</td>
<td>1.000</td>
</tr><tr><td>5</td>
<td>dem60</td>
<td>=~</td>
<td>y2</td>
<td>1.257</td>
<td>0.182</td>
<td>6.889</td>
<td>5.636</td>
<td>0.899</td>
<td>1.614</td>
</tr><tr><td>6</td>
<td>dem60</td>
<td>=~</td>
<td>y3</td>
<td>1.058</td>
<td>0.151</td>
<td>6.987</td>
<td>2.808</td>
<td>0.761</td>
<td>1.354</td>
</tr><tr><td>7</td>
<td>dem60</td>
<td>=~</td>
<td>y4</td>
<td>1.265</td>
<td>0.145</td>
<td>8.722</td>
<td>0.000</td>
<td>0.981</td>
<td>1.549</td>
</tr><tr><td>8</td>
<td>dem65</td>
<td>=~</td>
<td>y5</td>
<td>1.000</td>
<td>0.000</td>
<td></td>
<td></td>
<td>1.000</td>
<td>1.000</td>
</tr><tr><td>9</td>
<td>dem65</td>
<td>=~</td>
<td>y6</td>
<td>1.186</td>
<td>0.169</td>
<td>7.024</td>
<td>2.159</td>
<td>0.855</td>
<td>1.517</td>
</tr><tr><td>10</td>
<td>dem65</td>
<td>=~</td>
<td>y7</td>
<td>1.280</td>
<td>0.160</td>
<td>8.002</td>
<td>1.332</td>
<td>0.966</td>
<td>1.593</td>
</tr><tr><td>11</td>
<td>dem65</td>
<td>=~</td>
<td>y8</td>
<td>1.266</td>
<td>0.158</td>
<td>8.007</td>
<td>1.110</td>
<td>0.956</td>
<td>1.576</td>
</tr><tr><td>12</td>
<td>dem60</td>
<td>~</td>
<td>ind60</td>
<td>1.483</td>
<td>0.399</td>
<td>3.715</td>
<td>2.029</td>
<td>0.701</td>
<td>2.265</td>
</tr><tr><td>13</td>
<td>dem65</td>
<td>~</td>
<td>ind60</td>
<td>0.572</td>
<td>0.221</td>
<td>2.586</td>
<td>9.707</td>
<td>0.139</td>
<td>1.006</td>
</tr><tr><td>14</td>
<td>dem65</td>
<td>~</td>
<td>dem60</td>
<td>0.837</td>
<td>0.098</td>
<td>8.514</td>
<td>0.000</td>
<td>0.645</td>
<td>1.030</td>
</tr><tr><td>15</td>
<td>y1</td>
<td>~~</td>
<td>y5</td>
<td>0.624</td>
<td>0.358</td>
<td>1.741</td>
<td>8.176</td>
<td>-0.079</td>
<td>1.326</td>
</tr><tr><td>16</td>
<td>y2</td>
<td>~~</td>
<td>y4</td>
<td>1.313</td>
<td>0.702</td>
<td>1.871</td>
<td>6.140</td>
<td>-0.063</td>
<td>2.689</td>
</tr><tr><td>17</td>
<td>y2</td>
<td>~~</td>
<td>y6</td>
<td>2.153</td>
<td>0.734</td>
<td>2.934</td>
<td>3.347</td>
<td>0.715</td>
<td>3.591</td>
</tr><tr><td>18</td>
<td>y3</td>
<td>~~</td>
<td>y7</td>
<td>0.795</td>
<td>0.608</td>
<td>1.308</td>
<td>1.908</td>
<td>-0.396</td>
<td>1.986</td>
</tr><tr><td>19</td>
<td>y4</td>
<td>~~</td>
<td>y8</td>
<td>0.348</td>
<td>0.442</td>
<td>0.787</td>
<td>4.310</td>
<td>-0.519</td>
<td>1.215</td>
</tr><tr><td>20</td>
<td>y6</td>
<td>~~</td>
<td>y8</td>
<td>1.356</td>
<td>0.568</td>
<td>2.386</td>
<td>1.701</td>
<td>0.242</td>
<td>2.470</td>
</tr><tr><td>21</td>
<td>x1</td>
<td>~~</td>
<td>x1</td>
<td>0.082</td>
<td>0.019</td>
<td>4.184</td>
<td>2.861</td>
<td>0.043</td>
<td>0.120</td>
</tr><tr><td>22</td>
<td>x2</td>
<td>~~</td>
<td>x2</td>
<td>0.120</td>
<td>0.070</td>
<td>1.718</td>
<td>8.573</td>
<td>-0.017</td>
<td>0.256</td>
</tr><tr><td>23</td>
<td>x3</td>
<td>~~</td>
<td>x3</td>
<td>0.467</td>
<td>0.090</td>
<td>5.177</td>
<td>2.260</td>
<td>0.290</td>
<td>0.643</td>
</tr><tr><td>24</td>
<td>y1</td>
<td>~~</td>
<td>y1</td>
<td>1.891</td>
<td>0.444</td>
<td>4.256</td>
<td>2.083</td>
<td>1.020</td>
<td>2.762</td>
</tr><tr><td>25</td>
<td>y2</td>
<td>~~</td>
<td>y2</td>
<td>7.373</td>
<td>1.374</td>
<td>5.366</td>
<td>8.032</td>
<td>4.680</td>
<td>10.066</td>
</tr><tr><td>26</td>
<td>y3</td>
<td>~~</td>
<td>y3</td>
<td>5.067</td>
<td>0.952</td>
<td>5.324</td>
<td>1.012</td>
<td>3.202</td>
<td>6.933</td>
</tr><tr><td>27</td>
<td>y4</td>
<td>~~</td>
<td>y4</td>
<td>3.148</td>
<td>0.739</td>
<td>4.261</td>
<td>2.036</td>
<td>1.700</td>
<td>4.596</td>
</tr><tr><td>28</td>
<td>y5</td>
<td>~~</td>
<td>y5</td>
<td>2.351</td>
<td>0.480</td>
<td>4.895</td>
<td>9.810</td>
<td>1.410</td>
<td>3.292</td>
</tr><tr><td>29</td>
<td>y6</td>
<td>~~</td>
<td>y6</td>
<td>4.954</td>
<td>0.914</td>
<td>5.419</td>
<td>6.006</td>
<td>3.162</td>
<td>6.746</td>
</tr><tr><td>30</td>
<td>y7</td>
<td>~~</td>
<td>y7</td>
<td>3.431</td>
<td>0.713</td>
<td>4.814</td>
<td>1.482</td>
<td>2.034</td>
<td>4.829</td>
</tr><tr><td>31</td>
<td>y8</td>
<td>~~</td>
<td>y8</td>
<td>3.254</td>
<td>0.695</td>
<td>4.685</td>
<td>2.802</td>
<td>1.893</td>
<td>4.615</td>
</tr><tr><td>32</td>
<td>ind60</td>
<td>~~</td>
<td>ind60</td>
<td>0.448</td>
<td>0.087</td>
<td>5.173</td>
<td>2.306</td>
<td>0.279</td>
<td>0.618</td>
</tr><tr><td>33</td>
<td>dem60</td>
<td>~~</td>
<td>dem60</td>
<td>3.956</td>
<td>0.921</td>
<td>4.295</td>
<td>1.751</td>
<td>2.151</td>
<td>5.762</td>
</tr><tr><td>34</td>
<td>dem65</td>
<td>~~</td>
<td>dem65</td>
<td>0.172</td>
<td>0.215</td>
<td>0.803</td>
<td>4.220</td>
<td>-0.249</td>
<td>0.593</td>
</tr></table><div><pre><span></span>htmlTable<span>(</span>txtRound<span>(</span>reliability<span>(</span>fit<span>),</span><span>3</span><span>),</span> align<span>=</span><span>&quot;l|r|r|r|r&quot;</span><span>)</span>
</pre></div>
<table><tr> ind60
dem60
dem65
total
</tr><tr><td>alpha</td>
<td>0.902</td>
<td>0.859</td>
<td>0.883</td>
<td>0.915</td>
</tr><tr><td>omega</td>
<td>0.944</td>
<td>0.838</td>
<td>0.856</td>
<td>0.913</td>
</tr><tr><td>omega2</td>
<td>0.944</td>
<td>0.838</td>
<td>0.856</td>
<td>0.913</td>
</tr><tr><td>omega3</td>
<td>0.944</td>
<td>0.841</td>
<td>0.858</td>
<td>0.919</td>
</tr><tr><td>avevar</td>
<td>0.859</td>
<td>0.600</td>
<td>0.641</td>
<td>0.632</td>
</tr></table><p>There are other packages to convert R output to tables such as <code>knitr</code> and <code>xtables</code> that can also export to <span>\(\rm\LaTeX\)</span>.</p>
<h1>Creating a diagram for the model in R</h1>
<p>Now let's get on to producing the exciting part of an SEM analysis - the model diagram. This code might not be good-looking but the result is!</p>
<div><pre><span></span>svg<span>(</span><span>&quot;sem_r/sem_example_2.svg&quot;</span><span>)</span>
semPaths<span>(</span>fit<span>,</span> style<span>=</span><span>&quot;lisrel&quot;</span><span>,</span> 
        whatLabels <span>=</span> <span>&quot;std&quot;</span><span>,</span> edge.label.cex <span>=</span> <span>.6</span><span>,</span> node.label.cex <span>=</span> <span>.6</span><span>,</span> 
        label.prop<span>=</span><span>0.9</span><span>,</span> edge.label.color <span>=</span> <span>&quot;black&quot;</span><span>,</span> rotation <span>=</span> <span>4</span><span>,</span> 
        equalizeManifests <span>=</span> <span>FALSE</span><span>,</span> optimizeLatRes <span>=</span> <span>TRUE</span><span>,</span> node.width <span>=</span> <span>1.5</span><span>,</span> 
        edge.width <span>=</span> <span>0.5</span><span>,</span> shapeMan <span>=</span> <span>&quot;rectangle&quot;</span><span>,</span> shapeLat <span>=</span> <span>&quot;ellipse&quot;</span><span>,</span> 
        shapeInt <span>=</span> <span>&quot;triangle&quot;</span><span>,</span> sizeMan <span>=</span> <span>4</span><span>,</span> sizeInt <span>=</span> <span>2</span><span>,</span> sizeLat <span>=</span> <span>4</span><span>,</span> 
        curve<span>=</span><span>2</span><span>,</span> unCol <span>=</span> <span>&quot;#070b8c&quot;</span><span>)</span>
dev.off<span>()</span>
</pre></div>
<div>
</div>
<h1>Appendix</h1>
<p>This is the TikZ (LaTeX) code to obtain the first diagram.</p>
<div><pre><span></span><span>\documentclass</span><span>[border=3mm]</span><span>{</span>standalone<span>}</span>
<span>\usepackage</span><span>[applemac]</span><span>{</span>inputenc<span>}</span>
<span>\usepackage</span><span>[protrusion=true,expansion=true]</span><span>{</span>microtype<span>}</span>
<span>\usepackage</span><span>[bb=lucida,bbscaled=1,cal=boondoxo]</span><span>{</span>mathalfa<span>}</span>
<span>\usepackage</span><span>[stdmathitalics=true,math-style=iso,lucidasmallscale=true,romanfamily=bright]</span><span>{</span>lucimatx<span>}</span>
<span>\usepackage</span><span>{</span>tikz<span>}</span>
<span>\usetikzlibrary</span><span>{</span>arrows,positioning,calc<span>}</span>
<span>\newcommand</span><span>{</span><span>\at</span><span>}{</span><span>\makeatletter</span> @<span>\makeatother</span><span>}</span>
<span>\begin</span><span>{</span>document<span>}</span>
<span>\begin</span><span>{</span>tikzpicture<span>}</span>[auto,node distance=.5cm,
    latent/.style=<span>{</span>fill=red!20,circle,draw, thick,inner sep=0pt,minimum size=8mm,align=center<span>}</span>,
    observed/.style=<span>{</span>fill=blue!20,rectangle,draw, thick,inner sep=0pt,minimum width=8mm,minimum height=8mm,align=center<span>}</span>,
    error/.style=<span>{</span>fill=yellow!20,circle,draw, thick,inner sep=0pt,minimum width=8mm,minimum height=8mm,align=center<span>}</span>,
    paths/.style=<span>{</span>->,  thick, >=stealth'<span>}</span>,
    paths2/.style=<span>{</span>&lt;-,  thick, >=stealth'<span>}</span>,
    twopaths/.style=<span>{</span>&lt;->,  thick, >=stealth'<span>}</span>
]

<span>%Define observed variables</span>
<span>\node</span> [latent] (z2) at (0,0) <span>{</span><span>$</span><span>z_</span><span>2</span><span>$</span><span>}</span>;
<span>\node</span> [latent] (z3) [below=7cm of z2]  <span>{</span><span>$</span><span>z_</span><span>3</span><span>$</span><span>}</span>;

<span>\node</span> [error] (ez2) [above=0.5cm of z2]  <span>{</span><span>$</span><span>\zeta</span><span>_</span><span>2</span><span>$</span><span>}</span>;
<span>\node</span> [error] (ez3) [below=0.5cm of z3]  <span>{</span><span>$</span><span>\zeta</span><span>_</span><span>3</span><span>$</span><span>}</span>;

<span>%%%</span>

<span>\node</span> [observed] (y2) [above left=0.2cm and 1.8cm of z2]  <span>{</span><span>$</span><span>y_</span><span>2</span><span>$</span><span>}</span>;
<span>\node</span> [observed] (y1) [above=1cm of y2]  <span>{</span><span>$</span><span>y_</span><span>1</span><span>$</span><span>}</span>;
<span>\node</span> [observed] (y3) [below=1cm of y2]  <span>{</span><span>$</span><span>y_</span><span>3</span><span>$</span><span>}</span>;
<span>\node</span> [observed] (y4) [below=1cm of y3]  <span>{</span><span>$</span><span>y_</span><span>4</span><span>$</span><span>}</span>;

<span>\node</span> [error] (ey1) [left=0.5cm of y1]  <span>{</span><span>$</span><span>\varepsilon</span><span>_</span><span>1</span><span>$</span><span>}</span>;
<span>\node</span> [error] (ey2) [left=0.5cm of y2]  <span>{</span><span>$</span><span>\varepsilon</span><span>_</span><span>2</span><span>$</span><span>}</span>;
<span>\node</span> [error] (ey3) [left=0.5cm of y3]  <span>{</span><span>$</span><span>\varepsilon</span><span>_</span><span>3</span><span>$</span><span>}</span>;
<span>\node</span> [error] (ey4) [left=0.5cm of y4]  <span>{</span><span>$</span><span>\varepsilon</span><span>_</span><span>4</span><span>$</span><span>}</span>;

<span>%%%</span>

<span>\node</span> [observed] (y6) [above left=0.2cm and 1.8cm of z3]  <span>{</span><span>$</span><span>y_</span><span>6</span><span>$</span><span>}</span>;
<span>\node</span> [observed] (y5) [above=1cm of y6]  <span>{</span><span>$</span><span>y_</span><span>5</span><span>$</span><span>}</span>;
<span>\node</span> [observed] (y7) [below=1cm of y6]  <span>{</span><span>$</span><span>y_</span><span>7</span><span>$</span><span>}</span>;
<span>\node</span> [observed] (y8) [below=1cm of y7]  <span>{</span><span>$</span><span>y_</span><span>8</span><span>$</span><span>}</span>;

<span>\node</span> [error] (ey5) [left=0.5cm of y5]  <span>{</span><span>$</span><span>\varepsilon</span><span>_</span><span>5</span><span>$</span><span>}</span>;
<span>\node</span> [error] (ey6) [left=0.5cm of y6]  <span>{</span><span>$</span><span>\varepsilon</span><span>_</span><span>6</span><span>$</span><span>}</span>;
<span>\node</span> [error] (ey7) [left=0.5cm of y7]  <span>{</span><span>$</span><span>\varepsilon</span><span>_</span><span>7</span><span>$</span><span>}</span>;
<span>\node</span> [error] (ey8) [left=0.5cm of y8]  <span>{</span><span>$</span><span>\varepsilon</span><span>_</span><span>8</span><span>$</span><span>}</span>;

<span>%%%</span>

<span>\node</span> [latent] (z1) [right=3cm of z2]  <span>{</span><span>$</span><span>z_</span><span>1</span><span>$</span><span>}</span>;

<span>\node</span> [error] (ez1) [above=0.5cm of z1]  <span>{</span><span>$</span><span>\zeta</span><span>_</span><span>1</span><span>$</span><span>}</span>;

<span>%%%</span>

<span>\node</span> [observed] (x2) [right=1.8cm of z1]  <span>{</span><span>$</span><span>x_</span><span>2</span><span>$</span><span>}</span>;
<span>\node</span> [observed] (x1) [above=of x2]  <span>{</span><span>$</span><span>x_</span><span>1</span><span>$</span><span>}</span>;
<span>\node</span> [observed] (x3) [below=of x2]  <span>{</span><span>$</span><span>x_</span><span>3</span><span>$</span><span>}</span>;

<span>\node</span> [error] (ex1) [right=0.5cm of x1]  <span>{</span><span>$</span><span>\delta</span><span>_</span><span>1</span><span>$</span><span>}</span>;
<span>\node</span> [error] (ex2) [right=0.5cm of x2]  <span>{</span><span>$</span><span>\delta</span><span>_</span><span>2</span><span>$</span><span>}</span>;
<span>\node</span> [error] (ex3) [right=0.5cm of x3]  <span>{</span><span>$</span><span>\delta</span><span>_</span><span>3</span><span>$</span><span>}</span>;

<span>% Draw paths form latent to observed variables</span>

<span>\foreach</span> <span>\all</span> in <span>{</span>y1,y2,y3,y4<span>}{</span>
    <span>\draw</span> [paths] (z2.west) to node <span>{}</span> (<span>\all</span>.east);
<span>}</span>

<span>\draw</span> [paths] (y1.west) to (ey1.east);
<span>\draw</span> [paths] (y2.west) to (ey2.east);
<span>\draw</span> [paths] (y3.west) to (ey3.east);
<span>\draw</span> [paths] (y4.west) to (ey4.east);

<span>%%%</span>

<span>\foreach</span> <span>\all</span> in <span>{</span>y5,y6,y7,y8<span>}{</span>
    <span>\draw</span> [paths] (z3.west) to node <span>{}</span> (<span>\all</span>.east);
<span>}</span>

<span>\draw</span> [paths] (y5.west) to (ey5.east);
<span>\draw</span> [paths] (y6.west) to (ey6.east);
<span>\draw</span> [paths] (y7.west) to (ey7.east);
<span>\draw</span> [paths] (y8.west) to (ey8.east);

<span>%%%</span>

<span>\foreach</span> <span>\all</span> in <span>{</span>x1,x2,x3<span>}{</span>
    <span>\draw</span> [paths] (z1.east) to node <span>{}</span> (<span>\all</span>.west);
<span>}</span>

<span>\draw</span> [paths] (x1.east) to (ex1.west);
<span>\draw</span> [paths] (x2.east) to (ex2.west);
<span>\draw</span> [paths] (x3.east) to (ex3.west);

<span>%%%</span>

<span>\draw</span> [paths] (z1.north) to (ez1.south);
<span>\draw</span> [paths] (z2.north) to (ez2.south);
<span>\draw</span> [paths] (z3.south) to (ez3.north);

<span>%%%</span>

<span>\draw</span> [paths] (z2.south) to (z3.north);
<span>\draw</span> [paths] (z1.west) to (z2.east);
<span>\draw</span> [paths] (z1.west) to (z3.north);

<span>%%%</span>

<span>\draw</span> [twopaths] (y1.south west) to [bend right=90] (y5.north west);
<span>\draw</span> [twopaths] (y2.south west) to [bend right=90] (y6.north west);
<span>\draw</span> [twopaths] (y3.south west) to [bend right=90] (y7.north west);
<span>\draw</span> [twopaths] (y4.south west) to [bend right=90] (y8.north west);

<span>\draw</span> [twopaths] (y2.south west) to [out=180,in=90] (<span>$</span><span>(</span><span>ey</span><span>3</span><span>)+(-</span><span>1</span><span>,</span><span>0</span><span>)</span><span>$</span>) to [out=-90, in=-180] (y4.north west);
<span>\draw</span> [twopaths] (y6.south west) to [out=180,in=90] (<span>$</span><span>(</span><span>ey</span><span>7</span><span>)+(-</span><span>1</span><span>,</span><span>0</span><span>)</span><span>$</span>) to [out=-90, in=-180] (y8.north west);

<span>\end</span><span>{</span>tikzpicture<span>}</span>
<span>\end</span><span>{</span>document<span>}</span>
</pre></div>
<p>and then I ran <code>pdf2svg sem_example.pdf sem_example.svg</code>.</p>