<!DOCTYPE html>
<!-- Generated by pkgdown: do not edit by hand --><html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Incorporating structural equation models • specr</title>
<!-- jquery --><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script><!-- Bootstrap --><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha256-bZLfwXAP04zRMK2BjiO8iu9pf4FbLqX6zitd+tIvLhE=" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha256-nuL8/2cJ5NDSSwnKD8VqreErSWHtnEP9E7AySL+1ev4=" crossorigin="anonymous"></script><!-- bootstrap-toc --><link rel="stylesheet" href="../bootstrap-toc.css">
<script src="../bootstrap-toc.js"></script><!-- Font Awesome icons --><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" integrity="sha256-mmgLkCYLUQbXn0B1SRqzHar6dCnv9oZFPEC1g1cwlkk=" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/v4-shims.min.css" integrity="sha256-wZjR52fzng1pJHwx4aV2AO3yyTOXrcDW7jBpJtTwVxw=" crossorigin="anonymous">
<!-- clipboard.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js" integrity="sha256-inc5kl9MA1hkeYUt+EC3BhlIgyp/2jDIyBLS6k3UxPI=" crossorigin="anonymous"></script><!-- headroom.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/headroom.min.js" integrity="sha256-AsUX4SJE1+yuDu5+mAVzJbuYNPHj/WroHuZ8Ir/CkE0=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/jQuery.headroom.min.js" integrity="sha256-ZX/yNShbjqsohH1k95liqY9Gd8uOiE1S4vZc+9KQ1K4=" crossorigin="anonymous"></script><!-- pkgdown --><link href="../pkgdown.css" rel="stylesheet">
<script src="../pkgdown.js"></script><meta property="og:title" content="Incorporating structural equation models">
<meta property="og:description" content="specr">
<!-- mathjax --><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js" integrity="sha256-nvJJv9wWKEm88qvoQl9ekL2J+k/RWIsaSScxxlsrv8k=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/config/TeX-AMS-MML_HTMLorMML.js" integrity="sha256-84DKXVJXs0/F8OTMzX4UR909+jtl4G7SPypPavF+GfA=" crossorigin="anonymous"></script><!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body data-spy="scroll" data-target="#toc">
    

    <div class="container template-article">
      <header><div class="navbar navbar-default navbar-fixed-top" role="navigation">
  <div class="container">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <span class="navbar-brand">
        <a class="navbar-link" href="../index.html">specr</a>
        <span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="">1.0.1</span>
      </span>
    </div>

    <div id="navbar" class="navbar-collapse collapse">
      <ul class="nav navbar-nav">
<li>
  <a href="../articles/getting-started.html">Getting started</a>
</li>
<li>
  <a href="../reference/index.html">Reference</a>
</li>
<li class="dropdown">
  <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
    Articles
     
    <span class="caret"></span>
  </a>
  <ul class="dropdown-menu" role="menu">
<li class="dropdown-header">Basics</li>
    <li>
      <a href="../articles/different-specifications.html">Setting up different types of specifications</a>
    </li>
    <li>
      <a href="../articles/custom-plot.html">Visualizing specification curve analyses</a>
    </li>
    <li>
      <a href="../articles/invest-spec.html">Investigating specific specifications</a>
    </li>
    <li>
      <a href="../articles/inferences.html">Inferences with specification curve analysis</a>
    </li>
    <li>
      <a href="../articles/parallelization.html">Parallelization</a>
    </li>
    <li class="divider">
    </li>
<li class="dropdown-header">Incorporating specific models</li>
    <li>
      <a href="../articles/measurement-models.html">Structural equation models</a>
    </li>
    <li>
      <a href="../articles/multilevel-models.html">Multilevel models</a>
    </li>
    <li>
      <a href="../articles/parallel-bayesian-models.html">Bayesian models</a>
    </li>
  </ul>
</li>
<li>
  <a href="../news/index.html">News</a>
</li>
      </ul>
<ul class="nav navbar-nav navbar-right">
<li>
  <a href="https://github.com/masurp/specr" class="external-link">
    <span class="fa fa-github fa-lg"></span>
     
  </a>
</li>
      </ul>
</div>
<!--/.nav-collapse -->
  </div>
<!--/.container -->
</div>
<!--/.navbar -->

      

      </header><div class="row">
  <div class="col-md-9 contents">
    <div class="page-header toc-ignore">
      <h1 data-toc-skip>Incorporating structural equation models</h1>
            
      
      <small class="dont-index">Source: <a href="https://github.com/masurp/specr/blob/HEAD/vignettes/measurement-models.Rmd" class="external-link"><code>vignettes/measurement-models.Rmd</code></a></small>
      <div class="hidden name"><code>measurement-models.Rmd</code></div>

    </div>

    
    
<p>Sometimes, we may want to estimate relationships between latent
variables and we are interested in the effect of different measurement
models on the relationship of interest. Because specifically customized
model-functions can be passed to <code><a href="../reference/specr.html">specr()</a></code> many different
model types (including structural equation models, multilevel models…)
can be estimated. This vignette exemplifies how to integrate latent
measurement models and estimate structural equations models (SEM).</p>
<div class="section level2">
<h2 id="preparations">Preparations<a class="anchor" aria-label="anchor" href="#preparations"></a>
</h2>
<div class="section level3">
<h3 id="preparing-the-data-set">Preparing the data set<a class="anchor" aria-label="anchor" href="#preparing-the-data-set"></a>
</h3>
<div class="sourceCode" id="cb1"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="co"># Load packages</span></span>
<span><span class="kw"><a href="https://rdrr.io/r/base/library.html" class="external-link">library</a></span><span class="op">(</span><span class="va"><a href="https://tidyverse.tidyverse.org" class="external-link">tidyverse</a></span><span class="op">)</span></span>
<span><span class="kw"><a href="https://rdrr.io/r/base/library.html" class="external-link">library</a></span><span class="op">(</span><span class="va"><a href="https://masurp.github.io/specr/" class="external-link">specr</a></span><span class="op">)</span></span>
<span><span class="kw"><a href="https://rdrr.io/r/base/library.html" class="external-link">library</a></span><span class="op">(</span><span class="va"><a href="https://lavaan.ugent.be" class="external-link">lavaan</a></span><span class="op">)</span></span></code></pre></div>
<p>For this example, we will us the <code>HolzingerSwineford1939</code>
data set that is included in the <a href="https://lavaan.ugent.be/" class="external-link">lavaan</a> package. We quickly
dummy-code the sex variable as we want to include it as a covariate.</p>
<div class="sourceCode" id="cb2"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="co"># Load data and recode</span></span>
<span><span class="va">d</span> <span class="op">&lt;-</span> <span class="va">HolzingerSwineford1939</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%&gt;%</a></span> </span>
<span>  <span class="fu"><a href="https://dplyr.tidyverse.org/reference/mutate.html" class="external-link">mutate</a></span><span class="op">(</span>sex <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/character.html" class="external-link">as.character</a></span><span class="op">(</span><span class="va">sex</span><span class="op">)</span>,</span>
<span>         school <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/character.html" class="external-link">as.character</a></span><span class="op">(</span><span class="va">school</span><span class="op">)</span><span class="op">)</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%&gt;%</a></span></span>
<span>  <span class="va">as_tibble</span></span>
<span></span>
<span><span class="co"># Check data</span></span>
<span><span class="fu"><a href="https://rdrr.io/r/utils/head.html" class="external-link">head</a></span><span class="op">(</span><span class="va">d</span><span class="op">)</span></span>
<span><span class="co">#&gt; <span style="color: #949494;"># A tibble: 6 × 15</span></span></span>
<span><span class="co">#&gt;      id sex   ageyr agemo school grade    x1    x2    x3    x4    x5    x6    x7</span></span>
<span><span class="co">#&gt;   <span style="color: #949494; font-style: italic;">&lt;int&gt;</span> <span style="color: #949494; font-style: italic;">&lt;chr&gt;</span> <span style="color: #949494; font-style: italic;">&lt;int&gt;</span> <span style="color: #949494; font-style: italic;">&lt;int&gt;</span> <span style="color: #949494; font-style: italic;">&lt;chr&gt;</span>  <span style="color: #949494; font-style: italic;">&lt;int&gt;</span> <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">1</span>     1 1        13     1 Paste…     7  3.33  7.75 0.375  2.33  5.75 1.29   3.39</span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">2</span>     2 2        13     7 Paste…     7  5.33  5.25 2.12   1.67  3    1.29   3.78</span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">3</span>     3 2        13     1 Paste…     7  4.5   5.25 1.88   1     1.75 0.429  3.26</span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">4</span>     4 1        13     2 Paste…     7  5.33  7.75 3      2.67  4.5  2.43   3   </span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">5</span>     5 2        12     2 Paste…     7  4.83  4.75 0.875  2.67  4    2.57   3.70</span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">6</span>     6 2        14     1 Paste…     7  5.33  5    2.25   1     3    0.857  4.35</span></span>
<span><span class="co">#&gt; <span style="color: #949494;"># ℹ 2 more variables: x8 &lt;dbl&gt;, x9 &lt;dbl&gt;</span></span></span></code></pre></div>
<p>Let’s quickly run a simple structural equation model with lavaan.
Note that there are separate regression formulas for the measurement
models and the actual regression models in the string that represents
the model. The regression formulas follows a similar pattern as formulas
in linear models (e.g., using <code><a href="https://rdrr.io/r/stats/lm.html" class="external-link">lm()</a></code> or <code><a href="https://rdrr.io/r/stats/glm.html" class="external-link">glm()</a></code>)
or multilevel models (e.g., using <code><a href="https://rdrr.io/pkg/lme4/man/lmer.html" class="external-link">lme4::lmer()</a></code>). This
regression formula will automatically be built by the function
<code><a href="../reference/setup.html">setup()</a></code>. The formulas denoting the measurement model (in
this case only one), however, we need to actively paste into the formula
string.</p>
</div>
<div class="section level3">
<h3 id="understanding-lavaan-syntax-and-output">Understanding lavaan syntax and output<a class="anchor" aria-label="anchor" href="#understanding-lavaan-syntax-and-output"></a>
</h3>
<div class="sourceCode" id="cb3"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="co"># Model syntax</span></span>
<span><span class="va">model</span> <span class="op">&lt;-</span> <span class="st">"</span></span>
<span><span class="st">  # measures</span></span>
<span><span class="st">  visual  =~ x1 + x2 + x3</span></span>
<span><span class="st"></span></span>
<span><span class="st">  # regressions</span></span>
<span><span class="st">  visual ~ ageyr + grade</span></span>
<span><span class="st">"</span></span>
<span></span>
<span><span class="va">fit</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/pkg/lavaan/man/sem.html" class="external-link">sem</a></span><span class="op">(</span><span class="va">model</span>, <span class="va">d</span><span class="op">)</span></span>
<span><span class="fu">broom</span><span class="fu">::</span><span class="fu"><a href="https://generics.r-lib.org/reference/tidy.html" class="external-link">tidy</a></span><span class="op">(</span><span class="va">fit</span><span class="op">)</span></span>
<span><span class="co">#&gt; <span style="color: #949494;"># A tibble: 12 × 9</span></span></span>
<span><span class="co">#&gt;    term      op    estimate std.error statistic   p.value std.lv std.all std.nox</span></span>
<span><span class="co">#&gt;    <span style="color: #949494; font-style: italic;">&lt;chr&gt;</span>     <span style="color: #949494; font-style: italic;">&lt;chr&gt;</span>    <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span>     <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span>     <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span>     <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span>  <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span>   <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span>   <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 1</span> visual =… =~       1        0          <span style="color: #BB0000;">NA</span>    <span style="color: #BB0000;">NA</span>   <span style="color: #949494;"> </span>     0.782   0.670   0.670</span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 2</span> visual =… =~       0.732    0.130       5.62  1.96<span style="color: #949494;">e</span><span style="color: #BB0000;">- 8</span>  0.572   0.486   0.486</span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 3</span> visual =… =~       0.947    0.163       5.82  5.77<span style="color: #949494;">e</span><span style="color: #BB0000;">- 9</span>  0.740   0.656   0.656</span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 4</span> visual ~… ~       -<span style="color: #BB0000;">0.147</span>    0.061<span style="text-decoration: underline;">4</span>     -<span style="color: #BB0000;">2.39</span>  1.68<span style="color: #949494;">e</span><span style="color: #BB0000;">- 2</span> -<span style="color: #BB0000;">0.188</span>  -<span style="color: #BB0000;">0.197</span>  -<span style="color: #BB0000;">0.188</span></span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 5</span> visual ~… ~        0.539    0.135       4.00  6.36<span style="color: #949494;">e</span><span style="color: #BB0000;">- 5</span>  0.690   0.345   0.690</span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 6</span> x1 ~~ x1  ~~       0.751    0.116       6.46  1.06<span style="color: #949494;">e</span><span style="color: #BB0000;">-10</span>  0.751   0.551   0.551</span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 7</span> x2 ~~ x2  ~~       1.06     0.104      10.2   0   <span style="color: #949494;"> </span>     1.06    0.764   0.764</span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 8</span> x3 ~~ x3  ~~       0.727    0.107       6.80  1.02<span style="color: #949494;">e</span><span style="color: #BB0000;">-11</span>  0.727   0.570   0.570</span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 9</span> visual ~… ~~       0.557    0.125       4.44  8.96<span style="color: #949494;">e</span><span style="color: #BB0000;">- 6</span>  0.912   0.912   0.912</span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">10</span> ageyr ~~… ~~       1.10     0          <span style="color: #BB0000;">NA</span>    <span style="color: #BB0000;">NA</span>   <span style="color: #949494;"> </span>     1.10    1       1.10 </span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">11</span> ageyr ~~… ~~       0.268    0          <span style="color: #BB0000;">NA</span>    <span style="color: #BB0000;">NA</span>   <span style="color: #949494;"> </span>     0.268   0.511   0.268</span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">12</span> grade ~~… ~~       0.249    0          <span style="color: #BB0000;">NA</span>    <span style="color: #BB0000;">NA</span>   <span style="color: #949494;"> </span>     0.249   1       0.249</span></span></code></pre></div>
<p>Whenever we want to include more complex models in “specr”, it makes
sense to check what output the <code><a href="https://generics.r-lib.org/reference/tidy.html" class="external-link">broom::tidy()</a></code> function
produces. Here, we can see that the variable <code>term</code> does not
only include the predictor (as it usually does with models such as “lm”
or “glm”), but it includes the entire paths within the model. If we do
not specify different types of model, this will not be a problem, but we
we do (e.g., “sem” and “lm”), we need to adjust the paremeter extract
function.</p>
</div>
</div>
<div class="section level2">
<h2 id="specification-curve-analysis-with-latent-variables">Specification curve analysis with latent variables<a class="anchor" aria-label="anchor" href="#specification-curve-analysis-with-latent-variables"></a>
</h2>
<div class="section level3">
<h3 id="defining-the-customized-sem-model-function">Defining the customized sem model function<a class="anchor" aria-label="anchor" href="#defining-the-customized-sem-model-function"></a>
</h3>
<p>In a first step, we thus need to create a specific function that
defines the latent measurement models for the latent measures specified
as <code>x</code> and <code>y</code> in <code><a href="../reference/setup.html">setup()</a></code> and
incoporate them into a formula that follows the lavaan-syntax. The
function needs to have two arguments: a) formula and b) data. The exact
function now depends on the purpose and goals of the particular
question.</p>
<p>In this case, we want to include three different latent measurement
models for dependent variables. First, we have to define a a <em>named
list</em> with these measurement models. This is important as the
function makes use of the “names”.</p>
<p>In a second step, we need to exclude the “+ 1” placeholder the specr
automatically adds to each formula if no covariates are included (in
contrast to <code><a href="https://rdrr.io/r/stats/lm.html" class="external-link">lm()</a></code> or <code><a href="https://rdrr.io/pkg/lme4/man/lmer.html" class="external-link">lme4::lmer()</a></code>,
<code><a href="https://rdrr.io/pkg/lavaan/man/sem.html" class="external-link">lavaan::sem()</a></code> does not support such a placeholder). Third,
we need to make sure that only those measurement models are integrated
which are actually used in the regression formula (it does not matter
whether these are independent or control variables). Fourth, we need to
paste the remaining measurement models into the formula. Finally, we run
the structural equation model (here, additional arguments such as
<code>estimator</code> could be used).</p>
<div class="sourceCode" id="cb4"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="va">sem_custom</span> <span class="op">&lt;-</span> <span class="kw">function</span><span class="op">(</span><span class="va">formula</span>, <span class="va">data</span><span class="op">)</span> <span class="op">{</span></span>
<span>  </span>
<span>  <span class="kw"><a href="https://rdrr.io/r/base/library.html" class="external-link">require</a></span><span class="op">(</span><span class="va"><a href="https://lavaan.ugent.be" class="external-link">lavaan</a></span><span class="op">)</span></span>
<span>  </span>
<span>  <span class="co"># 1) Define latent variables as a named list</span></span>
<span>  <span class="va">latent</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/base/list.html" class="external-link">list</a></span><span class="op">(</span>visual <span class="op">=</span>  <span class="st">"visual  =~ x1 + x2 + x3"</span>,</span>
<span>                 textual <span class="op">=</span> <span class="st">"textual =~ x4 + x5 + x6"</span>,</span>
<span>                 speed <span class="op">=</span>   <span class="st">"speed   =~ x7 + x8 + x9"</span><span class="op">)</span></span>
<span>  </span>
<span>  <span class="co"># 2) Remove placeholder for no covariates (lavaan does not like "+ 1")</span></span>
<span>  <span class="va">formula</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://stringr.tidyverse.org/reference/str_remove.html" class="external-link">str_remove_all</a></span><span class="op">(</span><span class="va">formula</span>, <span class="st">"\\+ 1"</span><span class="op">)</span></span>
<span>  </span>
<span>  <span class="co"># 3) Check which of the additional measurement models are actually used in the formula</span></span>
<span>  <span class="va">valid</span> <span class="op">&lt;-</span> <span class="fu">purrr</span><span class="fu">::</span><span class="fu"><a href="https://purrr.tidyverse.org/reference/keep.html" class="external-link">keep</a></span><span class="op">(</span><span class="fu"><a href="https://rdrr.io/r/base/names.html" class="external-link">names</a></span><span class="op">(</span><span class="va">latent</span><span class="op">)</span>, </span>
<span>                       <span class="op">~</span> <span class="fu">stringr</span><span class="fu">::</span><span class="fu"><a href="https://stringr.tidyverse.org/reference/str_detect.html" class="external-link">str_detect</a></span><span class="op">(</span><span class="va">formula</span>, <span class="va">.x</span><span class="op">)</span><span class="op">)</span></span>
<span>  </span>
<span>  <span class="co"># 4) Include measurement models in the formula using lavaan syntax</span></span>
<span>  <span class="va">formula</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/base/paste.html" class="external-link">paste</a></span><span class="op">(</span><span class="va">formula</span>, <span class="st">"\n"</span>,</span>
<span>                   <span class="fu"><a href="https://rdrr.io/r/base/paste.html" class="external-link">paste</a></span><span class="op">(</span><span class="va">latent</span><span class="op">[</span><span class="va">valid</span><span class="op">]</span>, </span>
<span>                         collapse <span class="op">=</span> <span class="st">" \n "</span><span class="op">)</span><span class="op">)</span></span>
<span>  </span>
<span>  <span class="co"># 5) Run SEM with sem function</span></span>
<span>  <span class="fu"><a href="https://rdrr.io/pkg/lavaan/man/sem.html" class="external-link">sem</a></span><span class="op">(</span><span class="va">formula</span>, <span class="va">data</span><span class="op">)</span></span>
<span><span class="op">}</span></span>
<span></span>
<span><span class="co"># In short:</span></span>
<span><span class="va">sem_custom</span> <span class="op">&lt;-</span> <span class="kw">function</span><span class="op">(</span><span class="va">formula</span>, <span class="va">data</span><span class="op">)</span> <span class="op">{</span></span>
<span>  <span class="kw"><a href="https://rdrr.io/r/base/library.html" class="external-link">require</a></span><span class="op">(</span><span class="va"><a href="https://lavaan.ugent.be" class="external-link">lavaan</a></span><span class="op">)</span></span>
<span>  <span class="va">latent</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/base/list.html" class="external-link">list</a></span><span class="op">(</span>visual <span class="op">=</span>  <span class="st">"visual  =~ x1 + x2 + x3"</span>,</span>
<span>                 textual <span class="op">=</span> <span class="st">"textual =~ x4 + x5 + x6"</span>,</span>
<span>                 speed <span class="op">=</span>   <span class="st">"speed   =~ x7 + x8 + x9"</span><span class="op">)</span></span>
<span>  <span class="va">formula</span> <span class="op">&lt;-</span> <span class="fu">stringr</span><span class="fu">::</span><span class="fu"><a href="https://stringr.tidyverse.org/reference/str_remove.html" class="external-link">str_remove_all</a></span><span class="op">(</span><span class="va">formula</span>, <span class="st">"\\+ 1"</span><span class="op">)</span></span>
<span>  <span class="va">valid</span> <span class="op">&lt;-</span> <span class="fu">purrr</span><span class="fu">::</span><span class="fu"><a href="https://purrr.tidyverse.org/reference/keep.html" class="external-link">keep</a></span><span class="op">(</span><span class="fu"><a href="https://rdrr.io/r/base/names.html" class="external-link">names</a></span><span class="op">(</span><span class="va">latent</span><span class="op">)</span>, <span class="op">~</span> <span class="fu">stringr</span><span class="fu">::</span><span class="fu"><a href="https://stringr.tidyverse.org/reference/str_detect.html" class="external-link">str_detect</a></span><span class="op">(</span><span class="va">formula</span>, <span class="va">.x</span><span class="op">)</span><span class="op">)</span></span>
<span>  <span class="va">formula</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/base/paste.html" class="external-link">paste</a></span><span class="op">(</span><span class="va">formula</span>, <span class="st">"\n"</span>, <span class="fu"><a href="https://rdrr.io/r/base/paste.html" class="external-link">paste</a></span><span class="op">(</span><span class="va">latent</span><span class="op">[</span><span class="va">valid</span><span class="op">]</span>, collapse <span class="op">=</span> <span class="st">" \n "</span><span class="op">)</span><span class="op">)</span></span>
<span>  <span class="fu"><a href="https://rdrr.io/pkg/lavaan/man/sem.html" class="external-link">sem</a></span><span class="op">(</span><span class="va">formula</span>, <span class="va">data</span><span class="op">)</span></span>
<span><span class="op">}</span></span></code></pre></div>
</div>
<div class="section level3">
<h3 id="run-the-specification-curve-analysis-with-additional-parameters">Run the specification curve analysis with additional parameters<a class="anchor" aria-label="anchor" href="#run-the-specification-curve-analysis-with-additional-parameters"></a>
</h3>
<p>Now we use <code><a href="../reference/setup.html">setup()</a></code> like we are used to. We only include
the new function as model parameter and use the latent variables (see
named list in the custom function) as depended variables. Warning
messages may appear if models do not converge or have other issues.</p>
<div class="sourceCode" id="cb5"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="co"># Setup specs</span></span>
<span><span class="va">specs</span> <span class="op">&lt;-</span> <span class="fu"><a href="../reference/setup.html">setup</a></span><span class="op">(</span>data <span class="op">=</span> <span class="va">d</span>,</span>
<span>               y <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"textual"</span>, <span class="st">"visual"</span>, <span class="st">"speed"</span><span class="op">)</span>,</span>
<span>               x <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"ageyr"</span><span class="op">)</span>,</span>
<span>               model <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"sem_custom"</span><span class="op">)</span>,</span>
<span>               controls <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"grade"</span><span class="op">)</span>,</span>
<span>               subsets <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/list.html" class="external-link">list</a></span><span class="op">(</span>sex <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/unique.html" class="external-link">unique</a></span><span class="op">(</span><span class="va">d</span><span class="op">$</span><span class="va">sex</span><span class="op">)</span>,</span>
<span>                              school <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/unique.html" class="external-link">unique</a></span><span class="op">(</span><span class="va">d</span><span class="op">$</span><span class="va">school</span><span class="op">)</span><span class="op">)</span><span class="op">)</span></span>
<span></span>
<span><span class="co"># Summarize specifications</span></span>
<span><span class="fu"><a href="https://rdrr.io/r/base/summary.html" class="external-link">summary</a></span><span class="op">(</span><span class="va">specs</span>, row <span class="op">=</span> <span class="fl">10</span><span class="op">)</span></span>
<span><span class="co">#&gt; Setup for the Specification Curve Analysis</span></span>
<span><span class="co">#&gt; -------------------------------------------</span></span>
<span><span class="co">#&gt; Class:                      specr.setup -- version: 1.0.1 </span></span>
<span><span class="co">#&gt; Number of specifications:   54 </span></span>
<span><span class="co">#&gt; </span></span>
<span><span class="co">#&gt; Specifications:</span></span>
<span><span class="co">#&gt; </span></span>
<span><span class="co">#&gt;   Independent variable:     ageyr </span></span>
<span><span class="co">#&gt;   Dependent variable:       textual, visual, speed </span></span>
<span><span class="co">#&gt;   Models:                   sem_custom </span></span>
<span><span class="co">#&gt;   Covariates:               no covariates, grade </span></span>
<span><span class="co">#&gt;   Subsets analyses:         1 &amp; Pasteur, 2 &amp; Pasteur, Pasteur, 1 &amp; Grant-White, 2 &amp; Grant-White, Grant-White, 1, 2, all </span></span>
<span><span class="co">#&gt; </span></span>
<span><span class="co">#&gt; Function used to extract parameters:</span></span>
<span><span class="co">#&gt; </span></span>
<span><span class="co">#&gt;   function (x) </span></span>
<span><span class="co">#&gt; broom::tidy(x, conf.int = TRUE)</span></span>
<span><span class="co">#&gt; &lt;environment: 0x7fc4ae4c4a00&gt;</span></span>
<span><span class="co">#&gt; </span></span>
<span><span class="co">#&gt; </span></span>
<span><span class="co">#&gt; Head of specifications table (first 10 rows):</span></span>
<span><span class="co">#&gt; <span style="color: #949494;"># A tibble: 10 × 8</span></span></span>
<span><span class="co">#&gt;    x     y       model      controls      subsets         sex   school   formula</span></span>
<span><span class="co">#&gt;    <span style="color: #949494; font-style: italic;">&lt;chr&gt;</span> <span style="color: #949494; font-style: italic;">&lt;chr&gt;</span>   <span style="color: #949494; font-style: italic;">&lt;chr&gt;</span>      <span style="color: #949494; font-style: italic;">&lt;chr&gt;</span>         <span style="color: #949494; font-style: italic;">&lt;chr&gt;</span>           <span style="color: #949494; font-style: italic;">&lt;fct&gt;</span> <span style="color: #949494; font-style: italic;">&lt;fct&gt;</span>    <span style="color: #949494; font-style: italic;">&lt;glue&gt;</span> </span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 1</span> ageyr textual sem_custom no covariates 1 &amp; Pasteur     1     Pasteur  textua…</span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 2</span> ageyr textual sem_custom no covariates 2 &amp; Pasteur     2     Pasteur  textua…</span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 3</span> ageyr textual sem_custom no covariates Pasteur         <span style="color: #BB0000;">NA</span>    Pasteur  textua…</span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 4</span> ageyr textual sem_custom no covariates 1 &amp; Grant-White 1     Grant-W… textua…</span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 5</span> ageyr textual sem_custom no covariates 2 &amp; Grant-White 2     Grant-W… textua…</span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 6</span> ageyr textual sem_custom no covariates Grant-White     <span style="color: #BB0000;">NA</span>    Grant-W… textua…</span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 7</span> ageyr textual sem_custom no covariates 1               1     <span style="color: #BB0000;">NA</span>       textua…</span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 8</span> ageyr textual sem_custom no covariates 2               2     <span style="color: #BB0000;">NA</span>       textua…</span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 9</span> ageyr textual sem_custom no covariates all             <span style="color: #BB0000;">NA</span>    <span style="color: #BB0000;">NA</span>       textua…</span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">10</span> ageyr textual sem_custom grade         1 &amp; Pasteur     1     Pasteur  textua…</span></span></code></pre></div>
<p>Within the specification table, we don’t really see much difference
compared to standard models such as e.g., “lm”. However, in the formula,
variables refer to latent variables as specified in the custom
function.</p>
<p>If we know pass it to <code><a href="../reference/specr.html">specr()</a></code>, actual structural
equation models will be fitted in the background.</p>
<div class="sourceCode" id="cb6"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="va">results</span> <span class="op">&lt;-</span> <span class="fu"><a href="../reference/specr.html">specr</a></span><span class="op">(</span><span class="va">specs</span><span class="op">)</span></span>
<span><span class="fu"><a href="https://rdrr.io/r/graphics/plot.default.html" class="external-link">plot</a></span><span class="op">(</span><span class="va">results</span>, choices <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"y"</span>, <span class="st">"controls"</span>, <span class="st">"model"</span>, <span class="st">"subsets"</span><span class="op">)</span><span class="op">)</span></span></code></pre></div>
<p><img src="measurement-models_files/figure-html/unnamed-chunk-6-1.png" width="100%"></p>
</div>
<div class="section level3">
<h3 id="additional-insights-from-lavaan-objects">Additional insights from “lavaan” objects<a class="anchor" aria-label="anchor" href="#additional-insights-from-lavaan-objects"></a>
</h3>
<p>Because the <code><a href="https://generics.r-lib.org/reference/tidy.html" class="external-link">broom::tidy()</a></code> functions also extracts
standardized coefficients, we can plot them on top of the unstandarized
coefficients with a little bit of extra code.</p>
<div class="sourceCode" id="cb7"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="co"># Create curve with standardized coefficients</span></span>
<span><span class="va">plot_a</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/graphics/plot.default.html" class="external-link">plot</a></span><span class="op">(</span><span class="va">results</span>, <span class="st">"curve"</span><span class="op">)</span> <span class="op">+</span> </span>
<span>    <span class="fu"><a href="https://ggplot2.tidyverse.org/reference/geom_point.html" class="external-link">geom_point</a></span><span class="op">(</span><span class="fu"><a href="https://ggplot2.tidyverse.org/reference/aes.html" class="external-link">aes</a></span><span class="op">(</span>y <span class="op">=</span> <span class="va">std.all</span>, alpha <span class="op">=</span> <span class="fl">.1</span>, size <span class="op">=</span> <span class="fl">1.25</span><span class="op">)</span><span class="op">)</span> <span class="op">+</span></span>
<span>    <span class="fu"><a href="https://ggplot2.tidyverse.org/reference/geom_abline.html" class="external-link">geom_hline</a></span><span class="op">(</span>yintercept <span class="op">=</span> <span class="fl">0</span>, linetype <span class="op">=</span> <span class="st">"dashed"</span><span class="op">)</span></span>
<span></span>
<span><span class="co"># Choice panel</span></span>
<span><span class="va">plot_b</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/graphics/plot.default.html" class="external-link">plot</a></span><span class="op">(</span><span class="va">results</span>, <span class="st">"choices"</span>,</span>
<span>               choices <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"y"</span>, <span class="st">"controls"</span>, <span class="st">"subsets"</span><span class="op">)</span><span class="op">)</span></span>
<span></span>
<span><span class="co"># Combine plots</span></span>
<span><span class="fu"><a href="https://wilkelab.org/cowplot/reference/plot_grid.html" class="external-link">plot_grid</a></span><span class="op">(</span><span class="va">plot_a</span>, <span class="va">plot_b</span>,</span>
<span>          ncol <span class="op">=</span> <span class="fl">1</span>,           </span>
<span>          align <span class="op">=</span> <span class="st">"v"</span>,            </span>
<span>          axis <span class="op">=</span> <span class="st">"rbl"</span>,            </span>
<span>          rel_heights <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="fl">1.5</span>, <span class="fl">2</span><span class="op">)</span><span class="op">)</span>  </span></code></pre></div>
<p><img src="measurement-models_files/figure-html/unnamed-chunk-7-1.png" width="100%"></p>
<p>Some fit indices are already included in the result data frame by
default. With a few code lines, we can plot the distribution of these
fit indices across all specifications.</p>
<div class="sourceCode" id="cb8"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="co"># Looking at included fit indices</span></span>
<span><span class="va">results</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%&gt;%</a></span></span>
<span>  <span class="va">as_tibble</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%&gt;%</a></span></span>
<span>  <span class="fu"><a href="https://dplyr.tidyverse.org/reference/select.html" class="external-link">select</a></span><span class="op">(</span><span class="va">x</span>, <span class="va">y</span>, <span class="va">model</span>, <span class="va">controls</span>, <span class="va">subsets</span>, </span>
<span>         <span class="va">fit_cfi</span>, <span class="va">fit_tli</span>, <span class="va">fit_rmsea</span><span class="op">)</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%&gt;%</a></span></span>
<span>  <span class="va">head</span></span>
<span><span class="co">#&gt; <span style="color: #949494;"># A tibble: 6 × 8</span></span></span>
<span><span class="co">#&gt;   x     y       model      controls      subsets       fit_cfi fit_tli fit_rmsea</span></span>
<span><span class="co">#&gt;   <span style="color: #949494; font-style: italic;">&lt;chr&gt;</span> <span style="color: #949494; font-style: italic;">&lt;chr&gt;</span>   <span style="color: #949494; font-style: italic;">&lt;chr&gt;</span>      <span style="color: #949494; font-style: italic;">&lt;chr&gt;</span>         <span style="color: #949494; font-style: italic;">&lt;chr&gt;</span>           <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span>   <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span>     <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">1</span> ageyr textual sem_custom no covariates 1 &amp; Pasteur     0.991   0.974    0.083<span style="text-decoration: underline;">4</span></span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">2</span> ageyr textual sem_custom no covariates 2 &amp; Pasteur     1       1.02     0     </span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">3</span> ageyr textual sem_custom no covariates Pasteur         1       1.01     0     </span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">4</span> ageyr textual sem_custom no covariates 1 &amp; Grant-Wh…   0.975   0.926    0.132 </span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">5</span> ageyr textual sem_custom no covariates 2 &amp; Grant-Wh…   0.949   0.847    0.209 </span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">6</span> ageyr textual sem_custom no covariates Grant-White     1       1.02     0</span></span>
<span></span>
<span><span class="co"># Create curve plot</span></span>
<span><span class="va">p1</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/graphics/plot.default.html" class="external-link">plot</a></span><span class="op">(</span><span class="va">results</span>, <span class="st">"curve"</span>, var <span class="op">=</span> <span class="va">fit_cfi</span>, ci <span class="op">=</span> <span class="cn">FALSE</span><span class="op">)</span> <span class="op">+</span></span>
<span>  <span class="fu"><a href="https://ggplot2.tidyverse.org/reference/geom_path.html" class="external-link">geom_line</a></span><span class="op">(</span><span class="fu"><a href="https://ggplot2.tidyverse.org/reference/aes.html" class="external-link">aes</a></span><span class="op">(</span>x <span class="op">=</span> <span class="va">specifications</span>, y <span class="op">=</span> <span class="va">fit_cfi</span><span class="op">)</span>, color <span class="op">=</span> <span class="st">"grey"</span><span class="op">)</span> <span class="op">+</span></span>
<span>  <span class="fu"><a href="https://ggplot2.tidyverse.org/reference/geom_point.html" class="external-link">geom_point</a></span><span class="op">(</span>size <span class="op">=</span> <span class="fl">2</span>, shape <span class="op">=</span> <span class="fl">18</span><span class="op">)</span> <span class="op">+</span> <span class="co"># increasing size of points</span></span>
<span>  <span class="fu"><a href="https://ggplot2.tidyverse.org/reference/geom_path.html" class="external-link">geom_line</a></span><span class="op">(</span><span class="fu"><a href="https://ggplot2.tidyverse.org/reference/aes.html" class="external-link">aes</a></span><span class="op">(</span>x <span class="op">=</span> <span class="va">specifications</span>, y <span class="op">=</span> <span class="va">fit_rmsea</span><span class="op">)</span>, color <span class="op">=</span> <span class="st">"grey"</span><span class="op">)</span> <span class="op">+</span></span>
<span>  <span class="fu"><a href="https://ggplot2.tidyverse.org/reference/geom_point.html" class="external-link">geom_point</a></span><span class="op">(</span><span class="fu"><a href="https://ggplot2.tidyverse.org/reference/aes.html" class="external-link">aes</a></span><span class="op">(</span>x <span class="op">=</span> <span class="va">specifications</span>, y <span class="op">=</span> <span class="va">fit_rmsea</span><span class="op">)</span>, shape <span class="op">=</span> <span class="fl">20</span>, size <span class="op">=</span> <span class="fl">2</span><span class="op">)</span> <span class="op">+</span></span>
<span>  <span class="fu"><a href="https://ggplot2.tidyverse.org/reference/lims.html" class="external-link">ylim</a></span><span class="op">(</span><span class="fl">0</span>, <span class="fl">1</span><span class="op">)</span> <span class="op">+</span></span>
<span>  <span class="fu"><a href="https://ggplot2.tidyverse.org/reference/labs.html" class="external-link">labs</a></span><span class="op">(</span>y <span class="op">=</span> <span class="st">"cfi &amp; rmsea"</span><span class="op">)</span></span>
<span></span>
<span><span class="co"># Create choice panel with chisq arrangement</span></span>
<span><span class="va">p2</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/graphics/plot.default.html" class="external-link">plot</a></span><span class="op">(</span><span class="va">results</span>, <span class="st">"choices"</span>, var <span class="op">=</span> <span class="va">fit_cfi</span>, </span>
<span>           choices <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"y"</span>, <span class="st">"controls"</span>, <span class="st">"subsets"</span><span class="op">)</span><span class="op">)</span></span>
<span></span>
<span><span class="co"># Bind together</span></span>
<span><span class="fu"><a href="https://wilkelab.org/cowplot/reference/plot_grid.html" class="external-link">plot_grid</a></span><span class="op">(</span><span class="va">p1</span>, <span class="va">p2</span>,</span>
<span>          ncol <span class="op">=</span> <span class="fl">1</span>,           </span>
<span>          align <span class="op">=</span> <span class="st">"v"</span>,            </span>
<span>          axis <span class="op">=</span> <span class="st">"rbl"</span>,            </span>
<span>          rel_heights <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="fl">1.5</span>, <span class="fl">2</span><span class="op">)</span><span class="op">)</span></span></code></pre></div>
<p><img src="measurement-models_files/figure-html/unnamed-chunk-8-1.png" width="100%"></p>
</div>
</div>
  </div>

  <div class="col-md-3 hidden-xs hidden-sm" id="pkgdown-sidebar">

        <nav id="toc" data-toggle="toc"><h2 data-toc-skip>Contents</h2>
    </nav>
</div>

</div>



      <footer><div class="copyright">
  <p></p>
<p>Developed by Philipp K. Masur, Michael Scharkow.</p>
</div>

<div class="pkgdown">
  <p></p>
<p>Site built with <a href="https://pkgdown.r-lib.org/" class="external-link">pkgdown</a> 2.0.7.</p>
</div>

      </footer>
</div>

  


  

  </body>
</html>
