<?xml version="1.0" encoding="UTF-8"?>
<rss  xmlns:atom="http://www.w3.org/2005/Atom" 
      xmlns:media="http://search.yahoo.com/mrss/" 
      xmlns:content="http://purl.org/rss/1.0/modules/content/" 
      xmlns:dc="http://purl.org/dc/elements/1.1/" 
      version="2.0">
<channel>
<title>Matti&#39;s website</title>
<link>https://vuorre.com/blog.html</link>
<atom:link href="https://vuorre.com/blog.xml" rel="self" type="application/rss+xml"/>
<description>Matti&#39;s website</description>
<generator>quarto-1.8.27</generator>
<lastBuildDate>Mon, 13 Oct 2025 22:00:00 GMT</lastBuildDate>
<item>
  <title>Against publishing</title>
  <dc:creator>Matti Vuorre</dc:creator>
  <link>https://vuorre.com/posts/preprints-opinion/</link>
  <description><![CDATA[ 





<p>385 days ago, I submitted a manuscript for evaluation at an academic journal. Around the same time, I submitted the same manuscript to <a href="https://osf.io/preprints/psyarxiv">PsyArXiv</a>, a document sharing website popular in the psychological sciences. The results: Radio silence for the journal submission; 356 downloads and 5 citations for the <a href="https://osf.io/preprints/psyarxiv/mwg4f">PsyArXiv version</a>.</p>
<p>But this is a meaningless comparison: The PsyArXiv version hasn’t been peer-reviewed and listed on a journal’s website: It is not <em>published</em>, and everyone knows that publications are more valid than preprints, and that it is publications, not preprints, that provide the pitons on a scientist’s climb to success and fame.</p>
<p>Never mind that my colleagues are reading and citing the document on PsyArXiv. For this manuscript to count as a legitimate scientific product I must first endure inexplicable delays; arbitrary formatting requirements (the formatting manual costs $47.99); conflicts between <a href="https://en.wikipedia.org/wiki/Mertonian_norms#Four_Mertonian_norms">my scholarly values</a> and the <a href="https://astro.theoj.org/post/168-">astronomical profits</a> that <a href="https://www.theguardian.com/commentisfree/2011/aug/29/academic-publishers-murdoch-socialist">private publishing companies</a> make from our taxpayer funded work; introduction of errors into my manuscript by the journal’s proofreaders; websites from hell; and of course peer review. Without that process of publication, my work will remain a “<em>preprint</em>”—an incomplete and unreliable artifact unworthy of a place in the scientific literature.</p>
<p>Could <a href="https://osf.io/preprints/psyarxiv/2uxwk_v1">things be better</a>? I surmise that, like fish unaware of their wet surrounds, academics don’t feel the pain because it’s all they’ve ever known.</p>
<p>For one, peer review has nothing to do with commercial journals or publishers—it’s the voluntary labor of our colleagues in service of scientific progress. We could, right now, be reviewing each others work on <a href="https://prereview.org/">PREreview</a> or <a href="https://www.reviewcommons.org/">Review Commons</a>. Alas, instead of these scholarly debates we are complacent with pretending that a <a href="https://theconversation.com/academic-publishing-is-a-multibillion-dollar-industry-its-not-always-good-for-science-250056">40% profit margin industry</a> is somehow facilitating the peer-review process better than the transparent platforms already available to us, for free.</p>
<p>Neither does the role of an editor have to be tied to a <a href="https://www.abc.net.au/religion/nicholas-agar-big-academic-publishing-rent-seeking-behaviour/104066062">commercial rent-seeker</a>: The <a href="https://elifesciences.org/inside-elife/dc24a9cd/open-science-what-is-publish-review-curate">Publish, Review, Curate</a> model of scholarly communication enables a given scholarly work to be included in a plurality of collections, perhaps analogous to journal volumes or blog categories, each curated by different editors on different platforms. Many editorial teams are already recognizing that things could indeed be better, and are <a href="https://retractionwatch.com/the-retraction-watch-mass-resignations-list/">resigning en masse</a> to start free scholar-run journals.</p>
<p>These <a href="https://knowledge-exchange.pubpub.org/pub/73tb00rf/release/3">alternatives</a> to “<a href="https://www.abc.net.au/religion/nicholas-agar-humanities-phamphlets-big-academic-publishing/103729186">Big Academic Publishing</a>” are already making it faster and <a href="https://peercommunityin.org/2025/01/08/2024-pcis-finances-and-article-costs/">cheaper</a> to get one’s work permanently available and findable online, vetted by editors, and reviewed by peers.</p>
<p>Considering the <a href="https://doi.org/10.48550/arXiv.2407.16551">estimated $8.97 billion dollars</a> of (mostly) taxpayer money hoovered up in four years by only six commercial publishers on Open Access (OA) article processing fees, Elsevier’s $3,480 median hybrid OA processing fee, and an <a href="https://doi.org/10.1162/qss_a_00327">average turnaround time of 111 days</a>, alternatives fare well: <a href="https://peercommunityin.org/">Peer Community In</a>, an online platform for reviews and “recommendations” (brief editorial reports), reports total <a href="https://peercommunityin.org/2025/01/08/2024-pcis-finances-and-article-costs/">costs of €369 per article</a>. We’ve known these flawed economics for decades, yet the scientific literature remains in captivity. Maybe we just lack the <a href="https://www.scottaaronson.com/writings/journal.html">sufficient anger</a> for change.</p>
<p>Perhaps the time to <a href="https://doi.org/10.1098/rsos.230206">replace academic journals</a> is now. For me, it should have been 350 days ago.</p>


<div id="quarto-appendix" class="default"><section id="article-information" class="level2 appendix"><h2 class="anchored quarto-appendix-heading">Article information</h2><div class="quarto-appendix-contents">

<p>This write-up is available at <a href="https://vuorre.com/posts/preprints-opinion/" class="uri">https://vuorre.com/posts/preprints-opinion/</a> and <a href="https://universonline.nl/nieuws/2025/10/14/against-publishing/" class="uri">https://universonline.nl/nieuws/2025/10/14/against-publishing/</a> under a CC-0 license.</p>


</div></section><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/publicdomain/zero/1.0/">CC0 1.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{vuorre2025,
  author = {Vuorre, Matti},
  title = {Against Publishing},
  date = {2025-10-14},
  url = {https://vuorre.com/posts/preprints-opinion/},
  langid = {en},
  abstract = {Preprints-\/-\/-scholarly manuscripts not yet captured by
    the publication industry-\/-\/-are widely read and circulated, yet
    the “{[}intellectual
    perestroika{]}(https://eprints.soton.ac.uk/251894/1/harnad90.skywriting.html)”
    they could facilitate hasn’t been uniformly realized because
    scholars continue to think of preprints as less authoritative than
    their industry-captured (“published”) counterparts. It is time to
    free the scholarly literature from hostile captivity and embrace
    preprints as the primary objects of scholarly communication. This
    post first appeared at
    {[}Univers{]}(https://universonline.nl/nieuws/2025/10/14/against-publishing/).}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-vuorre2025" class="csl-entry quarto-appendix-citeas">
Vuorre, Matti. 2025. <span>“Against Publishing.”</span> October 14,
2025. <a href="https://vuorre.com/posts/preprints-opinion/">https://vuorre.com/posts/preprints-opinion/</a>.
</div></div></section></div> ]]></description>
  <category>opinion</category>
  <category>research</category>
  <guid>https://vuorre.com/posts/preprints-opinion/</guid>
  <pubDate>Mon, 13 Oct 2025 22:00:00 GMT</pubDate>
</item>
<item>
  <title>My PsyArXiv coauthorship network</title>
  <dc:creator>Matti Vuorre</dc:creator>
  <link>https://vuorre.com/posts/psyarxiv-network/</link>
  <description><![CDATA[ 





<p><a href="https://osf.io/preprints/psyarxiv">PsyArXiv</a> is the leading free preprint service for the psychological sciences, maintained by <a href="http://improvingpsych.org/">The Society for the Improvement of Psychological Science</a> and powered by <a href="https://osf.io/preprints">OSF Preprints</a>. Today, PsyArXiv hosts 45924 preprints from 166674 contributors<sup>1</sup>. Beyond these basic statistics, the OSF API (<a href="https://developer.osf.io/#tag/Preprints">link to documentation</a>) makes a wealth of data available, but interacting with the API can be cumbersome and slow.</p>
<p>To make PsyArXiv data more accessible, <a href="https://github.com/mvuorre/psyarxivr">psyarxivr</a> provides metadata for all PsyArXiv preprints in a single table as an R package. In this post, I show how to use data from psyarxivr to create a single person’s second-degree coauthorship network.</p>
<section id="getting-started" class="level2">
<h2 class="anchored" data-anchor-id="getting-started">Getting started</h2>
<p>I first load the required packages: <a href="https://github.com/tidyverse/tidyverse">tidyverse</a> for general purpose wrangling, <a href="https://github.com/thomasp85/patchwork/">patchwork</a> for combining plots, <a href="https://github.com/jeroen/jsonlite">jsonlite</a> for processing JSON data, and <a href="https://github.com/mvuorre/psyarxivr">psyarxivr</a> for the data.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(tidyverse)</span>
<span id="cb1-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(patchwork)</span>
<span id="cb1-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(jsonlite)</span>
<span id="cb1-4"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(psyarxivr)</span></code></pre></div></div>
</div>
</section>
<section id="data-wrangling" class="level2">
<h2 class="anchored" data-anchor-id="data-wrangling">Data wrangling</h2>
<p>The psyarxivr package, when loaded as above, provides access to the <code>preprints</code> table. Below, we take our focal variables <code>id</code> (for each preprint) and <code>contributors</code>, which contains the contributor data as JSON strings.</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Click to show/hide code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb2-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Parse contributors JSON variable into its own table with preprint ids</span></span>
<span id="cb2-2">contributors <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> preprints <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-3">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Remove preprints with no contributor data and non-latest versions</span></span>
<span id="cb2-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(contributors <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"[]"</span>, is_latest_version <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-5">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Select required variables only</span></span>
<span id="cb2-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(id, contributors) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-7">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Convert JSON into data frames in a list-column</span></span>
<span id="cb2-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(</span>
<span id="cb2-9">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">contributors =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">map</span>(</span>
<span id="cb2-10">      contributors,</span>
<span id="cb2-11">      fromJSON</span>
<span id="cb2-12">    )</span>
<span id="cb2-13">  )</span>
<span id="cb2-14"></span>
<span id="cb2-15"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Unnest into a table of contributors and clean</span></span>
<span id="cb2-16">contributors <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> contributors <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-17">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">unnest</span>(contributors) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-18">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Only include bibliographic authors</span></span>
<span id="cb2-19">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(bibliographic) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-20">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Remove some other contributor variables and rename</span></span>
<span id="cb2-21">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(id, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> full_name) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-22">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Take out unnamed contributors</span></span>
<span id="cb2-23">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(name <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span>)</span>
<span id="cb2-24"></span>
<span id="cb2-25"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Calculate total number of contributors</span></span>
<span id="cb2-26">contributors_total <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">nrow</span>(contributors)</span></code></pre></div></div>
</details>
</div>
<p>In this post I’m only interested in my own coauthorship network. The <code>contributors</code> table now has rows for each preprint’s contributors. I first filter it to only include preprints on which I was a coauthor (retaining all authors of the preprints):</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb3-1">my_coauthors <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> contributors <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-2">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Retain all preprints where any of the authors was me</span></span>
<span id="cb3-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">any</span>(name <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Matti Vuorre"</span>), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.by =</span> id)</span>
<span id="cb3-4"></span>
<span id="cb3-5">my_coauthors</span>
<span id="cb3-6"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## # A tibble: 90 × 2</span></span>
<span id="cb3-7"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">##   id       name               </span></span>
<span id="cb3-8"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">##   &lt;chr&gt;    &lt;chr&gt;              </span></span>
<span id="cb3-9"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## 1 qrjza_v1 Niklas Johannes    </span></span>
<span id="cb3-10"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## 2 qrjza_v1 Matti Vuorre       </span></span>
<span id="cb3-11"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## 3 qrjza_v1 Andrew K Przybylski</span></span>
<span id="cb3-12"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## # ℹ 87 more rows</span></span></code></pre></div></div>
</details>
</div>
<p>Above, <code>id</code> is the preprint’s OSF ID, and each has one or more <code>name</code>s of the preprints’ contributors.</p>
<p>If I created a graph from these data, it would only show my immediate collaborators, but I wish to expand it to show their other collaborators as well. To do so, I filter the original contributor data to include only preprints that have one or more authors who appear as contributors on any of my preprints:</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb4-1">my_coauthors_coauthors <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> contributors <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb4-2">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Retain all preprints where any author was my coauthor</span></span>
<span id="cb4-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">any</span>(name <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%in%</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">unique</span>(my_coauthors<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>name)), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.by =</span> id)</span>
<span id="cb4-4"></span>
<span id="cb4-5">my_coauthors_coauthors</span>
<span id="cb4-6"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## # A tibble: 1,195 × 2</span></span>
<span id="cb4-7"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">##   id       name                  </span></span>
<span id="cb4-8"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">##   &lt;chr&gt;    &lt;chr&gt;                 </span></span>
<span id="cb4-9"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## 1 zzbka_v1 Andrew K Przybylski   </span></span>
<span id="cb4-10"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## 2 zzbka_v1 Antonius J. van Rooij </span></span>
<span id="cb4-11"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## 3 zzbka_v1 Michelle Colder Carras</span></span>
<span id="cb4-12"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## # ℹ 1,192 more rows</span></span></code></pre></div></div>
</details>
</div>
<p>There are 1195 individual contributions to preprints that were either coauthored by me, or any of my coauthors. This is the data I’ll use to construct what I call my second-degree PsyArXiv coauthor network graph.</p>
<section id="creating-the-graph" class="level3">
<h3 class="anchored" data-anchor-id="creating-the-graph">Creating the graph</h3>
<p>Here’s the graph-related packages I’ll use. Most of the actual network analysis functionality comes from the <a href="https://github.com/igraph/rigraph/">igraph</a> package, but <a href="https://github.com/thomasp85/tidygraph">tidygraph</a> wraps those into syntax that I find easier to understand. <a href="https://github.com/thomasp85/ggraph">ggraph</a> allows plotting the data with <a href="https://github.com/tidyverse/ggplot2">ggplot2</a>.</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb5-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(tidygraph)</span>
<span id="cb5-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(ggraph)</span></code></pre></div></div>
</details>
</div>
<p>I then need to convert the table of (my 2nd degree) coauthors to a suitable format for creating graphs. To do so I first expand the long-format table to a table of edges:</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb6-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Get all pairs of co-authors for each paper and count collaborations</span></span>
<span id="cb6-2">edges <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> my_coauthors_coauthors <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb6-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(id) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb6-4">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Create all pairwise combinations within each paper</span></span>
<span id="cb6-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">reframe</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">expand.grid</span>(</span>
<span id="cb6-6">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">author1 =</span> name,</span>
<span id="cb6-7">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">author2 =</span> name,</span>
<span id="cb6-8">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">stringsAsFactors =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span></span>
<span id="cb6-9">  )) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb6-10">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Remove self-loops and order pairs for undirected edges</span></span>
<span id="cb6-11">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(author1 <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> author2) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb6-12">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rename</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">from =</span> author1, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">to =</span> author2)</span>
<span id="cb6-13"></span>
<span id="cb6-14">edges</span>
<span id="cb6-15"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## # A tibble: 2,624 × 3</span></span>
<span id="cb6-16"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">##   id       from         to             </span></span>
<span id="cb6-17"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">##   &lt;chr&gt;    &lt;chr&gt;        &lt;chr&gt;          </span></span>
<span id="cb6-18"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## 1 2erwy_v1 Harm Veling  Niklas Johannes</span></span>
<span id="cb6-19"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## 2 2erwy_v1 Jonas Dora   Niklas Johannes</span></span>
<span id="cb6-20"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## 3 2erwy_v1 Adrian Meier Niklas Johannes</span></span>
<span id="cb6-21"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## # ℹ 2,621 more rows</span></span></code></pre></div></div>
</details>
</div>
<p>In this table, all contributors co-occurring in a preprint are represented as <code>from</code>-<code>to</code> pairs. As you can see from the roughness of that code, it took me some hacking around to accomplish this.</p>
<p>Then, I use convenience functions from <a href="https://github.com/thomasp85/tidygraph">tidygraph</a> to convert the <code>edges</code> data frame to a graph, and calculate each coauthors’ (“nodes”) distance from me. I took a social network analysis about a decade ago so details &amp; code below are likely to be a bit dodgy: Let me know if you see room for improvement.</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb7-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Create graph with key metrics</span></span>
<span id="cb7-2">graph <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> edges <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_tbl_graph</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">directed =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(</span>
<span id="cb7-5">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">distance =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">factor</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">node_distance_from</span>(name <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Matti Vuorre"</span>))</span>
<span id="cb7-6">  )</span>
<span id="cb7-7"></span>
<span id="cb7-8">graph</span>
<span id="cb7-9"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## # A tbl_graph: 567 nodes and 2624 edges</span></span>
<span id="cb7-10"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## #</span></span>
<span id="cb7-11"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## # An undirected multigraph with 1 component</span></span>
<span id="cb7-12"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## #</span></span>
<span id="cb7-13"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## # Node Data: 567 × 2 (active)</span></span>
<span id="cb7-14"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">##    name                distance</span></span>
<span id="cb7-15"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">##    &lt;chr&gt;               &lt;fct&gt;   </span></span>
<span id="cb7-16"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">##  1 Harm Veling         2       </span></span>
<span id="cb7-17"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">##  2 Jonas Dora          2       </span></span>
<span id="cb7-18"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">##  3 Adrian Meier        2       </span></span>
<span id="cb7-19"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">##  4 Leonard Reinecke    2       </span></span>
<span id="cb7-20"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">##  5 Moniek Buijzen      2       </span></span>
<span id="cb7-21"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">##  6 Donald R. Williams  2       </span></span>
<span id="cb7-22"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">##  7 Andrew K Przybylski 1       </span></span>
<span id="cb7-23"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">##  8 Nick Ballou         1       </span></span>
<span id="cb7-24"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">##  9 Tamás Andrei Földes 2       </span></span>
<span id="cb7-25"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## 10 Elina Renko         2       </span></span>
<span id="cb7-26"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## # ℹ 557 more rows</span></span>
<span id="cb7-27"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## #</span></span>
<span id="cb7-28"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## # Edge Data: 2,624 × 3</span></span>
<span id="cb7-29"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">##    from    to id      </span></span>
<span id="cb7-30"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">##   &lt;int&gt; &lt;int&gt; &lt;chr&gt;   </span></span>
<span id="cb7-31"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## 1     1   140 2erwy_v1</span></span>
<span id="cb7-32"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## 2     2   140 2erwy_v1</span></span>
<span id="cb7-33"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## 3     3   140 2erwy_v1</span></span>
<span id="cb7-34"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## # ℹ 2,621 more rows</span></span></code></pre></div></div>
</details>
</div>
</section>
</section>
<section id="visualizing-the-graph" class="level2 page-columns page-full">
<h2 class="anchored" data-anchor-id="visualizing-the-graph">Visualizing the graph</h2>
<p>With the data prepared we can now start constructing the plot. First, I’ll sketch a no-frills version that shows just the data with default settings. Perhaps the most critical option is <code>ggraph(layout = "fr")</code> which determines the layout algorithm. I recall “fr” being okay for these and it seems to work okay, but there are probably other better ones.</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb8-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">set.seed</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">999</span>)</span>
<span id="cb8-2">graph <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb8-3">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Create a ggplot with appropriate mappings for graph data</span></span>
<span id="cb8-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggraph</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">layout =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"fr"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb8-5">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Show edges</span></span>
<span id="cb8-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_edge_link</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb8-7">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Show nodes</span></span>
<span id="cb8-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_node_point</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb8-9">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># A blank theme</span></span>
<span id="cb8-10">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme_graph</span>()</span></code></pre></div></div>
</details>
</div>
<p>This figure would display the data all right, but the plot would be ugly and uninformative. To improve, I’ll specify and map more aesthetics (size et cetera) to variables in the data, highlight myself, add text labels to my coauthors, and adjust the colors and sizes of the elements.</p>
<div class="cell page-columns page-full">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb9-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">set.seed</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">999</span>)</span>
<span id="cb9-2">graph <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggraph</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">layout =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"fr"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb9-4">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Make edges less prominent</span></span>
<span id="cb9-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_edge_link</span>(</span>
<span id="cb9-6">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">linewidth =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.2</span>,</span>
<span id="cb9-7">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">alpha =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.4</span>,</span>
<span id="cb9-8">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">color =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gray70"</span></span>
<span id="cb9-9">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb9-10">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Nodes further from me are smaller</span></span>
<span id="cb9-11">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_node_point</span>(</span>
<span id="cb9-12">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> distance, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">color =</span> distance)</span>
<span id="cb9-13">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb9-14">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Add text to my (bold) &amp; coauthors' (plain) nodes</span></span>
<span id="cb9-15">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_node_text</span>(</span>
<span id="cb9-16">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> . <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(distance <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>),</span>
<span id="cb9-17">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(</span>
<span id="cb9-18">      <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">label =</span> name,</span>
<span id="cb9-19">      <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">fontface =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ifelse</span>(name <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Matti Vuorre"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"bold"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"plain"</span>)</span>
<span id="cb9-20">    ),</span>
<span id="cb9-21">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">repel =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>,</span>
<span id="cb9-22">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.1</span></span>
<span id="cb9-23">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb9-24">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Specify sizes, colors, and theme options</span></span>
<span id="cb9-25">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_size_manual</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb9-26">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_color_manual</span>(</span>
<span id="cb9-27">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dodgerblue4"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dodgerblue2"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dodgerblue1"</span>)</span>
<span id="cb9-28">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb9-29">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme_graph</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb9-30">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">legend.position =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"none"</span>)</span></code></pre></div></div>
</details>
<div class="cell-output-display page-columns page-full">
<div id="fig-2" class="quarto-float quarto-figure quarto-figure-center anchored page-columns page-full">
<figure class="quarto-float quarto-float-fig figure page-columns page-full">
<div aria-describedby="fig-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca" class="page-columns page-full">
<img src="https://vuorre.com/posts/psyarxiv-network/index_files/figure-html/fig-2-1.png" class="img-fluid figure-img column-screen-inset" width="1344">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;1: My 2nd degree PsyArXiv coauthor network.
</figcaption>
</figure>
</div>
</div>
</div>
<p>Looking at this graph, keep in mind that this is not my (or any of my coauthors, etc.) coauthorship network in the literature as a whole, but that of (the latest versions of) preprints posted on PsyArXiv. Having said that, it’s interesting to note that several of my 2nd-degree coauthors from two different 1st-degree coauthors connect through a third 1st-degree coauthor (Paul—no surprise; everyone wants to work with him!)</p>
</section>
<section id="conclusion" class="level2">
<h2 class="anchored" data-anchor-id="conclusion">Conclusion</h2>
<p>I wrote this post to take the <a href="https://github.com/mvuorre/psyarxivr">psyarxivr</a> R package for a test drive. I only looked at one variable from the preprints’ metadata table—although probably the richest one—and as such hope that others might find the data interesting and valuable. <a href="https://github.com/mvuorre/psyarxivr/issues">psyarxivr</a> if you have any issues with it.</p>


</section>


<div id="quarto-appendix" class="default"><section id="footnotes" class="footnotes footnotes-end-of-document"><h2 class="anchored quarto-appendix-heading">Footnotes</h2>

<ol>
<li id="fn1"><p>Numbers here refer to preprints’ latest versions and bibliographic authors only.↩︎</p></li>
</ol>
</section><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{vuorre2025,
  author = {Vuorre, Matti},
  title = {My {PsyArXiv} Coauthorship Network},
  date = {2025-09-24},
  url = {https://vuorre.com/posts/psyarxiv-network/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-vuorre2025" class="csl-entry quarto-appendix-citeas">
Vuorre, Matti. 2025. <span>“My PsyArXiv Coauthorship Network.”</span>
September 24, 2025. <a href="https://vuorre.com/posts/psyarxiv-network/">https://vuorre.com/posts/psyarxiv-network/</a>.
</div></div></section></div> ]]></description>
  <category>r</category>
  <category>research</category>
  <guid>https://vuorre.com/posts/psyarxiv-network/</guid>
  <pubDate>Tue, 23 Sep 2025 22:00:00 GMT</pubDate>
</item>
<item>
  <title>How I work on computationally reproducible academic projects</title>
  <dc:creator>Matti Vuorre</dc:creator>
  <link>https://vuorre.com/posts/workflow/</link>
  <description><![CDATA[ 





<p>Figure&nbsp;1 outlines an ideal but not fully fleshed out workflow in academic psychology: You receive an idea from divine inspiration, do <strong>?</strong>, and science comes out the other end.</p>
<div id="fig-underpants" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-underpants-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/workflow/images/underpants.jpg" class="img-fluid figure-img" style="width:80.0%">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-underpants-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;1: Underpant gnomes and the ideal scientific workflow. From <a href="https://en.wikipedia.org/wiki/Gnomes_(South_Park)">South Park</a>.
</figcaption>
</figure>
</div>
<p>There are loosely speaking <a href="https://plato.stanford.edu/entries/feyerabend/#AgaiMeth1970">as many answers</a> to what <strong>?</strong> signifies as there are practising scientists, and that might be fine, maybe, according to some prominent writers <span class="citation" data-cites="oberheimPaulFeyerabend2025">(Oberheim and Preston 2025)</span>.</p>
<p>But instead of philosophizing, here I talk about the day-to-day activities that fill the space between receiving an idea and science: What do I do after receiving an idea? How do I read and write scholarly works? How do I organize my materials and collaborate with others? How do I make my computations and manuscripts reproducible? Where do I put my materials such that they don’t just tick an “open data” checkbox but are actually <a href="https://www.go-fair.org/fair-principles/">findable and useable</a> by others? What kinds of tools fill my workshop and what programs do I run on my computers? And how do I (want to) publish the resulting write-ups?</p>
<p>This post is about providing my current answers to these kinds of questions. It is not really about teaching the tools (<a href="https://vuorre.com/posts/methods-syllabus/">here’s some links</a>), platforms, and methods I use. Instead, I outline the things I have to deal with, and how I bring them together to a workflow where tools (mostly) get out of my way to let work happen. The guiding principle here is to accept that a lot of science these days can be considered “amateur software development” (Figure&nbsp;2). So while some of this will be technical, ignoring the technical aspects of scientific work is counterproductive. Instead we might as well learn the tools of the trade.</p>
<div id="fig-dev" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-dev-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-video ratio ratio-16x9"><iframe data-external="1" src="https://www.youtube.com/embed/8qzVV7eEiaI" title="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe></div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-dev-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;2: Richard McElreath: “Software is both a cause of unreliable research and part of the solution. The bulk of scientific research relies upon specialized software for data management and analysis. The bad news is that much of this software is poorly tested and documented, and researchers often use software in unreliable ways. Part of the problem is that researchers are being asked to perform a job they have not been trained for: software development. The good news is that borrowing simple habits and open tools from software engineering brings huge benefits. Even more good news: Specialized curricula already exist to train scientists to develop and use these habits in their own research.”
</figcaption>
</figure>
</div>
<section id="curating-a-library" class="level2" data-number="1">
<h2 data-number="1" class="anchored" data-anchor-id="curating-a-library"><span class="header-section-number">1</span> Curating a library</h2>
<p>First, my idea is probably related to something that someone else has already written about. I collect those writings in my <a href="https://www.zotero.org/">Zotero</a> library. There are alternatives to Zotero but many of them, like Endnote, suck. Zotero is free, open source (extensible), and works well. What I do is I collect all the works I know about the topic into a Zotero collection (or <a href="https://www.zotero.org/groups/6037273/preprints-all-you-need/library">group library</a>). I then use online search engines to find more works. Most search engines suck, but <a href="https://scholar.google.com/">Google Scholar</a> sucks the least. When I’m on a website that has some relevant writing (books, articles), I click the little Zotero button in Firefox (requires the Zotero Connector <a href="https://www.zotero.org/download/">add-on</a>) and the piece is saved to my Zotero library.</p>
<p>If I intend to write a document, I have a related Zotero collection with probably around a hundred works, but this varies a lot depending on how much I know about the topic already. Since all the previous works were wrong, when I read and re-read them my aim is to figure out exactly how they were wrong and why, so I can be a little less wrong this time around: I will also be wrong but hopefully in a useful and transparent way <span class="citation" data-cites="scheelWhyMostPsychological2022">(Scheel 2022)</span>.</p>
</section>
<section id="reading" class="level2" data-number="2">
<h2 data-number="2" class="anchored" data-anchor-id="reading"><span class="header-section-number">2</span> Reading</h2>
<p>I then semirandomly find time—on trains, buses, and aeroplanes—to read and understand what others have thought and done about the topic. It’s important to keep in mind that they are all wrong—that’s the point of research; nobody knows what they’re doing—but you still need to know what others have done in order to stand on their shoulders: What are some common methods and ideas, how have people approached this idea in the past?</p>
<p>If you ask people whether they know how to read, most will answer “yes”. Most of them are wrong. Developing the mental models and methods required for efficiently going through scholarly writings takes time and effort. Fortunately, guides exist <span class="citation" data-cites="savageHowWhyRead2024 careyTenSimpleRules2020">(Savage 2024; Carey, Steiner, and Petri 2020)</span> and I’d recommend looking into those.</p>
<section id="peer-review" class="level3" data-number="2.1">
<h3 data-number="2.1" class="anchored" data-anchor-id="peer-review"><span class="header-section-number">2.1</span> Peer review</h3>
<p>Reviewing others’ work is a common purpose for reading and a key part of the scientific workflow. I think most people aren’t trained in this at all, and based on a casual memory search of the reviews I’ve received, it really shows. I try to follow advice put forth in <span class="citation" data-cites="davisPeerReviewGuidelinesPromoting2018">Davis et al. (2018)</span>, <span class="citation" data-cites="roedigerTwelveTipsReviewers2007">Roediger (2007)</span>, and <span class="citation" data-cites="lindsayDigestTipsReviewerspdf2017">Lindsay, Giner-Sorolla, and Sun (2017)</span>:</p>
<blockquote class="blockquote">
<p>“Remember the Golden Rule. Treat authors the way you’d want to be treated. Be respectful and remember that you can easily demoralize authors, especially students and young scholars. Keep insults and snide comments to yourself. Don’t hide behind a veil of anonymity to lob mean-spirited critiques that you wouldn’t share with the authors face to face.”</p>
<p>–Scott Lilienfeld in <span class="citation" data-cites="lindsayDigestTipsReviewerspdf2017">Lindsay, Giner-Sorolla, and Sun (2017)</span></p>
</blockquote>
<p>I also try <a href="../open-peer-review/">not to review</a> works that aren’t openly available online. It’s probably a good idea to openly license your reviews, so the publication industry can’t steal and subsequently hide/suppress your words, and make them <a href="https://prereview.org/profiles/0000-0001-5052-066X">available</a> online so all can learn from them.</p>
</section>
</section>
<section id="writing" class="level2" data-number="3">
<h2 data-number="3" class="anchored" data-anchor-id="writing"><span class="header-section-number">3</span> Writing</h2>
<p>After developing a sufficient understanding of what I’m doing and what others have thought about the topic, I start writing some words into a <a href="https://plain-text.co/">plain text</a> <span class="citation" data-cites="healyPlainPersonsGuide2019">(Healy 2019)</span> file. This file may or may not build toward an early version of a manuscript.</p>
<p>My buddy Niklas once told me to write more like we speak and not in jargon-filled academese. I try to follow this advice as best as I can, but have a fondness for sentences that flow long like the Amazon river—through forests, mountainous valleys, flatlands, and human settlements—and thus become incomprehensible to readers who long ago have forgotten the point once they reach the sentence’s final punctuation mark. I guess we now have <a href="https://thebullshitmachines.com/">LLMs to help us write</a>, but these words are mine, and I take pleasure in crafting them and the process of discovery through writing.</p>
<blockquote class="blockquote">
<p>“Using ChatGPT to complete assignments is like bringing a forklift into the weight room; you will never improve your cognitive fitness that way.”</p>
<p>–<a href="https://www.newyorker.com/culture/the-weekend-essay/why-ai-isnt-going-to-make-art">Ted Chiang</a></p>
</blockquote>
<p>If you need some examples to improve your writing, go read some <a href="https://edyong.me/writing">Ed Yong</a>.</p>
<p>One way in which I make writing more enjoyable for myself is to use the right tool. For me this tool is an integrated development environment (IDE), which is a fancy text editor that allows me to write documents that weave together human and computer words. I currently use <a href="https://positron.posit.co/">Positron</a>, because I like it and it allows writing human words (“prose”, sometimes I don’t know what those words mean so I use <a href="https://onelook.com/">onelook.com</a>) and computer words (“code”, sometimes I have no idea what I’m doing so I read the <a href="https://paulbuerkner.com/brms/">documentation</a>) together into computationally reproducible documents (<a href="https://quarto.org/">more</a> on this in Section&nbsp;4).</p>
<p>Many people use Microsoft Word and that’s fine too, but one should not be surprised that there are alternatives. And if you use Word, do yourself a favor and use the Styles panel.</p>
<section id="positron-or-rstudio-vs-code-or-any-ide" class="level3" data-number="3.1">
<h3 data-number="3.1" class="anchored" data-anchor-id="positron-or-rstudio-vs-code-or-any-ide"><span class="header-section-number">3.1</span> Positron (or RStudio, VS Code, or any IDE)</h3>
<p>Figure&nbsp;3 shows what Positron looks like as I am writing this document. It’s confusing but you get used to it. On the left, I have a source file open called <code>index.qmd</code> (I’ll talk more about this below in Section&nbsp;4). Below it, there’s a terminal into which I can write commands that do things on my computer. On the left is a preview of what the rendered document will look like, which updates every time I save the source document.</p>
<div id="fig-ide" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-ide-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/workflow/images/ide.png" class="img-fluid figure-img">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-ide-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;3: Screenshot of my IDE (Positron) as I write this document.
</figcaption>
</figure>
</div>
</section>
</section>
<section id="sec-docs" class="level2" data-number="4">
<h2 data-number="4" class="anchored" data-anchor-id="sec-docs"><span class="header-section-number">4</span> Computationally reproducible documents</h2>
<p>Computationally reproducible documents are <a href="https://plain-text.co/">plain text</a> <span class="citation" data-cites="healyPlainPersonsGuide2019">(Healy 2019)</span> files into which I write prose, such as this, and code, such as the colored text in Figure&nbsp;3. (You can see the plain text source file of this very document <a href="https://github.com/mvuorre/mvuorre.github.io/edit/main/posts/workflow/index.qmd">here</a>). This source file is then “rendered” into a typeset document using a computer program. The code languages in that figure are <a href="https://quarto.org/docs/authoring/front-matter.html">YAML</a> at the top, which I use to specify metadata (the document’s title, for example) and <a href="https://quarto.org/docs/authoring/markdown-basics.html">markdown</a>, which I use to format text (<code>**bold**</code> source turns into <strong>bold</strong> output).</p>
<p>Other languages I commonly use in these documents are <a href="https://quarto.org/docs/computations/r.html">R</a>, which is a statistics language (<code>`{r} sqrt(2)`</code> in source turns into 1.4142136 in the output), and <a href="https://quarto.org/docs/authoring/markdown-basics.html#equations">LaTeX</a>, used to typeset maths from <code>$y = \alpha + \beta x$</code> in the source file to <img src="https://latex.codecogs.com/png.latex?y%20=%20%5Calpha%20+%20%5Cbeta%20x"> in the output document.</p>
<section id="quarto" class="level3" data-number="4.1">
<h3 data-number="4.1" class="anchored" data-anchor-id="quarto"><span class="header-section-number">4.1</span> Quarto</h3>
<p>To combine prose with all these languages and their outputs, a computer program is needed. I use <a href="https://quarto.org/">Quarto</a>. The source document “index.qmd” in Figure&nbsp;3 is a Quarto document, and this is how I write all of my computationally reproducible documents. What this means is that I might write a file like <a href="https://gist.github.com/mvuorre/537a8e41d57f504ba1f375fa867ba57e">this</a>, run a command (<code>quarto render index.qmd</code>) in the terminal, and get <a href="https://gist.github.com/mvuorre/537a8e41d57f504ba1f375fa867ba57e?permalink_comment_id=5659871#gistcomment-5659871">this</a>.</p>
<p>Many choose to write in MS Word (or LaTeX) instead, which is fine, but you cannot create reproducible documents with Word. With Word I need to copy-paste my computational results to the Word file. When they or data supporting them change, I must copy-paste again. Mistakes happen!</p>
<p>Reproducible documents typically require a project with many files: data, bibliographies, supplementary code, and so on. Here is the basic file structure common to many of my projects:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">❯</span> eza <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--tree</span> my-project <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--level</span> 2</span>
<span id="cb1-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">my-project</span></span>
<span id="cb1-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">├──</span> _quarto.yml</span>
<span id="cb1-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">├──</span> bibliography.bib</span>
<span id="cb1-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">├──</span> data-raw</span>
<span id="cb1-6"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│</span>   └── data.csv</span>
<span id="cb1-7"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">├──</span> index.qmd</span>
<span id="cb1-8"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">└──</span> README.md</span></code></pre></div></div>
<p>The most important file there is “README.md”, which must describe what the project is, who is involved, and how to reproduce all the computations and the manuscript itself. The computations and manuscript content are all in “index.qmd”. Here are two example manuscripts’ Quarto source files: <a href="https://github.com/mvuorre/mvuorre.github.io/blob/main/posts/sdt-regression/index.qmd">Estimating Signal Detection Models with regression using the brms R package</a> &amp; <a href="https://github.com/mvuorre/heterogeneity-uncertainty/blob/main/index.qmd">Communicating causal effect heterogeneity</a>. Here are what they look like when “rendered” with Quarto: <a href="https://osf.io/preprints/psyarxiv/vtfc3_v1" class="uri">https://osf.io/preprints/psyarxiv/vtfc3_v1</a> &amp; <a href="https://osf.io/preprints/psyarxiv/mwg4f_v1" class="uri">https://osf.io/preprints/psyarxiv/mwg4f_v1</a>.</p>
<p>“_quarto.yml” contains Quarto <a href="https://quarto.org/docs/projects/quarto-projects.html">metadata</a>, such as what the output should look like. “bibliography.bib” is a <a href="https://quarto.org/docs/authoring/citations.html">bibliography file</a> that contains all the references and their information used in the document.</p>
</section>
<section id="bibliography-management" class="level3" data-number="4.2">
<h3 data-number="4.2" class="anchored" data-anchor-id="bibliography-management"><span class="header-section-number">4.2</span> Bibliography management</h3>
<p>Since I use Zotero to manage my library and Positron to write my Quarto documents, I use <a href="../zotero-positron-vscode/">this extension</a> to easily insert references in the document. In Positron, I call “Zotero Citation Picker”, find a reference, hit return which inserts something like <code>[@healyPlainPersonsGuide2019]</code> into the text and the associated entry in the bibliography file. When the document is rendered, the citation is automatically formatted as an in-text reference and in the bibliography section.</p>
</section>
</section>
<section id="version-control" class="level2" data-number="5">
<h2 data-number="5" class="anchored" data-anchor-id="version-control"><span class="header-section-number">5</span> Version control</h2>
<p>While tools like MS Word’s “track changes” can be nice when you’re writing prose, they don’t work with computationally reproducible documents. So we end up with version control systems, such as <a href="https://swcarpentry.github.io/git-novice/">Git</a>.</p>
<section id="git" class="level3" data-number="5.1">
<h3 data-number="5.1" class="anchored" data-anchor-id="git"><span class="header-section-number">5.1</span> Git</h3>
<p>So what is Git, and version control systems more generally? This is a <em>whole thing</em> that you should learn about on <a href="https://swcarpentry.github.io/git-novice/">Software Carpentry’s</a> or <a href="https://www.atlassian.com/git/tutorials/what-is-version-control">Atlassian’s</a> websites. It is mainly used by programmers, but as Richard McElreath puts in <a href="https://youtu.be/8qzVV7eEiaI?si=CNJ_cnGj2BpECdvX">Science as Amateur Software Development</a> today’s research involves a lot of programming, and we ignore that fact at our peril.</p>
<p>After I’ve established what idea I’m working on and how, I’m going to start tracking the state of the project with Git <span class="citation" data-cites="vuorreCuratingResearchAssets2018">(Vuorre and Curley 2018)</span>. I create a local Git repo, and link it to a remote GitHub repository (more on that in Section&nbsp;6.1). I commit my changes whenever it makes sense but am not religious about it: Version control is a tool to get stuff done, not the stuff itself. Figure&nbsp;4 shows how an example project might unfold over time.</p>
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div id="fig-git" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-git-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div>
<pre class="mermaid mermaid-js" data-label="fig-git">%%{init: {
  'theme': 'base',
  'themeVariables': {
    'primaryBorderColor': '#666',
    'commitLabelFontSize': '12px',
    'commitLabelBackground': '#ffffff',
    'git0': '#4a90e2',
    'git1': '#7b68ee'
  }
}}%%

gitGraph
    commit id: "Initial project"
    commit id: "Add data collection script"
    commit id: "Add statistical analysis"
    commit id: "First draft complete" tag: "v0.1.0"
    branch modeling
    checkout modeling
    commit id: "Try alternative model"
    commit id: "Add sensitivity analysis"
    commit id: "Robustness checks"
    checkout main
    commit id: "Update documentation"
    commit id: "Fix data processing"
    merge modeling
    commit id: "Finalize results"
    commit id: "Analysis complete" tag: "v0.2.0"
    commit id: "Add publication plots"
    commit id: "Ready for submission" tag: "v1.0.0"
</pre>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-git-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;4: Schematic of a project versioned with Git. ‘main’ is the branch where most of the work happens, but I switched to ‘modeling’ when I was working on a large feature. Diagonal texts are Git ‘commit messages’ that give descriptive labels of changes that occurred at that time. I use ‘v0.1.0’ tags to indicate “versions” of the project that are associated with a rendered output document or project milestone.
</figcaption>
</figure>
</div>
</div>
</div>
<p>If I’m working alone on a project, I often don’t bother with branches. If I’m working with others, I’m more careful and try to keep the main branch clean and working, so it is easier for others to maintain a working version without my possibly temporary and breaking changes. In Figure&nbsp;4 I switched to a “modeling” branch to work on a large feature, and didn’t want to put incomplete work into the ‘main’ branch, but still keep track of checkpoints on that work using commits. This probably makes no sense, but should after you’ve read <a href="https://swcarpentry.github.io/git-novice/">Software Carpentry’s</a> tutorial on Git.</p>
</section>
</section>
<section id="collaboration" class="level2" data-number="6">
<h2 data-number="6" class="anchored" data-anchor-id="collaboration"><span class="header-section-number">6</span> Collaboration</h2>
<p>Version control systems are mistakenly interpreted, as I suggest above, to be about version control. They do that too, but their main benefits become apparent when collaborating. Just like the “track changes” feature in MS Word, they allow you to see what’s changed in your document(s) and review &amp; undo edits, but more importantly they help <em>others</em> with that. It doesn’t matter if that “other” is another person or the selfsame you later in time.</p>
<div id="fig-github" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-github-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/workflow/images/git.png" class="img-fluid figure-img" style="width:80.0%">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-github-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;5: Schematic of a collaborative workflow using GitHub (Software Carpentries).
</figcaption>
</figure>
</div>
<p>If I’m just writing prose, I’ll probably collaborate on a Google Docs or MS Word (on OneDrive or some similar abomination), because these cloud platforms minimize friction in getting changes from person A to person B. As soon as we’re working together on a computationally reproducible projet, I encourage people to collaborate on the Git repo whose remote is on <a href="https://github.com/mvuorre">GitHub</a>. Figure&nbsp;5 (<a href="https://carpentries-incubator.github.io/open-science-with-r/09-collaborating/index.html">source</a>) shows a schematic of a collaborative workflow.</p>
<section id="sec-github" class="level3" data-number="6.1">
<h3 data-number="6.1" class="anchored" data-anchor-id="sec-github"><span class="header-section-number">6.1</span> GitHub</h3>
<p>GitHub is a Git repository hosting and collaboration platform. It is a for-profit enterprise owned by Microsoft, and while I use it I’m prepared to abandon ship as soon as enshittification begins. Right now it is the best tool for collaborating on Git repositories, but others exist.</p>
<p>After I’ve connected my local Git repo to a GitHub remote, I’ll send a link to my collaborators so they can clone their local version, work on it, commit, push, and send pull requests for me to review. There’s a lot of weird words there but they’re quick to learn (from <a href="https://happygitwithr.com/">here</a> or <a href="https://swcarpentry.github.io/git-novice/">here</a>, for example).</p>
</section>
<section id="fallback-options" class="level3" data-number="6.2">
<h3 data-number="6.2" class="anchored" data-anchor-id="fallback-options"><span class="header-section-number">6.2</span> Fallback options</h3>
<p>So it is clearly unrealistic to demand that all collaborators are on board with this workflow. That’s fine. For me it is important to manage a single source of truth—the reproducible Quarto plain text file that includes all the computations. But many others prefer Word or Google Docs. In those cases I read others’ revisions / comments / suggestions in the Word document, and based on my judgment edit the source Quarto document. I then render it into Word along with PDF (which will be the version I’ll submit). Going between Word and Positron is not optimal, but the goal is to go from “Receive idea” to “Science” (Figure&nbsp;1) with the least friction. I’ve found it is not that painful—with Word track changes someone still needs to evaluate revisions and modify accordingly. Here there’s just the extra step of doing that in a separate file.</p>
<p>If I’m not the lead author but maybe just working on the analyses or Results section, I write a Quarto file for just the Results section. That usually works okay as well.</p>
</section>
</section>
<section id="depositing-materials" class="level2" data-number="7">
<h2 data-number="7" class="anchored" data-anchor-id="depositing-materials"><span class="header-section-number">7</span> Depositing materials</h2>
<p>Many folks in my field drag and drop their files from their local filesystem to the <a href="https://osf.io/">Open Science Framework</a>. I prefer a simpler (to me) workflow, where <a href="https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository">GitHub releases</a> are automatically archived (with citation metadata, a DOI, etc) to <a href="https://docs.github.com/en/repositories/archiving-a-github-repository/referencing-and-citing-content">Zenodo</a>. Here is a <a href="https://zenodo.org/records/15533999">Zenodo</a> archive of <a href="https://github.com/digital-wellbeing/paradigm-comments">this GitHub</a> repository that contains a computationally reproducible manuscript project for <a href="https://osf.io/dpuya_v2">this manuscript</a>.</p>
</section>
<section id="showing-my-work-to-others" class="level2" data-number="8">
<h2 data-number="8" class="anchored" data-anchor-id="showing-my-work-to-others"><span class="header-section-number">8</span> Showing my work to others</h2>
<p>In academia, we typically call the process of showing our work to others “publishing”. Although the goal is pretty clear—make publicly funded common goods, or science, freely available for anyone to read—publishing is a byzantine process (Figure&nbsp;6).</p>
<div id="fig-publish" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-publish-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/workflow/images/syed.png" class="img-fluid figure-img" style="width:80.0%">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-publish-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;6: Moin Syed’s <a href="https://bsky.app/profile/syeducation.bsky.social/post/3logkez7hsk25">Blyesky post</a> about academic publishing.
</figcaption>
</figure>
</div>
<p>I am increasingly against how the current “publishing” system works, and for me a near-final milestone for an academic document is the PDF file I post to <a href="https://osf.io/preprints/psyarxiv">PsyArXiv Preprints</a>, a popular document-sharing platform for the psychological sciences. Optimally I would receive peer feedback on those documents to incorporate into the write-up, but sadly this is not how things work yet. So we go through some of the worst web portals known to humanity to “submit”, “revise and resubmit”, and “publish” the words and pictures in other kinds of websites called “journals”. It’s all a bit silly.</p>
<p>Surprisingly, my thoughts on this topic are not universally shared. For some context, take a look <a href="https://eprints.soton.ac.uk/251894/1/harnad90.skywriting.html">here</a> and <a href="https://web-archive.southampton.ac.uk/cogprints.org/1642/1/nature4.htm">here</a> <span class="citation" data-cites="harnadScholarlySkywritingPrepublication1990 harnadSelfarchivingInitiative2001">(Harnad 1990, 2001)</span>.</p>
</section>
<section id="overview-of-tools" class="level2" data-number="9">
<h2 data-number="9" class="anchored" data-anchor-id="overview-of-tools"><span class="header-section-number">9</span> Overview of tools</h2>
<div id="tbl-letters" class="bordered responsive info quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-tbl figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-tbl" id="tbl-letters-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Table&nbsp;1: An overview of tools used in my workflow, in rough order of appearance.
</figcaption>
<div aria-describedby="tbl-letters-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="table-responsive">
<table class="table-bordered table-info caption-top table">
<thead>
<tr class="header">
<th>Tool/Platform</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><a href="https://zotero.org">Zotero</a></td>
<td>Library and reference manager. (See also <a href="https://retorque.re/zotero-better-bibtex/">Better BibTeX</a>.)</td>
</tr>
<tr class="even">
<td><a href="https://positron.posit.co/">Positron</a></td>
<td>Integrated Development Enviroment for writing reproducible computational documents. (See also <a href="https://vuorre.com/posts/zotero-positron-vscode/">Zotero citation picker</a>, &amp; <a href="https://posit-dev.github.io/air/editor-vscode.html">Air formatter</a>.)</td>
</tr>
<tr class="odd">
<td><a href="https://quarto.org/">Quarto</a></td>
<td>A program for writing reproducible documents with multiple output formats.</td>
</tr>
<tr class="even">
<td><a href="https://git-scm.com/">Git</a></td>
<td>Version control system: Tracks the history of a folder on your computer.</td>
</tr>
<tr class="odd">
<td><a href="https://github.com/mvuorre">GitHub</a></td>
<td>Collaboration platform for projects tracked with Git.</td>
</tr>
<tr class="even">
<td><a href="https://zenodo.org/">Zenodo</a></td>
<td>An open-source, CERN-backed archiving and sharing platform. Automatically archives my projects’ GitHub releases and assigns each a citeable DOI.</td>
</tr>
<tr class="odd">
<td><a href="https://osf.io/preprints/psyarxiv">PsyArXiv</a></td>
<td>Document sharing platform for the psychological sciences.</td>
</tr>
<tr class="even">
<td><a href="https://prereview.org/">PREreview</a></td>
<td>Peer-review platform.</td>
</tr>
</tbody>
</table>
</div>
</div>
</figure>
</div>
</section>
<section id="end" class="level2" data-number="10">
<h2 data-number="10" class="anchored" data-anchor-id="end"><span class="header-section-number">10</span> End</h2>
<p>The central ideas in the ongoing can be boiled down to this:</p>
<ol type="1">
<li>Decide and define early on what you’re doing / the anticipated “product”. Usually this is a scholarly manuscript available for others to read and criticize.</li>
<li>Put all the things related to that thing into as few places as possible. Then track that with Git, and collaborate on GitHub.</li>
<li>Ensure that anyone can get the source of the project, click a button, and create the manuscript you share on PsyArXiv.</li>
</ol>
<p>Maybe that goes between collecting the underpants and profit?</p>



</section>

<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-bibliography"><h2 class="anchored quarto-appendix-heading">References</h2><div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="0">
<div id="ref-careyTenSimpleRules2020" class="csl-entry">
Carey, Maureen A., Kevin L. Steiner, and William A. Jr Petri. 2020. <span>“Ten Simple Rules for Reading a Scientific Paper.”</span> <em>PLOS Computational Biology</em> 16 (7): e1008032. <a href="https://doi.org/10.1371/journal.pcbi.1008032">https://doi.org/10.1371/journal.pcbi.1008032</a>.
</div>
<div id="ref-davisPeerReviewGuidelinesPromoting2018" class="csl-entry">
Davis, William E., Roger Giner-Sorolla, D. Stephen Lindsay, Jessica P. Lougheed, Matthew C. Makel, Matt E. Meier, Jessie Sun, Leigh Ann Vaughn, and John M. Zelenski. 2018. <span>“Peer-<span>Review Guidelines Promoting Replicability</span> and <span>Transparency</span> in <span>Psychological Science</span>.”</span> <em>Advances in Methods and Practices in Psychological Science</em> 1 (4): 556–73. <a href="https://doi.org/10.1177/2515245918806489">https://doi.org/10.1177/2515245918806489</a>.
</div>
<div id="ref-harnadScholarlySkywritingPrepublication1990" class="csl-entry">
Harnad, Stevan. 1990. <span>“Scholarly <span>Skywriting</span> and the <span>Prepublication Continuum</span> of <span>Scientific Inquiry</span>.”</span> <em>Psychological Science</em> 1 (6): 342–44. <a href="https://doi.org/10.1111/j.1467-9280.1990.tb00234.x">https://doi.org/10.1111/j.1467-9280.1990.tb00234.x</a>.
</div>
<div id="ref-harnadSelfarchivingInitiative2001" class="csl-entry">
———. 2001. <span>“The Self-Archiving Initiative.”</span> <em>Nature</em> 410 (April): 1024. <a href="https://doi.org/10.1038/35074210">https://doi.org/10.1038/35074210</a>.
</div>
<div id="ref-healyPlainPersonsGuide2019" class="csl-entry">
Healy, Kieran. 2019. <em>The <span>Plain Person</span>’s <span>Guide</span> to <span>Plain Text Social Science</span></em>. <a href="https://plain-text.co/">https://plain-text.co/</a>.
</div>
<div id="ref-lindsayDigestTipsReviewerspdf2017" class="csl-entry">
Lindsay, D., Roger Giner-Sorolla, and Jessie Sun. 2017. <span>“Digest of <span>Tips</span> for <span>Reviewers</span>.pdf,”</span> July. <a href="https://osf.io/https://osf.io/hbyu2">https://osf.io/https://osf.io/hbyu2</a>.
</div>
<div id="ref-oberheimPaulFeyerabend2025" class="csl-entry">
Oberheim, Eric, and John Preston. 2025. <span>“Paul <span>Feyerabend</span>.”</span> In <em>The <span>Stanford Encyclopedia</span> of <span>Philosophy</span></em>, edited by Edward N. Zalta and Uri Nodelman, Spring 2025. Metaphysics Research Lab, Stanford University. <a href="https://plato.stanford.edu/archives/spr2025/entries/feyerabend/">https://plato.stanford.edu/archives/spr2025/entries/feyerabend/</a>.
</div>
<div id="ref-roedigerTwelveTipsReviewers2007" class="csl-entry">
Roediger, Henry L. 2007. <span>“Twelve <span>Tips</span> for <span>Reviewers</span>.”</span> <em>APS Observer</em> 20 (April). <a href="https://www.psychologicalscience.org/observer/twelve-tips-for-reviewers">https://www.psychologicalscience.org/observer/twelve-tips-for-reviewers</a>.
</div>
<div id="ref-savageHowWhyRead2024" class="csl-entry">
Savage, Patrick E. 2024. <span>“How and Why to Read (and Write and Publish) Academic Research.”</span> OSF. <a href="https://doi.org/10.31234/osf.io/p37zj">https://doi.org/10.31234/osf.io/p37zj</a>.
</div>
<div id="ref-scheelWhyMostPsychological2022" class="csl-entry">
Scheel, Anne M. 2022. <span>“Why Most Psychological Research Findings Are Not Even Wrong.”</span> <em>Infant and Child Development</em> 31 (1): e2295. <a href="https://doi.org/10.1002/icd.2295">https://doi.org/10.1002/icd.2295</a>.
</div>
<div id="ref-vuorreCuratingResearchAssets2018" class="csl-entry">
Vuorre, Matti, and James P. Curley. 2018. <span>“Curating <span>Research Assets</span>: <span>A Tutorial</span> on the <span>Git Version Control System</span>.”</span> <em>Advances in Methods and Practices in Psychological Science</em> 1 (2): 219–36. <a href="https://doi.org/10.1177/2515245918754826">https://doi.org/10.1177/2515245918754826</a>.
</div>
</div></section><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{vuorre2025,
  author = {Vuorre, Matti},
  title = {How {I} Work on Computationally Reproducible Academic
    Projects},
  date = {2025-08-22},
  url = {https://vuorre.com/posts/workflow/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-vuorre2025" class="csl-entry quarto-appendix-citeas">
Vuorre, Matti. 2025. <span>“How I Work on Computationally Reproducible
Academic Projects.”</span> August 22, 2025. <a href="https://vuorre.com/posts/workflow/">https://vuorre.com/posts/workflow/</a>.
</div></div></section></div> ]]></description>
  <category>research</category>
  <category>workflow</category>
  <guid>https://vuorre.com/posts/workflow/</guid>
  <pubDate>Thu, 21 Aug 2025 22:00:00 GMT</pubDate>
  <media:content url="https://vuorre.com/posts/workflow/images/underpants.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>PDF-direct</title>
  <dc:creator>Matti Vuorre</dc:creator>
  <link>https://vuorre.com/posts/pdf-direct/</link>
  <description><![CDATA[ 





<p>When you browse to an academic journal article’s website, for example <a href="https://journals.sagepub.com/doi/10.1177/2515245918770963">this one</a><sup>1</sup>, if you are lucky and the manuscript is not <a href="https://astro.theoj.org/post/168-">paywalled</a>, you can read the HTML version of the article which usually looks something like the one shown in Figure&nbsp;1.</p>
<div id="fig-page" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-page-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/pdf-direct/images/article-page2.png" class="img-fluid figure-img">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-page-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;1: A scholarly manuscript’s website.
</figcaption>
</figure>
</div>
<p>Vintage technophiles like myself still prefer reading (and archiving) the manuscript’s PDF version. But these publishers are smart and have implemented new <a href="https://doi.org/10.4000/proceedings.elpub.2018.30"><del>data-harvesting</del></a> accessibility features such as “fancy online PDF readers”. So when you click on the PDF/EPUB link on the page, instead of just getting the PDF, you see Figure&nbsp;2 instead.</p>
<div id="fig-epdf" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-epdf-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/pdf-direct/images/article-epdf.png" class="img-fluid figure-img">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-epdf-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;2: A scholarly manuscript’s PDF in the publisher’s “fancy online PDF reader”.
</figcaption>
</figure>
</div>
<p>This bugs me: I just want the PDF and every additional click and UI idiosynchracy adds friction to my daily work. So I did what any reasonable person would do and wrote a little <a href="https://github.com/mvuorre/pdf-direct">Firefox extension</a> that skips journals’ “enhanced” PDF viewers to direct PDF downloads. You can get it here: <a href="https://addons.mozilla.org/en-US/firefox/addon/pdf-direct/" class="uri">https://addons.mozilla.org/en-US/firefox/addon/pdf-direct/</a>. After installing PDF-Direct, clicking on the PDF/EPUB link will immediately just download the darn PDF (Figure&nbsp;3).</p>
<div id="fig-pdf" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-pdf-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/pdf-direct/images/article-pdf.png" class="img-fluid figure-img">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-pdf-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;3: A scholarly manuscript’s actual PDF in MacOS’s Preview.
</figcaption>
</figure>
</div>
<p>An additional problem with these “fancy online PDF readers” is that they seem to break <a href="https://www.zotero.org/">Zotero</a>’s ability to download PDF files, though I am not sure if that is the reason. I’m quite busy and don’t actually know/care about how these Firefox extensions work: PDF-direct is 99% vibe-coded but seems to work well. It is also simple enough that I am able to see that it probably doesn’t have any real security implications. I might be wrong though, so send your reports to <a href="https://github.com/mvuorre/pdf-direct" class="uri">https://github.com/mvuorre/pdf-direct</a>.</p>




<div id="quarto-appendix" class="default"><section id="footnotes" class="footnotes footnotes-end-of-document"><h2 class="anchored quarto-appendix-heading">Footnotes</h2>

<ol>
<li id="fn1"><p>Goes without saying that this particular (quite nice) article has nothing to do with the topic of this post, I just happened to be reading it and since it was open access I was able to show how this works in practice.↩︎</p></li>
</ol>
</section><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{vuorre2025,
  author = {Vuorre, Matti},
  title = {PDF-Direct},
  date = {2025-07-03},
  url = {https://vuorre.com/posts/pdf-direct/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-vuorre2025" class="csl-entry quarto-appendix-citeas">
Vuorre, Matti. 2025. <span>“PDF-Direct.”</span> July 3, 2025. <a href="https://vuorre.com/posts/pdf-direct/">https://vuorre.com/posts/pdf-direct/</a>.
</div></div></section></div> ]]></description>
  <category>communication</category>
  <category>workflow</category>
  <guid>https://vuorre.com/posts/pdf-direct/</guid>
  <pubDate>Wed, 02 Jul 2025 22:00:00 GMT</pubDate>
  <media:content url="https://vuorre.com/posts/pdf-direct/images/pdf.png" medium="image" type="image/png" height="144" width="144"/>
</item>
<item>
  <title>How to add citations from Zotero to Quarto documents</title>
  <dc:creator>Matti Vuorre</dc:creator>
  <link>https://vuorre.com/posts/zotero-positron-vscode/</link>
  <description><![CDATA[ 





<section id="tldr" class="level2 page-columns page-full">
<h2 class="anchored" data-anchor-id="tldr">tl;dr</h2>
<p>My version of the <a href="https://github.com/mvuorre/vscode-zotero/releases/tag/v0.2.0">Citation Picker for Zotero</a> VS Code (and Positron, etc) extension allows inserting references from Zotero to source documents and their .bib files. Here is what using it in <a href="https://positron.posit.co/">Positron</a> looks like:</p>
<div class="page-columns page-full">
<div class="quarto-figure quarto-figure-center page-columns page-full">
<figure class="figure page-columns page-full">
<p class="page-columns page-full"><img src="https://vuorre.com/posts/zotero-positron-vscode/images/extension.gif" class="img-fluid figure-img column-page-right"></p>
<figcaption>Improved Citation Picker for Zotero VS Code extension in action.</figcaption>
</figure>
</div>
</div>
</section>
<section id="what" class="level2">
<h2 class="anchored" data-anchor-id="what">What?</h2>
<p>We like writing all our scientific outputs with <a href="https://quarto.org/docs/authoring/front-matter.html">Quarto</a> using the <a href="https://positron.posit.co/">Positron</a> IDE. We also manage our references/library with <a href="https://www.zotero.org/">Zotero</a>, and want to insert references directly from Zotero to the Quarto documents. What does that mean?</p>
<p>It means that you fire up Positron, write a document like <code>manuscript.qmd</code>:</p>
<pre><code>---
title: Science!
author: Matti Vuorre
date: 2025-06-06
bibliography: bibliography.bib
---

Probability theory is cool [@jaynesProbabilityTheoryLogic2003].</code></pre>
<p>and then run <code>quarto render manuscript.qmd</code> in your terminal. By default this creates a HTML document (but can be a PDF, Word document, or whatever) that will look like this:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://vuorre.com/posts/zotero-positron-vscode/images/shot.png" class="img-fluid figure-img"></p>
<figcaption>Screenshot of a Quarto HTML document.</figcaption>
</figure>
</div>
<p>Notice how the Jaynes reference is nicely dealt with both in-text and in the references section. While Positron allows easily adding citations from Zotero when editing documents in <a href="https://quarto.org/docs/tools/positron/visual-editor.html#zotero-citations">visual mode</a>, this was less easy in source mode (which I much prefer).</p>
</section>
<section id="how" class="level2">
<h2 class="anchored" data-anchor-id="how">How?</h2>
<p>The <a href="https://github.com/mblode/vscode-zotero">vscode-zotero</a> extension makes it easy to add in-text references to Quarto documents, and can be installed through Positron’s “Extensions” panel:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://vuorre.com/posts/zotero-positron-vscode/images/extension.png" class="img-fluid figure-img"></p>
<figcaption>Screenshot of Positron’s “Extensions” panel.</figcaption>
</figure>
</div>
<p>Critically, the extension does not add the entry in the document’s associated .bib file (<code>bibliography: bibliography.bib</code> in the document’s YAML front matter.)</p>
</section>
<section id="how-an-improved-answer" class="level2">
<h2 class="anchored" data-anchor-id="how-an-improved-answer">How? An improved answer</h2>
<p>So what I did was fork the extension, add this functionality, and submit a <a href="https://github.com/mblode/vscode-zotero/pull/38">pull request</a>. So once/if the pull request is merged you can install it as above. For now, to install the extension, go to <a href="https://github.com/mvuorre/vscode-zotero/releases/tag/v0.2.0" class="uri">https://github.com/mvuorre/vscode-zotero/releases/tag/v0.2.0</a> and download the <code>.vsix</code> file.</p>
<p>Then, in Positron, install the extension by clicking “Install from VSIX…” and select the downloaded <code>.vsix</code> file.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://vuorre.com/posts/zotero-positron-vscode/images/extension2.png" class="img-fluid figure-img"></p>
<figcaption>Another screenshot of Positron’s “Extensions” panel.</figcaption>
</figure>
</div>
<p>Restart Positron, ensure Zotero is running and that you have installed the <a href="https://retorque.re/zotero-better-bibtex/">Better BibTex</a> Zotero plugin. Then, in Positron, open up your source document and ensure its frontmatter contains a reference to a <a href="https://quarto.org/docs/authoring/citations.html">bibliography file</a>. Then place your cursor where you want the citation to appear in your document, and launch the extension’s citation picker function. On a Mac the hotkey for launching the function is <kbd>Shift+Option+Z</kbd> and Windows probably has one too. This brings up the citation picker UI dialog:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://vuorre.com/posts/zotero-positron-vscode/images/jaynes.png" class="img-fluid figure-img"></p>
<figcaption>Positron’s UI citation picker.</figcaption>
</figure>
</div>
<p>Typing anything in the dialog will search for items with that string, and advanced search queries like <code>author:jaynes</code> and <code>author:jaynes theory</code> work as well. Once you’ve chosen the desired citation, hit <kbd>Return</kbd> and the in-text citation is added to the document, and its biblatex entry is written to the document’s associated <code>.bib</code> file.</p>
<p>Done and done.</p>
    <bluesky-comments post="at://did:plc:ai4isl2n4j2h7qcqebj7vu2k/app.bsky.feed.post/3lqx3refo3c2p" filter-config="{&quot;filterEmptyReplies&quot;:true,&quot;mutePatterns&quot;:[],&quot;muteUsers&quot;:[]}" profile="did:plc:ai4isl2n4j2h7qcqebj7vu2k"></bluesky-comments>
  


</section>

<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{vuorre2025,
  author = {Vuorre, Matti},
  title = {How to Add Citations from {Zotero} to {Quarto} Documents},
  date = {2025-06-06},
  url = {https://vuorre.com/posts/zotero-positron-vscode/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-vuorre2025" class="csl-entry quarto-appendix-citeas">
Vuorre, Matti. 2025. <span>“How to Add Citations from Zotero to Quarto
Documents .”</span> June 6, 2025. <a href="https://vuorre.com/posts/zotero-positron-vscode/">https://vuorre.com/posts/zotero-positron-vscode/</a>.
</div></div></section></div> ]]></description>
  <category>communication</category>
  <category>workflow</category>
  <guid>https://vuorre.com/posts/zotero-positron-vscode/</guid>
  <pubDate>Thu, 05 Jun 2025 22:00:00 GMT</pubDate>
  <media:content url="https://vuorre.com/posts/zotero-positron-vscode/images/zotero.png" medium="image" type="image/png" height="58" width="144"/>
</item>
<item>
  <title>Bayesian multilevel mediation with brms</title>
  <dc:creator>Matti Vuorre</dc:creator>
  <link>https://vuorre.com/posts/bmlm-multilevel-mediation/</link>
  <description><![CDATA[ 





<div class="cell" data-layout-align="center">
<details class="code-fold">
<summary>R setup</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(knitr)</span>
<span id="cb1-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(bmlm)</span>
<span id="cb1-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(tinytable)</span>
<span id="cb1-4"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(ggdist)</span>
<span id="cb1-5"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(posterior)</span>
<span id="cb1-6"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(patchwork)</span>
<span id="cb1-7"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(brms)</span>
<span id="cb1-8"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(tidyverse)</span>
<span id="cb1-9"></span>
<span id="cb1-10"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dir.create</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"cache"</span>, <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span>)</span>
<span id="cb1-11"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">options</span>(</span>
<span id="cb1-12">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">brms.backend =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Sys.getenv</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"BRMS_BACKEND"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"rstan"</span>),</span>
<span id="cb1-13">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">brms.threads =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as.numeric</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Sys.getenv</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"BRMS_THREADS"</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)),</span>
<span id="cb1-14">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mc.cores =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as.numeric</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Sys.getenv</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"MAX_CORES"</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>)),</span>
<span id="cb1-15">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">brms.short_summary =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>,</span>
<span id="cb1-16">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">tinytable_tt_digits =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>,</span>
<span id="cb1-17">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">tinytable_format_num_fmt =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"decimal"</span>,</span>
<span id="cb1-18">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">tinytable_format_num_zero =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>,</span>
<span id="cb1-19">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">tinytable_tt_theme =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"spacing"</span></span>
<span id="cb1-20">)</span>
<span id="cb1-21"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme_set</span>(</span>
<span id="cb1-22">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme_linedraw</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">base_size =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is_html_output</span>(), <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb1-23">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme</span>(</span>
<span id="cb1-24">      <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">panel.grid =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">element_blank</span>(),</span>
<span id="cb1-25">      <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">strip.background =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">element_blank</span>(),</span>
<span id="cb1-26">      <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">strip.text =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">element_text</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">hjust =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">colour =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"black"</span>)</span>
<span id="cb1-27">    )</span>
<span id="cb1-28">)</span>
<span id="cb1-29"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Omit MCMC info in brmsfit.summary</span></span>
<span id="cb1-30">.summary <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(x) {</span>
<span id="cb1-31">  out <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summary</span>(x)</span>
<span id="cb1-32">  out<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>random<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>id <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> out<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>random<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>id[, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>]</span>
<span id="cb1-33">  out<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>fixed <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> out<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>fixed[, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>]</span>
<span id="cb1-34">  out<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>spec_pars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> out<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>spec_pars[, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>]</span>
<span id="cb1-35">  out</span>
<span id="cb1-36">}</span></code></pre></div></div>
</details>
</div>
<section id="bmlm" class="level2">
<h2 class="anchored" data-anchor-id="bmlm">bmlm</h2>
<p>Back in 2016 I wrote an R package for bayesian estimation of a multivariate multilevel model for assessing a three-variable causal mediation model <span class="citation" data-cites="vuorreBmlmBayesianMultilevel2024">(Vuorre [2016] 2024)</span>. In the abstract to the article that discussed the methodology, Niall Bolger and I wrote</p>
<blockquote class="blockquote">
<p>“Statistical mediation allows researchers to investigate potential causal effects of experimental manipulations through intervening variables. It is a powerful tool for assessing the presence and strength of postulated causal mechanisms. Although mediation is used in certain areas of psychology, it is rarely applied in cognitive psychology and neuroscience. One reason for the scarcity of applications is that these areas of psychology commonly employ within-subjects designs, and mediation models for within-subjects data is considerably more complicated than for between-subjects data. Here, we draw attention to the importance and ubiquity of mediational hypotheses in within-subjects designs, and we present a general and flexible software package for conducting Bayesian within-subjects mediation analyses in the R programming environment. We use experimental data from cognitive psychology to illustrate the benefits of within-subject mediation for theory testing and comparison.” <span class="citation" data-cites="vuorreWithinsubjectMediationAnalysis2017">(Vuorre and Bolger 2017)</span></p>
</blockquote>
<p>I wrote the R package as an interface to a Stan <span class="citation" data-cites="standevelopmentteamStanModelingLanguage2024">(Team 2024)</span> model because brms <span class="citation" data-cites="burkner_brms:_2017">(Bürkner 2017a)</span>—still in its early days—did not implement the kind of multivariate structure required by the model. Shortly afterwards, probably within a few months actually, Paul updated brms to fit the required model structure and bmlm as a standalone package lost much of its value. So whenever people email me about bmlm, I keep suggesting them to estimate their models with brms instead because it can do this, and so much more. (I’ve had a tutorial for this up at <a href="https://vuorre.com/brms-workshop/posts/mediation/" class="uri">https://vuorre.com/brms-workshop/posts/mediation/</a> but it’s difficult to find.)</p>
<p>So in this post I’ll briefly show how to fit bmlm’s multilevel mediation model with brms, along with the required post-processing for computing the indirect effects, figures, etc.</p>
</section>
<section id="mediationa-word-of-caution" class="level2">
<h2 class="anchored" data-anchor-id="mediationa-word-of-caution">Mediation—a word of caution</h2>
<p>Mediation models are used to make causal claims from observational data. This is a complex and difficult endeavor, and all uses of mediation must appropriately wrestle with the implications and assumptions behind the models and claims that are being made. See <span class="citation" data-cites="greenEnoughAlreadyBlack2010">Green, Ha, and Bullock (2010)</span> and <span class="citation" data-cites="rohrerThatsLotProcess2022">Rohrer et al. (2022)</span>.</p>
</section>
<section id="analysis" class="level2">
<h2 class="anchored" data-anchor-id="analysis">Analysis</h2>
<p>In one of bmlm’s <a href="https://vuorre.com/bmlm/articles/bmlm-blch9/bmlm-blch9.html">vignettes</a> we analyse an example data set from <a href="http://www.intensivelongitudinal.com/index.html">Intensive Longitudinal Methods: An Introduction to Diary and Experience Sampling Research</a> <span class="citation" data-cites="bolgerIntensiveLongitudinalMethods2013">(Bolger and Laurenceau 2013)</span>. The data, shown in Table&nbsp;1 and included in the bmlm package, indicate several (hypothetical) participants’ (<code>id</code>) work stressors (<code>fwkstrs</code>), work dissatisfaction (<code>fwkdis</code>), and relationship dissatisfaction (<code>freldis</code>) over several days of study.</p>
<div class="cell" data-layout-align="center">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb2-1">dat <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tibble</span>(BLch9)[, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>)]</span>
<span id="cb2-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tt</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head</span>(dat))</span></code></pre></div></div>
</details>
<div id="tbl-data" class="cell quarto-float quarto-figure quarto-figure-center anchored" data-layout-align="center">
<figure class="quarto-float quarto-float-tbl figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-tbl" id="tbl-data-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Table&nbsp;1: Six rows of example data.
</figcaption>
<div aria-describedby="tbl-data-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell-output-display">
<!-- preamble start -->

    <script>

      function styleCell_eoh8jlys3cw7zjwdhmgn(i, j, css_id) {
          var table = document.getElementById("tinytable_eoh8jlys3cw7zjwdhmgn");
          var cell = table.rows[i]?.cells[j];  // Safe navigation to avoid errors
          if (cell) {
              console.log(`Styling cell at (${i}, ${j}) with class ${css_id}`);
              cell.classList.add(css_id);
          } else {
              console.warn(`Cell at (${i}, ${j}) not found.`);
          }
      }
      function insertSpanRow(i, colspan, content) {
        var table = document.getElementById('tinytable_eoh8jlys3cw7zjwdhmgn');
        var newRow = table.insertRow(i);
        var newCell = newRow.insertCell(0);
        newCell.setAttribute("colspan", colspan);
        // newCell.innerText = content;
        // this may be unsafe, but innerText does not interpret <br>
        newCell.innerHTML = content;
      }
      function spanCell_eoh8jlys3cw7zjwdhmgn(i, j, rowspan, colspan) {
        var table = document.getElementById("tinytable_eoh8jlys3cw7zjwdhmgn");
        const targetRow = table.rows[i];
        const targetCell = targetRow.cells[j];
        for (let r = 0; r < rowspan; r++) {
          // Only start deleting cells to the right for the first row (r == 0)
          if (r === 0) {
            // Delete cells to the right of the target cell in the first row
            for (let c = colspan - 1; c > 0; c--) {
              if (table.rows[i + r].cells[j + c]) {
                table.rows[i + r].deleteCell(j + c);
              }
            }
          }
          // For rows below the first, delete starting from the target column
          if (r > 0) {
            for (let c = colspan - 1; c >= 0; c--) {
              if (table.rows[i + r] && table.rows[i + r].cells[j]) {
                table.rows[i + r].deleteCell(j);
              }
            }
          }
        }
        // Set rowspan and colspan of the target cell
        targetCell.rowSpan = rowspan;
        targetCell.colSpan = colspan;
      }
      // tinytable span after
      window.addEventListener('load', function () {
          var cellsToStyle = [
            // tinytable style arrays after
          { positions: [ { i: 6, j: 3 },  ], css_id: 'tinytable_css_8vjghqn357rczv2973zp',}, 
          { positions: [ { i: 1, j: 3 }, { i: 2, j: 3 }, { i: 3, j: 3 }, { i: 4, j: 3 }, { i: 5, j: 3 },  ], css_id: 'tinytable_css_94fmd97lxhw6xte0n6gc',}, 
          { positions: [ { i: 0, j: 3 },  ], css_id: 'tinytable_css_w8friw6zvh8ut4jmougn',}, 
          { positions: [ { i: 6, j: 1 }, { i: 6, j: 0 }, { i: 6, j: 2 },  ], css_id: 'tinytable_css_i5q4zaty3sbtfkmkbrbl',}, 
          { positions: [ { i: 1, j: 0 }, { i: 4, j: 0 }, { i: 5, j: 0 }, { i: 2, j: 0 }, { i: 3, j: 0 }, { i: 1, j: 1 }, { i: 2, j: 1 }, { i: 3, j: 1 }, { i: 4, j: 1 }, { i: 5, j: 1 }, { i: 3, j: 2 }, { i: 4, j: 2 }, { i: 1, j: 2 }, { i: 2, j: 2 }, { i: 5, j: 2 },  ], css_id: 'tinytable_css_l4mp8nssb6qzogfxnxsz',}, 
          { positions: [ { i: 0, j: 0 }, { i: 0, j: 2 }, { i: 0, j: 1 },  ], css_id: 'tinytable_css_oq1gc6yyzewwk7xfdc1l',}, 
          ];

          // Loop over the arrays to style the cells
          cellsToStyle.forEach(function (group) {
              group.positions.forEach(function (cell) {
                  styleCell_eoh8jlys3cw7zjwdhmgn(cell.i, cell.j, group.css_id);
              });
          });
      });
    </script>

    <style>
      /* tinytable css entries after */
      .table td.tinytable_css_8vjghqn357rczv2973zp, .table th.tinytable_css_8vjghqn357rczv2973zp { border-bottom: solid #d3d8dc 0.1em; }
      .table td.tinytable_css_94fmd97lxhw6xte0n6gc, .table th.tinytable_css_94fmd97lxhw6xte0n6gc { padding-bottom: 0.1em; }
      .table td.tinytable_css_w8friw6zvh8ut4jmougn, .table th.tinytable_css_w8friw6zvh8ut4jmougn { border-bottom: solid #d3d8dc 0.1em; padding-bottom: 0.1em; }
      .table td.tinytable_css_i5q4zaty3sbtfkmkbrbl, .table th.tinytable_css_i5q4zaty3sbtfkmkbrbl { border-bottom: solid #d3d8dc 0.1em; padding-right: 0.5em; }
      .table td.tinytable_css_l4mp8nssb6qzogfxnxsz, .table th.tinytable_css_l4mp8nssb6qzogfxnxsz { padding-right: 0.5em; padding-bottom: 0.1em; }
      .table td.tinytable_css_oq1gc6yyzewwk7xfdc1l, .table th.tinytable_css_oq1gc6yyzewwk7xfdc1l { border-bottom: solid #d3d8dc 0.1em; padding-right: 0.5em; padding-bottom: 0.1em; }
    </style>
    <div class="container">
      <table class="table table-borderless" id="tinytable_eoh8jlys3cw7zjwdhmgn" style="width: auto; margin-left: auto; margin-right: auto;" data-quarto-disable-processing="true">
        <thead>
        
              <tr>
                <th scope="col">id</th>
                <th scope="col">fwkstrs</th>
                <th scope="col">fwkdis</th>
                <th scope="col">freldis</th>
              </tr>
        </thead>
        
        <tbody>
                <tr>
                  <td>101</td>
                  <td>3</td>
                  <td>5.59</td>
                  <td>3.03</td>
                </tr>
                <tr>
                  <td>101</td>
                  <td>3</td>
                  <td>5.54</td>
                  <td>4.62</td>
                </tr>
                <tr>
                  <td>101</td>
                  <td>3</td>
                  <td>3.89</td>
                  <td>2.85</td>
                </tr>
                <tr>
                  <td>101</td>
                  <td>4</td>
                  <td>5.35</td>
                  <td>6.40</td>
                </tr>
                <tr>
                  <td>101</td>
                  <td>1</td>
                  <td>4.48</td>
                  <td>2.54</td>
                </tr>
                <tr>
                  <td>101</td>
                  <td>2</td>
                  <td>3.34</td>
                  <td>5.16</td>
                </tr>
        </tbody>
      </table>
    </div>
<!-- hack to avoid NA insertion in last line -->
</div>
</div>
</figure>
</div>
</div>
<p>To see how the full analysis is conducted with bmlm, please see the vignette (<a href="https://vuorre.com/bmlm/articles/bmlm-blch9/bmlm-blch9.html" class="uri">https://vuorre.com/bmlm/articles/bmlm-blch9/bmlm-blch9.html</a>). Here, we implement the analysis without the use of bmlm’s functions.</p>
<section id="data-preparation" class="level3">
<h3 class="anchored" data-anchor-id="data-preparation">Data preparation</h3>
<p>First, we must isolate the within-person deviations of the key variables. We consider work stressors to be the independent variable, work dissatisfaction the mediator, and relationship dissatisfaction the outcome variable, and label them accordingly as <code>x</code>, <code>m</code>, and <code>y</code> for brevity.</p>
<div class="cell" data-layout-align="center">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb3-1">dat <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> dat <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(</span>
<span id="cb3-3">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> fwkstrs <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mean</span>(fwkstrs, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>),</span>
<span id="cb3-4">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">m =</span> fwkdis <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mean</span>(fwkdis, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>),</span>
<span id="cb3-5">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> freldis <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mean</span>(freldis, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>),</span>
<span id="cb3-6">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.by =</span> id,</span>
<span id="cb3-7">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.keep =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"unused"</span></span>
<span id="cb3-8">  )</span>
<span id="cb3-9"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tt</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head</span>(dat))</span></code></pre></div></div>
</details>
<div id="tbl-data-centered" class="cell quarto-float quarto-figure quarto-figure-center anchored" data-layout-align="center">
<figure class="quarto-float quarto-float-tbl figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-tbl" id="tbl-data-centered-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Table&nbsp;2: Subject-mean centered variables.
</figcaption>
<div aria-describedby="tbl-data-centered-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell-output-display">
<!-- preamble start -->

    <script>

      function styleCell_pgco63nyzc9o0lg6dkis(i, j, css_id) {
          var table = document.getElementById("tinytable_pgco63nyzc9o0lg6dkis");
          var cell = table.rows[i]?.cells[j];  // Safe navigation to avoid errors
          if (cell) {
              console.log(`Styling cell at (${i}, ${j}) with class ${css_id}`);
              cell.classList.add(css_id);
          } else {
              console.warn(`Cell at (${i}, ${j}) not found.`);
          }
      }
      function insertSpanRow(i, colspan, content) {
        var table = document.getElementById('tinytable_pgco63nyzc9o0lg6dkis');
        var newRow = table.insertRow(i);
        var newCell = newRow.insertCell(0);
        newCell.setAttribute("colspan", colspan);
        // newCell.innerText = content;
        // this may be unsafe, but innerText does not interpret <br>
        newCell.innerHTML = content;
      }
      function spanCell_pgco63nyzc9o0lg6dkis(i, j, rowspan, colspan) {
        var table = document.getElementById("tinytable_pgco63nyzc9o0lg6dkis");
        const targetRow = table.rows[i];
        const targetCell = targetRow.cells[j];
        for (let r = 0; r < rowspan; r++) {
          // Only start deleting cells to the right for the first row (r == 0)
          if (r === 0) {
            // Delete cells to the right of the target cell in the first row
            for (let c = colspan - 1; c > 0; c--) {
              if (table.rows[i + r].cells[j + c]) {
                table.rows[i + r].deleteCell(j + c);
              }
            }
          }
          // For rows below the first, delete starting from the target column
          if (r > 0) {
            for (let c = colspan - 1; c >= 0; c--) {
              if (table.rows[i + r] && table.rows[i + r].cells[j]) {
                table.rows[i + r].deleteCell(j);
              }
            }
          }
        }
        // Set rowspan and colspan of the target cell
        targetCell.rowSpan = rowspan;
        targetCell.colSpan = colspan;
      }
      // tinytable span after
      window.addEventListener('load', function () {
          var cellsToStyle = [
            // tinytable style arrays after
          { positions: [ { i: 6, j: 3 },  ], css_id: 'tinytable_css_batdaydnruq3dz1wyokp',}, 
          { positions: [ { i: 1, j: 3 }, { i: 2, j: 3 }, { i: 3, j: 3 }, { i: 4, j: 3 }, { i: 5, j: 3 },  ], css_id: 'tinytable_css_y8daes8a1rqii11r3pqv',}, 
          { positions: [ { i: 0, j: 3 },  ], css_id: 'tinytable_css_cf6e7mzgfkot1tm7lvty',}, 
          { positions: [ { i: 6, j: 1 }, { i: 6, j: 0 }, { i: 6, j: 2 },  ], css_id: 'tinytable_css_j9m5zdulaccvg7m17be5',}, 
          { positions: [ { i: 1, j: 0 }, { i: 4, j: 0 }, { i: 5, j: 0 }, { i: 2, j: 0 }, { i: 3, j: 0 }, { i: 1, j: 1 }, { i: 2, j: 1 }, { i: 3, j: 1 }, { i: 4, j: 1 }, { i: 5, j: 1 }, { i: 3, j: 2 }, { i: 4, j: 2 }, { i: 1, j: 2 }, { i: 2, j: 2 }, { i: 5, j: 2 },  ], css_id: 'tinytable_css_r0snu42h15tiudf5l9zz',}, 
          { positions: [ { i: 0, j: 0 }, { i: 0, j: 2 }, { i: 0, j: 1 },  ], css_id: 'tinytable_css_ye0c0qajwpnjjls8ceom',}, 
          ];

          // Loop over the arrays to style the cells
          cellsToStyle.forEach(function (group) {
              group.positions.forEach(function (cell) {
                  styleCell_pgco63nyzc9o0lg6dkis(cell.i, cell.j, group.css_id);
              });
          });
      });
    </script>

    <style>
      /* tinytable css entries after */
      .table td.tinytable_css_batdaydnruq3dz1wyokp, .table th.tinytable_css_batdaydnruq3dz1wyokp { border-bottom: solid #d3d8dc 0.1em; }
      .table td.tinytable_css_y8daes8a1rqii11r3pqv, .table th.tinytable_css_y8daes8a1rqii11r3pqv { padding-bottom: 0.1em; }
      .table td.tinytable_css_cf6e7mzgfkot1tm7lvty, .table th.tinytable_css_cf6e7mzgfkot1tm7lvty { border-bottom: solid #d3d8dc 0.1em; padding-bottom: 0.1em; }
      .table td.tinytable_css_j9m5zdulaccvg7m17be5, .table th.tinytable_css_j9m5zdulaccvg7m17be5 { border-bottom: solid #d3d8dc 0.1em; padding-right: 0.5em; }
      .table td.tinytable_css_r0snu42h15tiudf5l9zz, .table th.tinytable_css_r0snu42h15tiudf5l9zz { padding-right: 0.5em; padding-bottom: 0.1em; }
      .table td.tinytable_css_ye0c0qajwpnjjls8ceom, .table th.tinytable_css_ye0c0qajwpnjjls8ceom { border-bottom: solid #d3d8dc 0.1em; padding-right: 0.5em; padding-bottom: 0.1em; }
    </style>
    <div class="container">
      <table class="table table-borderless" id="tinytable_pgco63nyzc9o0lg6dkis" style="width: auto; margin-left: auto; margin-right: auto;" data-quarto-disable-processing="true">
        <thead>
        
              <tr>
                <th scope="col">id</th>
                <th scope="col">x</th>
                <th scope="col">m</th>
                <th scope="col">y</th>
              </tr>
        </thead>
        
        <tbody>
                <tr>
                  <td>101</td>
                  <td>0.33</td>
                  <td>0.98</td>
                  <td>-1.44</td>
                </tr>
                <tr>
                  <td>101</td>
                  <td>0.33</td>
                  <td>0.93</td>
                  <td>0.14</td>
                </tr>
                <tr>
                  <td>101</td>
                  <td>0.33</td>
                  <td>-0.72</td>
                  <td>-1.63</td>
                </tr>
                <tr>
                  <td>101</td>
                  <td>1.33</td>
                  <td>0.75</td>
                  <td>1.92</td>
                </tr>
                <tr>
                  <td>101</td>
                  <td>-1.67</td>
                  <td>-0.12</td>
                  <td>-1.93</td>
                </tr>
                <tr>
                  <td>101</td>
                  <td>-0.67</td>
                  <td>-1.27</td>
                  <td>0.69</td>
                </tr>
        </tbody>
      </table>
    </div>
<!-- hack to avoid NA insertion in last line -->
</div>
</div>
</figure>
</div>
</div>
</section>
<section id="model-fitting" class="level3">
<h3 class="anchored" data-anchor-id="model-fitting">Model fitting</h3>
<p>The model comprises of two regression formulas that share a variance-covariance matrix for the random effects (the <code>| p |</code> syntax). Notice that I have optimized my MCMC sampler options in an environment files and using <code>options()</code> as <a href="https://vuorre.com/posts/sdt-regression/#tips-for-estimating-models-with-brm-1">shown here</a>. In addition to directly connecting this model to the underlying regressions, brms estimates the model faster than bmlm (and allows using better priors, omitted here).</p>
<div class="cell" data-layout-align="center">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb4-1">path_m <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bf</span>(</span>
<span id="cb4-2">  m <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> x <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> (x <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> p <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> id)</span>
<span id="cb4-3">)</span>
<span id="cb4-4">path_y <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bf</span>(</span>
<span id="cb4-5">  y <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> x <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> m <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> (x <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> m <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> p <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> id)</span>
<span id="cb4-6">)</span>
<span id="cb4-7">fit <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">brm</span>(</span>
<span id="cb4-8">  path_m <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> path_y <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">set_rescor</span>(<span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span>),</span>
<span id="cb4-9">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> dat,</span>
<span id="cb4-10">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">file =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"cache/fit"</span></span>
<span id="cb4-11">)</span></code></pre></div></div>
</details>
</div>
</section>
<section id="model-summary" class="level3">
<h3 class="anchored" data-anchor-id="model-summary">Model summary</h3>
<p>The model parameters directly gives us the x -&gt; m (<code>m_x</code>, called <code>a</code> in bmlm), x -&gt; y (<code>y_m</code>, called <code>c'</code> or <code>cp</code> in bmlm) and m -&gt; y (<code>y_m</code>, called <code>b</code> in bmlm) path coefficients. These precisely match <a href="https://vuorre.com/bmlm/articles/bmlm-blch9/bmlm-blch9.html#summarize-fitted-model">bmlm’s estimates</a>.</p>
<div class="cell" data-layout-align="center">
<div class="cell-output cell-output-stdout">
<pre><code> Family: MV(gaussian, gaussian) 
  Links: mu = identity; sigma = identity
         mu = identity; sigma = identity 
Formula: m ~ x + (x | p | id) 
         y ~ x + m + (x + m | p | id) 
   Data: dat (Number of observations: 2100) 

Multilevel Hyperparameters:
~id (Number of levels: 100) 
                             Estimate Est.Error l-95% CI u-95% CI
sd(m_Intercept)                  0.02      0.01     0.00     0.05
sd(m_x)                          0.26      0.04     0.19     0.34
sd(y_Intercept)                  0.02      0.01     0.00     0.05
sd(y_x)                          0.08      0.03     0.01     0.14
sd(y_m)                          0.22      0.03     0.17     0.28
cor(m_Intercept,m_x)             0.02      0.39    -0.72     0.77
cor(m_Intercept,y_Intercept)     0.02      0.41    -0.75     0.77
cor(m_x,y_Intercept)            -0.01      0.41    -0.77     0.74
cor(m_Intercept,y_x)            -0.01      0.41    -0.77     0.75
cor(m_x,y_x)                     0.24      0.29    -0.39     0.77
cor(y_Intercept,y_x)            -0.01      0.42    -0.77     0.76
cor(m_Intercept,y_m)            -0.00      0.40    -0.75     0.72
cor(m_x,y_m)                     0.48      0.15     0.17     0.75
cor(y_Intercept,y_m)            -0.01      0.42    -0.79     0.76
cor(y_x,y_m)                     0.56      0.26    -0.11     0.91

Regression Coefficients:
            Estimate Est.Error l-95% CI u-95% CI
m_Intercept    -0.00      0.02    -0.05     0.05
y_Intercept    -0.00      0.02    -0.04     0.04
m_x             0.19      0.04     0.12     0.26
y_x             0.10      0.02     0.06     0.15
y_m             0.15      0.03     0.09     0.21

Further Distributional Parameters:
        Estimate Est.Error l-95% CI u-95% CI
sigma_m     1.09      0.02     1.06     1.13
sigma_y     0.93      0.01     0.90     0.96</code></pre>
</div>
</div>
</section>
<section id="mediation-parameters" class="level3">
<h3 class="anchored" data-anchor-id="mediation-parameters">Mediation parameters</h3>
<p>To get the additional mediation metrics (the indirect effect, the total effect, and others), we simply wrangle the model’s posterior samples. The indirect effect, or “mediated effect” is <img src="https://latex.codecogs.com/png.latex?me%20=%20ab%20+%20%5Csigma_%7B%7Ba_j%7D%7Bb_j%7D%7D">, or the population-level <code>m_x</code> times the population-level <code>y_m</code> plus the covariance of the person-level <code>m_x</code> and <code>y_m</code>s. The total effect is then <img src="https://latex.codecogs.com/png.latex?c%20=%20me%20+%20c'">. The proportion of the total effect that is mediated is <img src="https://latex.codecogs.com/png.latex?me%20/%20c">. While wrangling the variables below, I rename them for clarity.</p>
<div class="cell" data-layout-align="center">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb6-1">draws <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_draws_df</span>(</span>
<span id="cb6-2">  fit,</span>
<span id="cb6-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">variable =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(</span>
<span id="cb6-4">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"b_m_x"</span>,</span>
<span id="cb6-5">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"b_y_x"</span>,</span>
<span id="cb6-6">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"b_y_m"</span>,</span>
<span id="cb6-7">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sd_id__m_x"</span>,</span>
<span id="cb6-8">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sd_id__y_m"</span>,</span>
<span id="cb6-9">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"cor_id__m_x__y_m"</span></span>
<span id="cb6-10">  )</span>
<span id="cb6-11">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb6-12">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(</span>
<span id="cb6-13">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">a =</span> b_m_x,</span>
<span id="cb6-14">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">b =</span> b_y_m,</span>
<span id="cb6-15">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">cp =</span> b_y_x,</span>
<span id="cb6-16">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">covab =</span> cor_id__m_x__y_m <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> sd_id__m_x <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> sd_id__y_m,</span>
<span id="cb6-17">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">me =</span> a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> b <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> covab,</span>
<span id="cb6-18">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">c =</span> me <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> cp,</span>
<span id="cb6-19">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">pme =</span> me <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> c,</span>
<span id="cb6-20">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.keep =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"unused"</span></span>
<span id="cb6-21">  )</span></code></pre></div></div>
</details>
</div>
<p><code>draws</code> now contains the posterior draws of the key population-level effects, which we summarize below.</p>
<div class="cell" data-layout-align="center">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb7-1">draws <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise_draws</span>(</span>
<span id="cb7-3">    mean,</span>
<span id="cb7-4">    sd,</span>
<span id="cb7-5">    <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">quantile2</span>(.x, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">probs =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(.<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">025</span>, .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">975</span>))</span>
<span id="cb7-6">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tt</span>()</span></code></pre></div></div>
</details>
<div id="tbl-draws" class="cell quarto-float quarto-figure quarto-figure-center anchored" data-layout-align="center">
<figure class="quarto-float quarto-float-tbl figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-tbl" id="tbl-draws-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Table&nbsp;3: Summaries of key quantities posterior draws.
</figcaption>
<div aria-describedby="tbl-draws-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell-output-display">
<!-- preamble start -->

    <script>

      function styleCell_9ne3z7z3apab2x7ppoiv(i, j, css_id) {
          var table = document.getElementById("tinytable_9ne3z7z3apab2x7ppoiv");
          var cell = table.rows[i]?.cells[j];  // Safe navigation to avoid errors
          if (cell) {
              console.log(`Styling cell at (${i}, ${j}) with class ${css_id}`);
              cell.classList.add(css_id);
          } else {
              console.warn(`Cell at (${i}, ${j}) not found.`);
          }
      }
      function insertSpanRow(i, colspan, content) {
        var table = document.getElementById('tinytable_9ne3z7z3apab2x7ppoiv');
        var newRow = table.insertRow(i);
        var newCell = newRow.insertCell(0);
        newCell.setAttribute("colspan", colspan);
        // newCell.innerText = content;
        // this may be unsafe, but innerText does not interpret <br>
        newCell.innerHTML = content;
      }
      function spanCell_9ne3z7z3apab2x7ppoiv(i, j, rowspan, colspan) {
        var table = document.getElementById("tinytable_9ne3z7z3apab2x7ppoiv");
        const targetRow = table.rows[i];
        const targetCell = targetRow.cells[j];
        for (let r = 0; r < rowspan; r++) {
          // Only start deleting cells to the right for the first row (r == 0)
          if (r === 0) {
            // Delete cells to the right of the target cell in the first row
            for (let c = colspan - 1; c > 0; c--) {
              if (table.rows[i + r].cells[j + c]) {
                table.rows[i + r].deleteCell(j + c);
              }
            }
          }
          // For rows below the first, delete starting from the target column
          if (r > 0) {
            for (let c = colspan - 1; c >= 0; c--) {
              if (table.rows[i + r] && table.rows[i + r].cells[j]) {
                table.rows[i + r].deleteCell(j);
              }
            }
          }
        }
        // Set rowspan and colspan of the target cell
        targetCell.rowSpan = rowspan;
        targetCell.colSpan = colspan;
      }
      // tinytable span after
      window.addEventListener('load', function () {
          var cellsToStyle = [
            // tinytable style arrays after
          { positions: [ { i: 7, j: 4 },  ], css_id: 'tinytable_css_9sbwgg9y8i9sljcjsz7a',}, 
          { positions: [ { i: 1, j: 4 }, { i: 2, j: 4 }, { i: 3, j: 4 }, { i: 4, j: 4 }, { i: 5, j: 4 }, { i: 6, j: 4 },  ], css_id: 'tinytable_css_o44wub71q9lm4prvcrem',}, 
          { positions: [ { i: 0, j: 4 },  ], css_id: 'tinytable_css_jn4odwj438j75w65pfwg',}, 
          { positions: [ { i: 7, j: 0 }, { i: 7, j: 2 }, { i: 7, j: 1 }, { i: 7, j: 3 },  ], css_id: 'tinytable_css_a5e3xozfm5cmc2nxyqj5',}, 
          { positions: [ { i: 1, j: 0 }, { i: 2, j: 0 }, { i: 5, j: 0 }, { i: 6, j: 0 }, { i: 4, j: 0 }, { i: 1, j: 1 }, { i: 2, j: 1 }, { i: 4, j: 2 }, { i: 4, j: 1 }, { i: 5, j: 1 }, { i: 6, j: 1 }, { i: 4, j: 3 }, { i: 3, j: 0 }, { i: 1, j: 2 }, { i: 2, j: 2 }, { i: 3, j: 2 }, { i: 3, j: 1 }, { i: 5, j: 2 }, { i: 6, j: 2 }, { i: 3, j: 3 }, { i: 1, j: 3 }, { i: 2, j: 3 }, { i: 5, j: 3 }, { i: 6, j: 3 },  ], css_id: 'tinytable_css_s3l0cd1yqja0kqhoiazz',}, 
          { positions: [ { i: 0, j: 0 }, { i: 0, j: 2 }, { i: 0, j: 1 }, { i: 0, j: 3 },  ], css_id: 'tinytable_css_pamd1a611pw8y7feogd3',}, 
          ];

          // Loop over the arrays to style the cells
          cellsToStyle.forEach(function (group) {
              group.positions.forEach(function (cell) {
                  styleCell_9ne3z7z3apab2x7ppoiv(cell.i, cell.j, group.css_id);
              });
          });
      });
    </script>

    <style>
      /* tinytable css entries after */
      .table td.tinytable_css_9sbwgg9y8i9sljcjsz7a, .table th.tinytable_css_9sbwgg9y8i9sljcjsz7a { border-bottom: solid #d3d8dc 0.1em; }
      .table td.tinytable_css_o44wub71q9lm4prvcrem, .table th.tinytable_css_o44wub71q9lm4prvcrem { padding-bottom: 0.1em; }
      .table td.tinytable_css_jn4odwj438j75w65pfwg, .table th.tinytable_css_jn4odwj438j75w65pfwg { border-bottom: solid #d3d8dc 0.1em; padding-bottom: 0.1em; }
      .table td.tinytable_css_a5e3xozfm5cmc2nxyqj5, .table th.tinytable_css_a5e3xozfm5cmc2nxyqj5 { border-bottom: solid #d3d8dc 0.1em; padding-right: 0.5em; }
      .table td.tinytable_css_s3l0cd1yqja0kqhoiazz, .table th.tinytable_css_s3l0cd1yqja0kqhoiazz { padding-right: 0.5em; padding-bottom: 0.1em; }
      .table td.tinytable_css_pamd1a611pw8y7feogd3, .table th.tinytable_css_pamd1a611pw8y7feogd3 { border-bottom: solid #d3d8dc 0.1em; padding-right: 0.5em; padding-bottom: 0.1em; }
    </style>
    <div class="container">
      <table class="table table-borderless" id="tinytable_9ne3z7z3apab2x7ppoiv" style="width: auto; margin-left: auto; margin-right: auto;" data-quarto-disable-processing="true">
        <thead>
        
              <tr>
                <th scope="col">variable</th>
                <th scope="col">mean</th>
                <th scope="col">sd</th>
                <th scope="col">q2.5</th>
                <th scope="col">q97.5</th>
              </tr>
        </thead>
        
        <tbody>
                <tr>
                  <td>a</td>
                  <td>0.19</td>
                  <td>0.04</td>
                  <td>0.12</td>
                  <td>0.26</td>
                </tr>
                <tr>
                  <td>b</td>
                  <td>0.15</td>
                  <td>0.03</td>
                  <td>0.09</td>
                  <td>0.21</td>
                </tr>
                <tr>
                  <td>cp</td>
                  <td>0.10</td>
                  <td>0.02</td>
                  <td>0.06</td>
                  <td>0.15</td>
                </tr>
                <tr>
                  <td>covab</td>
                  <td>0.03</td>
                  <td>0.01</td>
                  <td>0.01</td>
                  <td>0.05</td>
                </tr>
                <tr>
                  <td>me</td>
                  <td>0.06</td>
                  <td>0.01</td>
                  <td>0.03</td>
                  <td>0.09</td>
                </tr>
                <tr>
                  <td>c</td>
                  <td>0.16</td>
                  <td>0.03</td>
                  <td>0.11</td>
                  <td>0.21</td>
                </tr>
                <tr>
                  <td>pme</td>
                  <td>0.36</td>
                  <td>0.08</td>
                  <td>0.21</td>
                  <td>0.53</td>
                </tr>
        </tbody>
      </table>
    </div>
<!-- hack to avoid NA insertion in last line -->
</div>
</div>
</figure>
</div>
</div>
<p>These parameter estimates directly reproduce the values obtained by bmlm.</p>
</section>
<section id="graphics" class="level3">
<h3 class="anchored" data-anchor-id="graphics">Graphics</h3>
<p>brms has a number of excellent built-in visualization facilities, such as drawing conditional effects with ggplot2 <span class="citation" data-cites="ggplot">(Wickham 2016)</span> (Figure&nbsp;1).</p>
<div class="cell" data-layout-align="center">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb8-1">ce1 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">conditional_effects</span>(</span>
<span id="cb8-2">  fit,</span>
<span id="cb8-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">effects =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"x"</span>,</span>
<span id="cb8-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">resp =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"m"</span>,</span>
<span id="cb8-5">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">robust =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span></span>
<span id="cb8-6">)</span>
<span id="cb8-7">ce1 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">plot</span>(ce1, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">plot =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span>)[[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]]</span>
<span id="cb8-8">ce2 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">conditional_effects</span>(</span>
<span id="cb8-9">  fit,</span>
<span id="cb8-10">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">effects =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"m"</span>,</span>
<span id="cb8-11">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">resp =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"y"</span>,</span>
<span id="cb8-12">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">robust =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span></span>
<span id="cb8-13">)</span>
<span id="cb8-14">ce2 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">plot</span>(ce2, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">plot =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span>)[[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]]</span>
<span id="cb8-15">ce1 <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> ce2</span></code></pre></div></div>
</details>
<div class="cell-output-display">
<div id="fig-ce" class="quarto-float quarto-figure quarto-figure-center anchored" data-fig-align="center">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-ce-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/bmlm-multilevel-mediation/index_files/figure-html/fig-ce-1.png" class="img-fluid quarto-figure quarto-figure-center figure-img" width="672">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-ce-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;1: Conditional population-level regression of m on x (left) and y on m (right).
</figcaption>
</figure>
</div>
</div>
</div>
<p>And the resulting objects and posterior samples are easily visualized with e.g.&nbsp;functions from the <code>ggdist</code> package <span class="citation" data-cites="ggdist">(Kay 2024a)</span> (Figure&nbsp;2).</p>
<div class="cell" data-layout-align="center">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb9-1">draws <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">starts_with</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"."</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_longer</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">everything</span>()) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> value, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> name)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb9-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">stat_slabinterval</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">normalize =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"xy"</span>)</span></code></pre></div></div>
</details>
<div class="cell-output-display">
<div id="fig-pars" class="quarto-float quarto-figure quarto-figure-center anchored" data-fig-align="center">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-pars-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/bmlm-multilevel-mediation/index_files/figure-html/fig-pars-1.png" class="img-fluid quarto-figure quarto-figure-center figure-img" width="672">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-pars-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;2: Approximate posterior distributions of key mediation parameters.
</figcaption>
</figure>
</div>
</div>
</div>
</section>
</section>
<section id="conclusion" class="level2">
<h2 class="anchored" data-anchor-id="conclusion">Conclusion</h2>
<p>If you are going to fit the model described in <span class="citation" data-cites="vuorreWithinsubjectMediationAnalysis2017">(Vuorre and Bolger 2017)</span>, I recommend using the brms R package <span class="citation" data-cites="burkner_brms:_2017">(Bürkner 2017a)</span> because of its flexibility, how it clearly connects to R regression syntax, and its estimation efficiency.</p>
</section>

<section id="feedback-comments" class="level2">
<h2 class="anchored" data-anchor-id="feedback-comments">Feedback &amp; comments</h2>
<p>I’d appreciate any feedback or comments you might have. Feel free to le me know what you think either using the comments field (below) or on Bluesky:</p>
    <bluesky-comments post="at://did:plc:ai4isl2n4j2h7qcqebj7vu2k/app.bsky.feed.post/3lo74t2bjpk2l" filter-config="{&quot;filterEmptyReplies&quot;:true,&quot;mutePatterns&quot;:[],&quot;muteUsers&quot;:[]}" profile="did:plc:ai4isl2n4j2h7qcqebj7vu2k"></bluesky-comments>
  



</section>

<div id="quarto-appendix" class="default"><section id="r-environment" class="level2 appendix"><h2 class="anchored quarto-appendix-heading">R environment</h2><div class="quarto-appendix-contents">

<div class="cell" data-layout-align="center">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb10-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(grateful)</span>
<span id="cb10-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">cite_packages</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">output =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"paragraph"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">pkgs =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Session"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">out.dir =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">getwd</span>())</span></code></pre></div></div>
</details>
<div class="cell-output-display">
<p>We used R version 4.5.0 <span class="citation" data-cites="base">(R Core Team 2025)</span> and the following R packages: bmlm v. 1.3.15 <span class="citation" data-cites="bmlm2018 bmlm2023">(Vuorre and Bolger 2018; Vuorre 2023)</span>, brms v. 2.22.0 <span class="citation" data-cites="brms2017 brms2018 brms2021">(Bürkner 2017b, 2018, 2021)</span>, distributional v. 0.5.0 <span class="citation" data-cites="distributional">(O’Hara-Wild et al. 2024)</span>, ggdist v. 3.3.2 <span class="citation" data-cites="ggdist2024a ggdist2024b">(Kay 2024c, 2024b)</span>, ggnewscale v. 0.5.1 <span class="citation" data-cites="ggnewscale">(Campitelli 2025)</span>, knitr v. 1.50 <span class="citation" data-cites="knitr2014 knitr2015 knitr2025">(Xie 2014, 2015, 2025)</span>, latex2exp v. 0.9.6 <span class="citation" data-cites="latex2exp">(Meschiari 2022)</span>, patchwork v. 1.3.0 <span class="citation" data-cites="patchwork">(Pedersen 2024)</span>, posterior v. 1.6.1 <span class="citation" data-cites="posterior2021b posterior2022d posterior2024c posterior2024e posterior2025a">(Vehtari et al. 2021, 2024; Lambert and Vehtari 2022; Margossian et al. 2024; Bürkner et al. 2025)</span>, Rcpp v. 1.0.14 <span class="citation" data-cites="Rcpp2011 Rcpp2013 Rcpp2018 Rcpp2025">(Eddelbuettel and François 2011; Eddelbuettel 2013; Eddelbuettel and Balamuta 2018; Eddelbuettel et al. 2025)</span>, scales v. 1.3.0 <span class="citation" data-cites="scales">(Wickham, Pedersen, and Seidel 2023)</span>, tidybayes v. 3.0.7 <span class="citation" data-cites="tidybayes">(Kay 2024d)</span>, tidyverse v. 2.0.0 <span class="citation" data-cites="tidyverse">(Wickham et al. 2019)</span>, tinytable v. 0.8.0 <span class="citation" data-cites="tinytable">(Arel-Bundock 2025)</span>.</p>
</div>
</div>
</div></section><section class="quarto-appendix-contents" id="quarto-bibliography"><h2 class="anchored quarto-appendix-heading">References</h2><div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="0">
<div id="ref-tinytable" class="csl-entry">
Arel-Bundock, Vincent. 2025. <em><span class="nocase">tinytable</span>: Simple and Configurable Tables in <span>“<span>HTML</span>,”</span> <span>“<span>LaTeX</span>,”</span> <span>“<span>Markdown</span>,”</span> <span>“<span>Word</span>,”</span> <span>“<span>PNG</span>,”</span> <span>“<span>PDF</span>,”</span> and <span>“<span>Typst</span>”</span> Formats</em>. <a href="https://doi.org/10.32614/CRAN.package.tinytable">https://doi.org/10.32614/CRAN.package.tinytable</a>.
</div>
<div id="ref-bolgerIntensiveLongitudinalMethods2013" class="csl-entry">
Bolger, Niall, and Jean-Philippe Laurenceau. 2013. <em>Intensive <span>Longitudinal Methods</span>: <span>An Introduction</span> to <span>Diary</span> and <span>Experience Sampling Research</span></em>. New York, NY: Guilford Press. <a href="http://www.intensivelongitudinal.com/">http://www.intensivelongitudinal.com/</a>.
</div>
<div id="ref-burkner_brms:_2017" class="csl-entry">
Bürkner, Paul-Christian. 2017a. <span>“Brms: <span>An R Package</span> for <span>Bayesian Multilevel Models Using Stan</span>.”</span> <em>Journal of Statistical Software</em> 80 (1): 1–28. <a href="https://doi.org/10.18637/jss.v080.i01">https://doi.org/10.18637/jss.v080.i01</a>.
</div>
<div id="ref-brms2017" class="csl-entry">
———. 2017b. <span>“<span class="nocase">brms</span>: An <span>R</span> Package for <span>Bayesian</span> Multilevel Models Using <span>Stan</span>.”</span> <em>Journal of Statistical Software</em> 80 (1): 1–28. <a href="https://doi.org/10.18637/jss.v080.i01">https://doi.org/10.18637/jss.v080.i01</a>.
</div>
<div id="ref-brms2018" class="csl-entry">
———. 2018. <span>“Advanced <span>Bayesian</span> Multilevel Modeling with the <span>R</span> Package <span class="nocase">brms</span>.”</span> <em>The R Journal</em> 10 (1): 395–411. <a href="https://doi.org/10.32614/RJ-2018-017">https://doi.org/10.32614/RJ-2018-017</a>.
</div>
<div id="ref-brms2021" class="csl-entry">
———. 2021. <span>“Bayesian Item Response Modeling in <span>R</span> with <span class="nocase">brms</span> and <span>Stan</span>.”</span> <em>Journal of Statistical Software</em> 100 (5): 1–54. <a href="https://doi.org/10.18637/jss.v100.i05">https://doi.org/10.18637/jss.v100.i05</a>.
</div>
<div id="ref-posterior2025a" class="csl-entry">
Bürkner, Paul-Christian, Jonah Gabry, Matthew Kay, and Aki Vehtari. 2025. <span>“<span class="nocase">posterior</span>: Tools for Working with Posterior Distributions.”</span> <a href="https://mc-stan.org/posterior/">https://mc-stan.org/posterior/</a>.
</div>
<div id="ref-ggnewscale" class="csl-entry">
Campitelli, Elio. 2025. <em><span class="nocase">ggnewscale</span>: Multiple Fill and Colour Scales in <span>“<span class="nocase">ggplot2</span>”</span></em>. <a href="https://doi.org/10.32614/CRAN.package.ggnewscale">https://doi.org/10.32614/CRAN.package.ggnewscale</a>.
</div>
<div id="ref-Rcpp2013" class="csl-entry">
Eddelbuettel, Dirk. 2013. <em>Seamless <span>R</span> and <span>C++</span> Integration with <span>Rcpp</span></em>. New York: Springer. <a href="https://doi.org/10.1007/978-1-4614-6868-4">https://doi.org/10.1007/978-1-4614-6868-4</a>.
</div>
<div id="ref-Rcpp2018" class="csl-entry">
Eddelbuettel, Dirk, and James Joseph Balamuta. 2018. <span>“<span class="nocase">Extending <span>R</span> with <span>C++</span>: A Brief Introduction to <span>Rcpp</span></span>.”</span> <em>The American Statistician</em> 72 (1): 28–36. <a href="https://doi.org/10.1080/00031305.2017.1375990">https://doi.org/10.1080/00031305.2017.1375990</a>.
</div>
<div id="ref-Rcpp2025" class="csl-entry">
Eddelbuettel, Dirk, Romain Francois, JJ Allaire, Kevin Ushey, Qiang Kou, Nathan Russell, Iñaki Ucar, Doug Bates, and John Chambers. 2025. <em><span>Rcpp</span>: Seamless r and c++ Integration</em>. <a href="https://doi.org/10.32614/CRAN.package.Rcpp">https://doi.org/10.32614/CRAN.package.Rcpp</a>.
</div>
<div id="ref-Rcpp2011" class="csl-entry">
Eddelbuettel, Dirk, and Romain François. 2011. <span>“<span>Rcpp</span>: Seamless <span>R</span> and <span>C++</span> Integration.”</span> <em>Journal of Statistical Software</em> 40 (8): 1–18. <a href="https://doi.org/10.18637/jss.v040.i08">https://doi.org/10.18637/jss.v040.i08</a>.
</div>
<div id="ref-greenEnoughAlreadyBlack2010" class="csl-entry">
Green, Donald P., Shang E. Ha, and John G. Bullock. 2010. <span>“Enough <span>Already</span> about <span>‘<span>Black Box</span>’</span> <span>Experiments</span>: <span>Studying Mediation Is More Difficult</span> Than <span>Most Scholars Suppose</span>.”</span> <em>The ANNALS of the American Academy of Political and Social Science</em> 628 (1): 200–208. <a href="https://doi.org/10.1177/0002716209351526">https://doi.org/10.1177/0002716209351526</a>.
</div>
<div id="ref-ggdist" class="csl-entry">
Kay, Matthew. 2024a. <em><span class="nocase">ggdist</span>: Visualizations of Distributions and Uncertainty</em>. <a href="https://doi.org/10.5281/zenodo.3879620">https://doi.org/10.5281/zenodo.3879620</a>.
</div>
<div id="ref-ggdist2024b" class="csl-entry">
———. 2024b. <em><span class="nocase">ggdist</span>: Visualizations of Distributions and Uncertainty</em>. <a href="https://doi.org/10.5281/zenodo.3879620">https://doi.org/10.5281/zenodo.3879620</a>.
</div>
<div id="ref-ggdist2024a" class="csl-entry">
———. 2024c. <span>“<span class="nocase">ggdist</span>: Visualizations of Distributions and Uncertainty in the Grammar of Graphics.”</span> <em>IEEE Transactions on Visualization and Computer Graphics</em> 30 (1): 414–24. <a href="https://doi.org/10.1109/TVCG.2023.3327195">https://doi.org/10.1109/TVCG.2023.3327195</a>.
</div>
<div id="ref-tidybayes" class="csl-entry">
———. 2024d. <em><span class="nocase">tidybayes</span>: Tidy Data and Geoms for <span>Bayesian</span> Models</em>. <a href="https://doi.org/10.5281/zenodo.1308151">https://doi.org/10.5281/zenodo.1308151</a>.
</div>
<div id="ref-posterior2022d" class="csl-entry">
Lambert, Ben, and Aki Vehtari. 2022. <span>“<span>Rstar</span>: A Robust MCMC Convergence Diagnostic with Uncertainty Using Decision Tree Classifiers.”</span> <em>Bayesian Analysis</em> 17 (2): 353–79. <a href="https://doi.org/10.1214/20-BA1252">https://doi.org/10.1214/20-BA1252</a>.
</div>
<div id="ref-posterior2024c" class="csl-entry">
Margossian, Charles C., Matthew D. Hoffman, Pavel Sountsov, Lionel Riou-Durand, Aki Vehtari, and Andrew Gelman. 2024. <span>“Nested Rhat: Assessing the Convergence of Markov Chain Monte Carlo When Running Many Short Chains.”</span> <em>Bayesian Analysis</em>. <a href="https://doi.org/10.1214/24-BA1453">https://doi.org/10.1214/24-BA1453</a>.
</div>
<div id="ref-latex2exp" class="csl-entry">
Meschiari, Stefano. 2022. <em>Latex2exp: Use LaTeX Expressions in Plots</em>. <a href="https://doi.org/10.32614/CRAN.package.latex2exp">https://doi.org/10.32614/CRAN.package.latex2exp</a>.
</div>
<div id="ref-distributional" class="csl-entry">
O’Hara-Wild, Mitchell, Matthew Kay, Alex Hayes, and Rob Hyndman. 2024. <em><span class="nocase">distributional</span>: Vectorised Probability Distributions</em>. <a href="https://doi.org/10.32614/CRAN.package.distributional">https://doi.org/10.32614/CRAN.package.distributional</a>.
</div>
<div id="ref-patchwork" class="csl-entry">
Pedersen, Thomas Lin. 2024. <em><span class="nocase">patchwork</span>: The Composer of Plots</em>. <a href="https://doi.org/10.32614/CRAN.package.patchwork">https://doi.org/10.32614/CRAN.package.patchwork</a>.
</div>
<div id="ref-base" class="csl-entry">
R Core Team. 2025. <em><span>R</span>: A Language and Environment for Statistical Computing</em>. Vienna, Austria: R Foundation for Statistical Computing. <a href="https://www.R-project.org/">https://www.R-project.org/</a>.
</div>
<div id="ref-rohrerThatsLotProcess2022" class="csl-entry">
Rohrer, Julia M., Paul Hünermund, Ruben C. Arslan, and Malte Elson. 2022. <span>“That’s a <span>Lot</span> to <span>Process</span>! <span>Pitfalls</span> of <span>Popular Path Models</span>.”</span> <em>Advances in Methods and Practices in Psychological Science</em> 5 (2): 25152459221095827. <a href="https://doi.org/10.1177/25152459221095827">https://doi.org/10.1177/25152459221095827</a>.
</div>
<div id="ref-standevelopmentteamStanModelingLanguage2024" class="csl-entry">
Team, Stan Development. 2024. <span>“Stan <span>Modeling Language Users Guide</span> and <span>Reference Manual</span>, Version 2.36.”</span> <a href="https://mc-stan.org">https://mc-stan.org</a>.
</div>
<div id="ref-posterior2021b" class="csl-entry">
Vehtari, Aki, Andrew Gelman, Daniel Simpson, Bob Carpenter, and Paul-Christian Bürkner. 2021. <span>“Rank-Normalization, Folding, and Localization: An Improved Rhat for Assessing Convergence of MCMC (with Discussion).”</span> <em>Bayesian Analysis</em> 16 (2): 667–718.
</div>
<div id="ref-posterior2024e" class="csl-entry">
Vehtari, Aki, Daniel Simpson, Andrew Gelman, Yuling Yao, and Jonah Gabry. 2024. <span>“Pareto Smoothed Importance Sampling.”</span> <em>Journal of Machine Learning Research</em> 25 (72): 1–58.
</div>
<div id="ref-bmlm2023" class="csl-entry">
Vuorre, Matti. 2023. <em><span class="nocase">bmlm</span>: Bayesian Multilevel Mediation</em>. <a href="https://CRAN.R-project.org/package=bmlm">https://CRAN.R-project.org/package=bmlm</a>.
</div>
<div id="ref-vuorreBmlmBayesianMultilevel2024" class="csl-entry">
———. (2016) 2024. <span>“Bmlm: <span>Bayesian</span> Multilevel Mediation.”</span> <a href="https://github.com/mvuorre/bmlm">https://github.com/mvuorre/bmlm</a>.
</div>
<div id="ref-vuorreWithinsubjectMediationAnalysis2017" class="csl-entry">
Vuorre, Matti, and Niall Bolger. 2017. <span>“Within-Subject Mediation Analysis for Experimental Data in Cognitive Psychology and Neuroscience.”</span> <em>Behavior Research Methods</em>, December, 1–19. <a href="https://doi.org/10.3758/s13428-017-0980-9">https://doi.org/10.3758/s13428-017-0980-9</a>.
</div>
<div id="ref-bmlm2018" class="csl-entry">
———. 2018. <span>“Within-Subject Mediation Analysis for Experimental Data in Cognitive Psychology and Neuroscience.”</span> <em>Behavior Research Methods</em>. <a href="https://doi.org/10.3758/s13428-017-0980-9">https://doi.org/10.3758/s13428-017-0980-9</a>.
</div>
<div id="ref-ggplot" class="csl-entry">
Wickham, Hadley. 2016. <em>Ggplot2: Elegant Graphics for Data Analysis</em>. Springer-Verlag New York. <a href="https://ggplot2.tidyverse.org">https://ggplot2.tidyverse.org</a>.
</div>
<div id="ref-tidyverse" class="csl-entry">
Wickham, Hadley, Mara Averick, Jennifer Bryan, Winston Chang, Lucy D’Agostino McGowan, Romain François, Garrett Grolemund, et al. 2019. <span>“Welcome to the <span class="nocase">tidyverse</span>.”</span> <em>Journal of Open Source Software</em> 4 (43): 1686. <a href="https://doi.org/10.21105/joss.01686">https://doi.org/10.21105/joss.01686</a>.
</div>
<div id="ref-scales" class="csl-entry">
Wickham, Hadley, Thomas Lin Pedersen, and Dana Seidel. 2023. <em><span class="nocase">scales</span>: Scale Functions for Visualization</em>. <a href="https://doi.org/10.32614/CRAN.package.scales">https://doi.org/10.32614/CRAN.package.scales</a>.
</div>
<div id="ref-knitr2014" class="csl-entry">
Xie, Yihui. 2014. <span>“<span class="nocase">knitr</span>: A Comprehensive Tool for Reproducible Research in <span>R</span>.”</span> In <em>Implementing Reproducible Computational Research</em>, edited by Victoria Stodden, Friedrich Leisch, and Roger D. Peng. Chapman; Hall/CRC.
</div>
<div id="ref-knitr2015" class="csl-entry">
———. 2015. <em>Dynamic Documents with <span>R</span> and Knitr</em>. 2nd ed. Boca Raton, Florida: Chapman; Hall/CRC. <a href="https://yihui.org/knitr/">https://yihui.org/knitr/</a>.
</div>
<div id="ref-knitr2025" class="csl-entry">
———. 2025. <em><span class="nocase">knitr</span>: A General-Purpose Package for Dynamic Report Generation in <span>R</span></em>. <a href="https://yihui.org/knitr/">https://yihui.org/knitr/</a>.
</div>
</div></section><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{vuorre2025,
  author = {Vuorre, Matti},
  title = {Bayesian Multilevel Mediation with Brms},
  date = {2025-05-02},
  url = {https://vuorre.com/posts/bmlm-multilevel-mediation/},
  langid = {en},
  abstract = {This post shows how to fit a three-variable multilevel
    mediation model with brms.}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-vuorre2025" class="csl-entry quarto-appendix-citeas">
Vuorre, Matti. 2025. <span>“Bayesian Multilevel Mediation with
Brms.”</span> May 2, 2025. <a href="https://vuorre.com/posts/bmlm-multilevel-mediation/">https://vuorre.com/posts/bmlm-multilevel-mediation/</a>.
</div></div></section></div> ]]></description>
  <category>r</category>
  <category>statistics</category>
  <guid>https://vuorre.com/posts/bmlm-multilevel-mediation/</guid>
  <pubDate>Thu, 01 May 2025 22:00:00 GMT</pubDate>
</item>
<item>
  <title>My peer review principles &amp; practices</title>
  <dc:creator>Matti Vuorre</dc:creator>
  <link>https://vuorre.com/posts/open-peer-review/</link>
  <description><![CDATA[ 





<p>In this entry, I outline my approach to evaluating scientific outputs based on the principles of transparency and openness.<sup>1</sup> I also include my template responses to review invitations.</p>
<section id="background-and-principles" class="level2">
<h2 class="anchored" data-anchor-id="background-and-principles">Background and principles</h2>
<p>I signed/joined the <a href="https://www.opennessinitiative.org/the-initiative/">PRO Initiative</a> way back when I was a PhD student, but just to remind myself:</p>
<blockquote class="blockquote">
<p>Openness and transparency are core values of science. As a manifestation of those values, a minimum requirement for publication of any scientific results must be the public submission of materials used in generating those results. As reviewers, it is our responsibility to ensure that publications meet certain minimum quality standards.</p>
<p>We therefore agree that as reviewers, starting 1 January 2017, we will not offer comprehensive review for, nor recommend the publication of, any manuscript that does not meet the following minimum requirements. Once such a manuscript has been certified by the authors to meet these minimum requirements, we will proceed with a more comprehensive review of the manuscript.</p>
<p>– <a href="https://www.opennessinitiative.org/the-initiative/">PRO Initiative</a>; <span class="citation" data-cites="moreyPeerReviewersOpenness2016">Morey et al. (2016)</span></p>
</blockquote>
<p>More recently I’ve been entertaining the idea of joining/signing something similar but regarding open assessment—the practice of i. evaluating openly available works and ii. making the evaluations themselves public. For example, I find <a href="https://nikokriegeskorte.org/category/open-review/">Nikolaus Kriegeskorte</a>’s Open Evaluation proposal very agreeable:</p>
<blockquote class="blockquote">
<p>“The current system of scientific publishing provides only journal prestige as an indication of the quality of new papers and relies on a non-transparent and noisy pre-publication peer-review process, which delays publication by many months on average. Here I propose an OE [Open Evaluation] system, in which papers are evaluated post-publication in an ongoing fashion by means of open peer review and rating. […] OA [Open Access] and OE together have the power to revolutionize scientific publishing and usher in a new culture of transparency, constructive criticism, and collaboration.</p>
<p>– <span class="citation" data-cites="kriegeskorteOpenEvaluationVision2012">Kriegeskorte (2012)</span></p>
</blockquote>
<p>The scientific enterprise relies on access to accurate information. One of the ways in which scientists have tried to ensure that information is accurate is the process of <strong>peer-review</strong>, where experts look at your work and evaluate whether it’s up to snuff. While the primary fruits of the peer-review process (the manuscripts) are increasingly openly available, the reviews (and editorial notes) are typically not. This creates a situation whereby consumers of the scientific literature must trust the peer-review process without the being able to evaluate and learn from the evaluations themselves.</p>
<p>Many have suggested that this closed approach to evaluation might be suboptimal <span class="citation" data-cites="kriegeskorteOpenEvaluationVision2012 holcombeScientistsWhatAre2025">(Kriegeskorte 2012; Holcombe 2025)</span>. Moreover, the peer reviews themselves can contain information that could be widely applicable outside the specific review context. Therefore, I am taking the following steps to increase my engagement with open assessment of scientific research:</p>
</section>
<section id="practices" class="level2">
<h2 class="anchored" data-anchor-id="practices">Practices</h2>
<div class="callout callout-style-simple callout-tip no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<ul>
<li>I review (and edit) for outlets that implement open evaluation, such as <a href="https://rr.peercommunityin.org/">PCI: Registered Reports</a></li>
<li>I make my reviews publicly available (e.g.&nbsp;on <a href="https://prereview.org/profiles/0000-0001-5052-066X">PREreview</a>, my blog, etc.)</li>
<li>I adhere to the PRO Initiative’s transparency and openness <a href="https://www.opennessinitiative.org/the-initiative/">guidelines</a></li>
<li>I acknowledge that e.g.&nbsp;privacy reasons may require deviating from these guidelines</li>
</ul>
</div>
</div>
</div>
</section>
<section id="template-responses" class="level2">
<h2 class="anchored" data-anchor-id="template-responses">Template responses</h2>
<p>Here’s some boilerplate text that I use in my responses to review invitations.</p>
<section id="when-no-preprint-exists" class="level3">
<h3 class="anchored" data-anchor-id="when-no-preprint-exists">When no preprint exists</h3>
<div class="callout callout-style-simple callout-warning no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>Thank you for considering me as a reviewer. I was not able to find a publicly available version of this manuscript, and so will tentatively decline your request. If you can point me to the publicly available manuscript, or if the authors make the manuscript publicly available, I would be happy to provide my signed review which I will also post publicly on PREreview (https://prereview.org/profiles/0000-0001-5052-066X) under a CC-BY 4.0 license to ensure it is permanently available and citeable.</p>
<p>This approach aligns with my commitment to rigorous, open, transparent, and citeable peer review of publicly available scientific work. (see e.g.&nbsp;Kriegeskorte, 2012 “Open Evaluation: A Vision for Entirely Transparent Post-Publication Peer Review and Rating for Science”). (If a preprint already exists, I apologize for missing it and would be happy to review it if you can provide a link to it.) Please let me know if you have any questions about this process.</p>
</div>
</div>
</div>
</section>
<section id="when-a-preprint-exists" class="level3">
<h3 class="anchored" data-anchor-id="when-a-preprint-exists">When a preprint exists</h3>
<div class="callout callout-style-simple callout-note no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>Thank you for considering me as a reviewer. I am happy to provide my signed review which I will also post publicly on PREreview (https://prereview.org/profiles/0000-0001-5052-066X) under a CC-BY 4.0 license to ensure it is permanently available and citeable.</p>
<p>This approach aligns with my commitment to open science and transparent evaluation (see e.g.&nbsp;Kriegeskorte, 2012 “Open Evaluation: A Vision for Entirely Transparent Post-Publication Peer Review and Rating for Science”). Please let me know if you would prefer to not have me upload a public review, or if have any questions about this process.</p>
</div>
</div>
</div>
</section>
<section id="open-datamaterials" class="level3">
<h3 class="anchored" data-anchor-id="open-datamaterials">Open data/materials</h3>
<p>When data/materials are not shared or transparently cited (see <a href="https://www.opennessinitiative.org/guidelines-for-action-editors-and-reviews/" class="uri">https://www.opennessinitiative.org/guidelines-for-action-editors-and-reviews/</a>) I will communicate to the editor that</p>
<div class="callout callout-style-simple callout-warning no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>I believe strongly in the value of openness and transparency. Please ask the authors on my behalf whether they can certify that they have met the standards of the Peer Reviewers’ Openness Initiative (https://opennessinitiative.org/).</p>
<p>– <a href="https://www.opennessinitiative.org/the-initiative/">PRO Initiative</a>; <span class="citation" data-cites="moreyPeerReviewersOpenness2016">Morey et al. (2016)</span></p>
</div>
</div>
</div>
<p>If a resubmission doesn’t meet the basic PRO requirements, I will communicate that</p>
<div class="callout callout-style-simple callout-important no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>I cannot recommend this paper for publication, as it does not meet the minimum quality requirements for an open scientific manuscript (see https://opennessinitiative.org/). I would be happy to review a revision of the manuscript that corrects this critical oversight.</p>
<p>– <a href="https://www.opennessinitiative.org/the-initiative/">PRO Initiative</a>; <span class="citation" data-cites="moreyPeerReviewersOpenness2016">Morey et al. (2016)</span></p>
</div>
</div>
</div>
</section>
</section>
<section id="conclusion" class="level2">
<h2 class="anchored" data-anchor-id="conclusion">Conclusion</h2>
<p>There is no conclusion. How we conduct, communicate, and evaluate scientific research is and always will be a work in progress. This document simply outlines my modest attempts at keeping up with (what I perceive to be) the latest gold-standard practices in transparent communication and evaluation.</p>
</section>




<div id="quarto-appendix" class="default"><section id="further-reading" class="level2 appendix"><h2 class="anchored quarto-appendix-heading">Further reading</h2><div class="quarto-appendix-contents">

<p>Some valuable background reading on these topics can be found in <span class="citation" data-cites="ahmedFutureAcademicPublishing2023">Ahmed et al. (2023)</span>; <span class="citation" data-cites="aleksicOpenSciencePeer2015">Aleksic et al. (2015)</span>; <span class="citation" data-cites="eisenImplementingPublishThen2020">Eisen et al. (2020)</span>; <span class="citation" data-cites="holcombeScientistsWhatAre2025">Holcombe (2025)</span>; <span class="citation" data-cites="kathawallaEasingOpenScience2021">Kathawalla, Silverstein, and Syed (2021)</span>; <span class="citation" data-cites="kriegeskorteOpenEvaluationVision2012">Kriegeskorte (2012)</span>; <span class="citation" data-cites="moreyPeerReviewersOpenness2016">Morey et al. (2016)</span>; <span class="citation" data-cites="moshontzGuidePostingManaging2021">Moshontz et al. (2021)</span>; <span class="citation" data-cites="severBiomedicalPublishingHistoric2023">Sever (2023)</span>; <span class="citation" data-cites="silversteinGuideSocialScience2024">Silverstein et al. (2024)</span>; <span class="citation" data-cites="syedValuingPreprintsMust2024">Syed (2024)</span>. <span class="citation" data-cites="silversteinGuideSocialScience2024">Silverstein et al. (2024)</span> might be especially relevant when communicating these ideas to editors.</p>
<p>Feature image credit: <a href="https://undraw.co/" class="uri">https://undraw.co/</a>.</p>
</div></section><section id="feedback-comments" class="level2 appendix"><h2 class="anchored quarto-appendix-heading">Feedback &amp; comments</h2><div class="quarto-appendix-contents">

<p>I’d appreciate any feedback on these ideas/practices; feel free to le me know what you think either using the comments field (below) or on Bluesky:</p>
    <bluesky-comments post="at://did:plc:ai4isl2n4j2h7qcqebj7vu2k/app.bsky.feed.post/3lhbko45psk2c" filter-config="{&quot;filterEmptyReplies&quot;:true,&quot;mutePatterns&quot;:[],&quot;muteUsers&quot;:[]}" profile="did:plc:ai4isl2n4j2h7qcqebj7vu2k"></bluesky-comments>
  



</div></section><section class="quarto-appendix-contents" id="quarto-bibliography"><h2 class="anchored quarto-appendix-heading">References</h2><div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="0">
<div id="ref-ahmedFutureAcademicPublishing2023" class="csl-entry">
Ahmed, Abubakari, Aceil Al-Khatib, Yap Boum, Humberto Debat, Alonso Gurmendi Dunkelberg, Lisa Janicke Hinchliffe, Frith Jarrad, et al. 2023. <span>“The Future of Academic Publishing.”</span> <em>Nature Human Behaviour</em>, July, 1–6. <a href="https://doi.org/10.1038/s41562-023-01637-2">https://doi.org/10.1038/s41562-023-01637-2</a>.
</div>
<div id="ref-aleksicOpenSciencePeer2015" class="csl-entry">
Aleksic, Jelena, Adrian Alexa, Teresa K. Attwood, Neil Chue Hong, Martin Dahlö, Robert Davey, Holger Dinkel, et al. 2015. <span>“An <span>Open Science Peer Review Oath</span>.”</span> January 9, 2015. <a href="https://doi.org/10.12688/f1000research.5686.2">https://doi.org/10.12688/f1000research.5686.2</a>.
</div>
<div id="ref-eisenImplementingPublishThen2020" class="csl-entry">
Eisen, Michael B, Anna Akhmanova, Timothy E Behrens, Diane M Harper, Detlef Weigel, and Mone Zaidi. 2020. <span>“Implementing a "Publish, Then Review" Model of Publishing.”</span> <em>eLife</em> 9 (December): e64910. <a href="https://doi.org/10.7554/eLife.64910">https://doi.org/10.7554/eLife.64910</a>.
</div>
<div id="ref-holcombeScientistsWhatAre2025" class="csl-entry">
Holcombe, Alex O. 2025. <span>“Scientists! <span>What</span> Are You Supporting?”</span> Alex Holcombe’s blog. January 31, 2025. <a href="https://alexholcombe.wordpress.com/2025/01/31/scientists-what-are-you-supporting/">https://alexholcombe.wordpress.com/2025/01/31/scientists-what-are-you-supporting/</a>.
</div>
<div id="ref-kathawallaEasingOpenScience2021" class="csl-entry">
Kathawalla, Ummul-Kiram, Priya Silverstein, and Moin Syed. 2021. <span>“Easing <span>Into Open Science</span>: <span>A Guide</span> for <span>Graduate Students</span> and <span>Their Advisors</span>.”</span> Edited by Eunike Wetzel. <em>Collabra: Psychology</em> 7 (1): 18684. <a href="https://doi.org/10.1525/collabra.18684">https://doi.org/10.1525/collabra.18684</a>.
</div>
<div id="ref-kriegeskorteOpenEvaluationVision2012" class="csl-entry">
Kriegeskorte, Nikolaus. 2012. <span>“Open <span>Evaluation</span>: <span>A Vision</span> for <span>Entirely Transparent Post-Publication Peer Review</span> and <span>Rating</span> for <span>Science</span>.”</span> <em>Frontiers in Computational Neuroscience</em> 6. <a href="https://doi.org/10.3389/fncom.2012.00079">https://doi.org/10.3389/fncom.2012.00079</a>.
</div>
<div id="ref-moreyPeerReviewersOpenness2016" class="csl-entry">
Morey, Richard D., Christopher D. Chambers, Peter J. Etchells, Christine R. Harris, Rink Hoekstra, Daniël Lakens, Stephan Lewandowsky, et al. 2016. <span>“The <span>Peer Reviewers Openness Initiative</span>: Incentivizing Open Research Practices Through Peer Review.”</span> <em>Royal Society Open Science</em> 3 (1): 150547. <a href="https://doi.org/10.1098/rsos.150547">https://doi.org/10.1098/rsos.150547</a>.
</div>
<div id="ref-moshontzGuidePostingManaging2021" class="csl-entry">
Moshontz, Hannah, Grace Binion, Haley Walton, Benjamin T. Brown, and Moin Syed. 2021. <span>“A <span>Guide</span> to <span>Posting</span> and <span>Managing Preprints</span>.”</span> <em>Advances in Methods and Practices in Psychological Science</em> 4 (2): 25152459211019948. <a href="https://doi.org/10.1177/25152459211019948">https://doi.org/10.1177/25152459211019948</a>.
</div>
<div id="ref-severBiomedicalPublishingHistoric2023" class="csl-entry">
Sever, Richard. 2023. <span>“Biomedical Publishing: <span>Past</span> Historic, Present Continuous, Future Conditional.”</span> <em>PLOS Biology</em> 21 (10): e3002234. <a href="https://doi.org/10.1371/journal.pbio.3002234">https://doi.org/10.1371/journal.pbio.3002234</a>.
</div>
<div id="ref-silversteinGuideSocialScience2024" class="csl-entry">
Silverstein, Priya, Colin Elman, Amanda Montoya, Barbara McGillivray, Charlotte R. Pennington, Chase H. Harrison, Crystal N. Steltenpohl, et al. 2024. <span>“A Guide for Social Science Journal Editors on Easing into Open Science.”</span> <em>Research Integrity and Peer Review</em> 9 (1): 2. <a href="https://doi.org/10.1186/s41073-023-00141-5">https://doi.org/10.1186/s41073-023-00141-5</a>.
</div>
<div id="ref-syedValuingPreprintsMust2024" class="csl-entry">
Syed, Moin. 2024. <span>“Valuing <span>Preprints Must</span> Be <span>Part</span> of <span>Responsible Research Assessment</span>.”</span> <em>Meta-Psychology</em> 8 (March). <a href="https://doi.org/10.15626/MP.2023.3758">https://doi.org/10.15626/MP.2023.3758</a>.
</div>
</div></section><section id="footnotes" class="footnotes footnotes-end-of-document"><h2 class="anchored quarto-appendix-heading">Footnotes</h2>

<ol>
<li id="fn1"><p>Obviously I also review the manuscripts on their content, but that is not the topic of this post.↩︎</p></li>
</ol>
</section><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{vuorre2025,
  author = {Vuorre, Matti},
  title = {My Peer Review Principles \&amp; Practices},
  date = {2025-02-03},
  url = {https://vuorre.com/posts/open-peer-review/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-vuorre2025" class="csl-entry quarto-appendix-citeas">
Vuorre, Matti. 2025. <span>“My Peer Review Principles &amp;
Practices.”</span> February 3, 2025. <a href="https://vuorre.com/posts/open-peer-review/">https://vuorre.com/posts/open-peer-review/</a>.
</div></div></section></div> ]]></description>
  <category>communication</category>
  <category>research</category>
  <guid>https://vuorre.com/posts/open-peer-review/</guid>
  <pubDate>Sun, 02 Feb 2025 23:00:00 GMT</pubDate>
  <media:content url="https://vuorre.com/posts/open-peer-review/images/undraw_collaboration_dtwk.png" medium="image" type="image/png" height="133" width="144"/>
</item>
<item>
  <title>Preprints: A Quarto extension and website</title>
  <dc:creator>Matti Vuorre</dc:creator>
  <link>https://vuorre.com/posts/quarto-preprint-psyarxiv-zero/</link>
  <description><![CDATA[ 





<p>It turns out that preprints are both important and pretty, <a href="https://youtu.be/kRz8-EXlhBo?feature=shared">pretty good</a> <span class="citation" data-cites="ahmedFutureAcademicPublishing2023 moshontzGuidePostingManaging2021 severBiomedicalPublishingHistoric2023 syedValuingPreprintsMust2024">(Ahmed et al. 2023; Moshontz et al. 2021; Sever 2023; Syed 2024)</span>. In fact in the modern scholarly publishing and communication ecosystem, the word “pre<em>print</em>” is a bit of misnomer: “Preprint” can refer to peer-reviewed <span class="citation" data-cites="vuorreThreeObjectionsNovel2022">(e.g. Vuorre, Johannes, and Przybylski 2022)</span> and non-peer-reviewed <span class="citation" data-cites="ballouHowVideoGames2024">(e.g. Ballou et al. 2024)</span> documents that may or may not ever be printed on physical paper. I think many in the community think of them as either (1) non-peer-reviewed documents that communicate scholarly arguments/content, or (2) pre-typeset versions of peer-reviewed (or otherwise “ready for production”) documents about to be published in a journal.</p>
<p>Many related issues remain before the community is ready to follow more mature sciences and embrace preprints as bona-fide scholarly outputs <span class="citation" data-cites="petrichoweNatureTakeWhat2022 syedValuingPreprintsMust2024">(Petrić Howe et al. 2022; Syed 2024)</span>, including discovery (how will I find signal from all this [subjective] noise?), and typesetting (“make papers look not awful”) which we so dearly love. Below, I describe my recent efforts on these two fronts.</p>
<section id="discovery" class="level2">
<h2 class="anchored" data-anchor-id="discovery">Discovery</h2>
<p>There are a handful of very popular preprint services, such as <a href="https://arxiv.org/">arXiv</a>, the OG preprint server for hard sciences, and <a href="https://www.biorxiv.org/">bioRxiv</a> for the biological sciences. <a href="https://osf.io/preprints">OSF Preprints</a> is a “A scholarly commons to connect the entire research cycle”, and home to some two dozen field-specific preprint services such as <a href="https://osf.io/preprints/metaarxiv">MetaArXiv</a> (metascience) and <a href="https://osf.io/preprints/psyarxiv">PsyArXiv</a> (psychology). While all these services offer support for categorizing / tagging submissions, it is still often the case that researchers find it difficult to follow the latest (and greatest?) in their chosen area of interest.</p>
<p>For my areas of interest in the psychological sciences, I try to keep an eye on the Social and Behavioral Sciences <a href="https://osf.io/search?activeFilters=%5B%7B%22propertyVisibleLabel%22%3A%22Subject%22%2C%22propertyPathKey%22%3A%22subject%22%2C%22label%22%3A%22Social%20and%20Behavioral%20Sciences%22%2C%22value%22%3A%22https%3A%2F%2Fapi.osf.io%2Fv2%2Fsubjects%2F584240da54be81056cecac48%22%7D%5D&amp;q=&amp;resourceType=Preprint&amp;sort=-relevance&amp;view_only=">category</a> on OSF Preprints, and a small handful of more focused categories on the PsyArXiv discovery <a href="https://osf.io/preprints/psyarxiv/discover">feed</a>. These allow me to narrow down the feeds by e.g.&nbsp;author, subject, date, etc, and order them by date. So effectively I can have, say, a <a href="https://osf.io/preprints/psyarxiv/discover?activeFilters=%5B%7B%22propertyVisibleLabel%22%3A%22Subject%22%2C%22propertyPathKey%22%3A%22subject%22%2C%22label%22%3A%22Cognitive%20Psychology%22%2C%22value%22%3A%22https%3A%2F%2Fapi.osf.io%2Fv2%2Fsubjects%2F584240da54be81056cecab7e%22%7D%2C%7B%22propertyVisibleLabel%22%3A%22Has%20related%20resource%22%2C%22propertyPathKey%22%3A%22hasPreregisteredAnalysisPlan%22%2C%22label%22%3A%22Preregistered%20analysis%20plan%22%2C%22value%22%3A%22is-present%22%2C%22suggestedFilterOperator%22%3A%22is-present%22%7D%5D&amp;sort=-dateCreated">feed</a> for the latest preprints in Cognitive Psychology that have pre-registered analysis plans and refresh it every morning in my browser. This is very cool.</p>
<section id="psyarxiv-zero" class="level3">
<h3 class="anchored" data-anchor-id="psyarxiv-zero">Psyarxiv Zero</h3>
<p>I wanted to build on this service to allow users to subscribe (e.g.&nbsp;via email or website account) to different custom feeds, and to present them in a fast text-based UI. To date I haven’t had time to make much progress on the first goal, but have finished a prototype for the latter (fast UI) at <a href="https://psyarxiv.vuorre.com" class="uri">https://psyarxiv.vuorre.com</a>. This website, Psyarxiv Zero<sup>1</sup>, at the moment presents a simple feed of recently (users can specify a time-frame) posted or edited preprints from PsyArXiv (Figure&nbsp;1).</p>
<div id="fig-1" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/quarto-preprint-psyarxiv-zero/images/psyarxiv-zero-home.png" class="img-fluid figure-img">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;1: Screenshot of Psyarxiv Zero homepage
</figcaption>
</figure>
</div>
<p>Clicking on any of the titles on the homepage sends the user to a preprint’s page (Figure&nbsp;2). I tried to make this page display the preprints main summaries (links, authors, keywords, and abstract) in an information-dense manner.</p>
<div id="fig-2" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/quarto-preprint-psyarxiv-zero/images/psyarxiv-zero-item.png" class="img-fluid figure-img">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;2: Screenshot of Psyarxiv Zero preprint page
</figcaption>
</figure>
</div>
<p>A lot of work remains to make this alternative UI for PsyArXiv (in the future, OSF Preprints more broadly) more useable and feature-rich. But at the moment I am happy with its performance—which is only limited by the speed of responses from the OSF API—and UI. Take it for a spin and give me your worst feedback / bug reports / feature requests at <a href="https://github.com/mvuorre/psyarxiv-ui" class="uri">https://github.com/mvuorre/psyarxiv-ui</a>.</p>
</section>
</section>
<section id="typesetting" class="level2">
<h2 class="anchored" data-anchor-id="typesetting">Typesetting</h2>
<p>I have a hunch that the typesetting of an article plays some non-ignorable role in readers’ credibility judgments of manuscripts made under time pressure and without other quality indicators. Moreover, reading a well-typeset document is a more pleasant experience than reading a poorly-typeset one. These (non-?)issues related to typesetting are prominent for readers of preprints, because preprints do not have any formatting standards or requirements. That’s probably a good thing, but at least I find reading typeset manuscripts a less onerous task.</p>
<p>I write most of my manuscripts in a computationally reproducible manner—in source documents that combine analysis code, its outputs, and prose—using <a href="https://quarto.org/">Quarto</a>. Quarto already has many <a href="https://quarto.org/docs/extensions/listing-journals.html">extensions</a> for producing (PDF) documents typeset to several journals’ requirements. In my field, the most relevant one is <a href="https://github.com/wjschne/apaquarto">apaquarto</a> that typesets documents to the American Psychological Association guidelines.</p>
<p>However I think many of these journal- or society-specific typesetting systems have a drawback: They require users to commit to a specific journal’s formatting requirements before knowing whether the paper will even end up in that journal; after rejection users will have to change to another format. Using Quarto makes this process easier by promising standard metadata fields for manuscripts, such as the ways in which author information should be formatted. Nevertheless, many format extensions require idiosyncratic settings / metadata, making switching between journal formats not quite the click of a button workflow as promised by Quarto.</p>
<p>Therefore, to add to the existing high-quality, but journal (or society-) specific Quarto formats, I wrote a little Quarto Typst extension called <a href="https://mvuorre.github.io/quarto-preprint/"><code>quarto-prepint</code></a> (<a href="https://mvuorre.github.io/quarto-preprint/index.pdf">PDF</a>). My aim with it is to enable fast and not-too-opinionated typesetting for computationally reproducible preprints written with <a href="https://quarto.org/">Quarto</a>. I paste from quarto-preprint’s manual below:</p>
<section id="quarto-preprint" class="level3">
<h3 class="anchored" data-anchor-id="quarto-preprint">quarto-preprint</h3>
<p><a href="https://quarto.org">Quarto</a> is an “<em>An open-source scientific and technical publishing system</em>”. It is both a markup language that extends <a href="https://pandoc.org/">pandoc</a> <a href="https://quarto.org/docs/authoring/markdown-basics.html">Markdown</a> and a program that renders source code written in Quarto Markdown to a variety of formats including PDF, MS Word, HTML, ePub, and many <a href="https://quarto.org/docs/output-formats/all-formats.html">more</a>. This source code can include prose (this text), maths (<img src="https://latex.codecogs.com/png.latex?%5Csqrt%7B2%7D">), code evaluation (<code>{r} sqrt(2)</code> renders to 1.414), scholarly <a href="https://quarto.org/docs/authoring/front-matter.html">metadata</a>, and more. In short, Quarto is a language and engine for reproducible manuscripts.</p>
<p>The look and feel of the output documents can be controlled within the source document (e.g.&nbsp;<a href="https://quarto.org/docs/output-formats/html-basics.html">here</a>), or by using a Quarto <a href="https://quarto.org/docs/extensions/">extension</a>. <a href="https://github.com/mvuorre/quarto-preprint"><code>quarto-preprint</code></a> is such an extension, designed to produce neat PDF documents quickly with minimum fuss. It is called “preprint” because it provides a basic layout in a Quarto-standards compliant package, allowing users to easily switch to a journal-specific <a href="https://quarto.org/docs/extensions/listing-journals.html">extension</a> if they so choose. It also produces basic Word .docx documents to facilitate collaboration and/or further WYSIWYG editing.</p>
<p>Why might one use the <code>preprint</code> extension? One, it renders documents from Quarto markdown to PDF using <a href="https://typst.app/docs">Typst</a><sup>2</sup>, and therefore is very fast in doing so. Typst doesn’t require complicated TeX installations and so is practically easier to use than other PDF-producing methods. Typst also simplifies the development and codebase of <code>preprint</code>, thus making edits, bug fixes, forks, and new features easier. Second, <code>preprint</code> aims to be 100% Quarto standards compliant: Users don’t need to adapt their source code in any way when they switch to other formats, such as other journal extensions, or completely different output formats such as HTML<sup>3</sup>.</p>
<p>If this sounds interesting, read more <a href="https://github.com/mvuorre/quarto-preprint">here</a>.</p>
</section>
</section>
<section id="conclusion" class="level2">
<h2 class="anchored" data-anchor-id="conclusion">Conclusion</h2>
<p>I encourage scholars to think more proactively about the roles that preprints play in the modern scholarly communication landscape <span class="citation" data-cites="severBiomedicalPublishingHistoric2023 syedValuingPreprintsMust2024 moshontzGuidePostingManaging2021 ahmedFutureAcademicPublishing2023">(Sever 2023; Syed 2024; Moshontz et al. 2021; Ahmed et al. 2023)</span>. To this end (and to learn web and Quarto extension development <span class="emoji" data-emoji="smile">😄</span>), I put together two (early-stage) resources for preprint authors and readers. If you try them out, feel free to let me know what’s wrong with them!</p>



</section>


<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-bibliography"><h2 class="anchored quarto-appendix-heading">References</h2><div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="0">
<div id="ref-ahmedFutureAcademicPublishing2023" class="csl-entry">
Ahmed, Abubakari, Aceil Al-Khatib, Yap Boum, Humberto Debat, Alonso Gurmendi Dunkelberg, Lisa Janicke Hinchliffe, Frith Jarrad, et al. 2023. <span>“The Future of Academic Publishing.”</span> <em>Nature Human Behaviour</em>, July, 1–6. <a href="https://doi.org/10.1038/s41562-023-01637-2">https://doi.org/10.1038/s41562-023-01637-2</a>.
</div>
<div id="ref-ballouHowVideoGames2024" class="csl-entry">
Ballou, Nick, Thomas Hakman, Matti Vuorre, Kristoffer Magnusson, and Andrew K. Przybylski. 2024. <span>“How Do Video Games Affect Mental Health? <span>A</span> Narrative Review of 13 Proposed Mechanisms.”</span> OSF. <a href="https://doi.org/10.31234/osf.io/q2kxg">https://doi.org/10.31234/osf.io/q2kxg</a>.
</div>
<div id="ref-moshontzGuidePostingManaging2021" class="csl-entry">
Moshontz, Hannah, Grace Binion, Haley Walton, Benjamin T. Brown, and Moin Syed. 2021. <span>“A <span>Guide</span> to <span>Posting</span> and <span>Managing Preprints</span>.”</span> <em>Advances in Methods and Practices in Psychological Science</em> 4 (2): 25152459211019948. <a href="https://doi.org/10.1177/25152459211019948">https://doi.org/10.1177/25152459211019948</a>.
</div>
<div id="ref-petrichoweNatureTakeWhat2022" class="csl-entry">
Petrić Howe, Nick, Elizabeth Gibney, Ehsan Masood, and Zoltan Fehervari. 2022. <span>“Nature’s <span>Take</span>: What’s Next for the Preprint Revolution.”</span> <em>Nature</em>, August. <a href="https://doi.org/10.1038/d41586-022-01985-5">https://doi.org/10.1038/d41586-022-01985-5</a>.
</div>
<div id="ref-severBiomedicalPublishingHistoric2023" class="csl-entry">
Sever, Richard. 2023. <span>“Biomedical Publishing: <span>Past</span> Historic, Present Continuous, Future Conditional.”</span> <em>PLOS Biology</em> 21 (10): e3002234. <a href="https://doi.org/10.1371/journal.pbio.3002234">https://doi.org/10.1371/journal.pbio.3002234</a>.
</div>
<div id="ref-syedValuingPreprintsMust2024" class="csl-entry">
Syed, Moin. 2024. <span>“Valuing <span>Preprints Must</span> Be <span>Part</span> of <span>Responsible Research Assessment</span>.”</span> <em>Meta-Psychology</em> 8 (March). <a href="https://doi.org/10.15626/MP.2023.3758">https://doi.org/10.15626/MP.2023.3758</a>.
</div>
<div id="ref-vuorreThreeObjectionsNovel2022" class="csl-entry">
Vuorre, Matti, Niklas Johannes, and Andrew K. Przybylski. 2022. <span>“Three Objections to a Novel Paradigm in Social Media Effects Research.”</span> PsyArXiv. <a href="https://doi.org/10.31234/osf.io/dpuya">https://doi.org/10.31234/osf.io/dpuya</a>.
</div>
</div></section><section id="footnotes" class="footnotes footnotes-end-of-document"><h2 class="anchored quarto-appendix-heading">Footnotes</h2>

<ol>
<li id="fn1"><p>Yes I quite like the look and feel of Hacker News and tried to copy much of it.↩︎</p></li>
<li id="fn2"><p>“<em><a href="https://typst.app/docs">Typst</a> is a new markup-based typesetting system for the sciences. It is designed to be an alternative both to advanced tools like LaTeX and simpler tools like Word and Google Docs.</em>”↩︎</p></li>
<li id="fn3"><p>There are a few small features that likely won’t show up in other formats, such as <code>branding</code> (see below), but their inclusion or exclusion in the metadata doesn’t impact how sources are rendered to other formats.↩︎</p></li>
</ol>
</section><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{vuorre2024,
  author = {Vuorre, Matti},
  title = {Preprints: {A} {Quarto} Extension and Website},
  date = {2024-06-20},
  url = {https://vuorre.com/posts/quarto-preprint-psyarxiv-zero/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-vuorre2024" class="csl-entry quarto-appendix-citeas">
Vuorre, Matti. 2024. <span>“Preprints: A Quarto Extension and
Website.”</span> June 20, 2024. <a href="https://vuorre.com/posts/quarto-preprint-psyarxiv-zero/">https://vuorre.com/posts/quarto-preprint-psyarxiv-zero/</a>.
</div></div></section></div> ]]></description>
  <category>communication</category>
  <category>research</category>
  <category>workflow</category>
  <guid>https://vuorre.com/posts/quarto-preprint-psyarxiv-zero/</guid>
  <pubDate>Wed, 19 Jun 2024 22:00:00 GMT</pubDate>
  <media:content url="https://vuorre.com/posts/quarto-preprint-psyarxiv-zero/images/undraw_Reviewed_docs_re_9lmr.png" medium="image" type="image/png" height="80" width="144"/>
</item>
<item>
  <title>A quantitative methods syllabus</title>
  <dc:creator>Matti Vuorre</dc:creator>
  <link>https://vuorre.com/posts/methods-syllabus/</link>
  <description><![CDATA[ 





<section id="how-to-use-a-computer" class="level1">
<h1>How to use a computer</h1>
<ul>
<li>The Unix Shell:
<ul>
<li><a href="https://swcarpentry.github.io/shell-novice/" class="uri">https://swcarpentry.github.io/shell-novice/</a></li>
<li><a href="https://laihoconsulting.com/blog/2025-06-basics-of-linux-shell-and-shell-scripts/" class="uri">https://laihoconsulting.com/blog/2025-06-basics-of-linux-shell-and-shell-scripts/</a></li>
</ul></li>
<li>Version control and collaboration with Git: <a href="https://swcarpentry.github.io/git-novice" class="uri">https://swcarpentry.github.io/git-novice</a></li>
<li>Automating things with GNU Make: <a href="https://swcarpentry.github.io/make-novice" class="uri">https://swcarpentry.github.io/make-novice</a></li>
</ul>
</section>
<section id="statistics" class="level1">
<h1>Statistics</h1>
<p>Here are some recommended writings on statistics and data analysis for the social and behavioral sciences. This blog entry is probably most useful for students, but I also list some more advanced books that might be of interest to others.</p>
<p><em>tl;dr</em>:</p>
<ul>
<li><a href="https://avehtari.github.io/ROS-Examples"><em>Regression and other stories</em></a> <span class="citation" data-cites="gelmanRegressionOtherStories2020">(Gelman, Hill, and Vehtari 2020)</span></li>
<li><a href="https://openintro-ims.netlify.app/"><em>Introduction to Modern Statistics</em></a> <span class="citation" data-cites="cetinkaya-rundelIntroductionModernStatistics2021">(Çetinkaya-Rundel and Hardin 2021)</span></li>
<li><a href="https://xcelab.net/rm/statistical-rethinking/"><em>Statistical rethinking: a Bayesian course with examples in R and Stan</em></a> <span class="citation" data-cites="mcelreathStatisticalRethinkingBayesian2020">(McElreath 2020)</span></li>
<li><a href="https://r4ds.hadley.nz/"><em>R for Data Science</em></a> <span class="citation" data-cites="wickhamDataScienceImport2016">(Wickham, Çetinkaya-Rundel, and Grolemund 2016)</span></li>
</ul>
<section id="the-basics-regression" class="level2">
<h2 class="anchored" data-anchor-id="the-basics-regression">The basics: Regression</h2>
<p>If there is one single concept in applied statistics worth learning, it is that of <em>regression</em>. You’ve probably learned statistics in the context of p-values from hypothesis tests, ANOVAs, t-tests and stuff like that, but the underlying and unifying concept is <em>regression</em>: Modelling (a set of) outcome variables on (a set of) predictor variables. ANOVA is a regression model… Assuming that your data is normally distributed can be a regression model… So I’d advise you to just take a moment and learn what this thing called regression is and what it could do for you.</p>
<p>To get started, I recommend taking a look at this book called <a href="https://avehtari.github.io/ROS-Examples"><em>Regression and other stories</em></a> <span class="citation" data-cites="gelmanRegressionOtherStories2020">(Gelman, Hill, and Vehtari 2020)</span>. The book is freely available on the authors’ website (<a href="https://avehtari.github.io/ROS-Examples/" class="uri">https://avehtari.github.io/ROS-Examples/</a>), and is extremely accessible:</p>
<blockquote class="blockquote">
<p>Many textbooks on regression focus on theory and the simplest of examples. Real statistical problems, however, are complex and subtle. This is not a book about the theory of regression. It is a book about how to use regression to solve real problems of comparison, estimation, prediction, and causal inference. It focuses on practical issues such as sample size and missing data and a wide range of goals and techniques. It jumps right in to methods and computer code you can use fresh out of the box.</p>
</blockquote>
<p>The quote-unquote downside of this book is that it is a bit heterodox in its approach to statistical inference. I believe this to be an entirely good thing, but the orthodox approach focusing on test statistics, p-values, and hypothesis testing gets a bit less attention in this book than you’d find in those orthodox introductions. In fact this is a reason for recommending this book over alternatives, but it is useful to know this nevertheless.</p>
<p>While we’re at the topic of unorthodox approaches to statistical inference, I’ll mention another book that personally influenced my thinking a lot: <a href="https://sites.google.com/site/doingbayesiandataanalysis/"><em>Doing Bayesian Data Analysis</em></a> by John Kruschke <span class="citation" data-cites="kruschkeDoingBayesianData2014">(Kruschke 2014)</span>. This book includes code examples for conducting bayesian analyses for common scenarios in the behavioral sciences. While much appreciated at the time, modern software options have outpaced those in the book. Nevertheless it is a very well (and whimsically) written book full of educational wisdom, such as “The steps of bayesian data analysis”:</p>
<blockquote class="blockquote">
<ol type="1">
<li>Identify the data relevant to the research questions. What are the measurement scales of the data? Which data variables are to be predicted, and which data variables are supposed to act as predictors?</li>
<li>Define a descriptive model for the relevant data. The mathematical form and its parameters should be meaningful and appropriate to the theoretical purposes of the analysis.</li>
<li>Specify a prior distribution on the parameters. The prior must pass muster with the audience of the analysis, such as skeptical scientists.</li>
<li>Use Bayesian inference to re-allocate credibility across parameter values. Interpret the posterior distribution with respect to theoretically meaningful issues (assuming that the model is a reasonable description of the data; see next step).</li>
<li>Check that the posterior predictions mimic the data with reasonable accuracy (i.e., conduct a “posterior predictive check”). If not, then consider a different descriptive model.</li>
</ol>
</blockquote>
<p>Two other books about regression come to mind: <a href="https://www.john-fox.ca/AppliedRegression/index.html"><em>Applied Regression Analysis and Generalized Linear Models</em></a> <span class="citation" data-cites="foxAppliedRegressionAnalysis2015">(Fox 2015)</span> and <a href="http://irep.ntu.ac.uk/id/eprint/16540/"><em>Serious stats: a guide to advanced statistics for the behavioral sciences</em></a> <span class="citation" data-cites="baguleySeriousStatsGuide2012">(Baguley 2012)</span>. Both are very clear in their treatment of foundational concepts and include just the right amount (in my view) of mathematics. The Fox book is used a lot as a textbook for applied stats courses and I quite like it.</p>
</section>
<section id="statistical-rethinking" class="level2">
<h2 class="anchored" data-anchor-id="statistical-rethinking">Statistical rethinking</h2>
<p>This book needs its own heading here, it is just that good.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://vuorre.com/posts/methods-syllabus/images/rethinking-fig-1-1.png" class="img-fluid figure-img" alt="Example decision tree, or flowchart, for selecting an appropri- ate statistical procedure. Beginning at the top, the user answers a series of questions about measurement and intent, arriving eventually at the name of a procedure. Many such decision trees are possible."></p>
<figcaption>Figure 1.1 from “Statistical rethinking”</figcaption>
</figure>
</div>
<p>This book, <a href="https://xcelab.net/rm/statistical-rethinking/"><em>Statistical rethinking: a Bayesian course with examples in R and Stan</em></a> <span class="citation" data-cites="mcelreathStatisticalRethinkingBayesian2020">(McElreath 2020)</span> essentially <em>argues against</em> a view of statistics visualized as a decision-tree like process above. Instead, it makes the–again–heterodox suggestion that researchers should instead <em>critically think</em> about their research problem and design appropriate models that mathematically represent those problems. It also serves as an excellent textbook on bayesian statistics, which is another term for using the rules of probability to make inferences from data. This is a very good candidate for a second textbook on statistics, once you’ve confirmed with a first book that you indeed ever want to read another book on statistics again!</p>
<p>The author of this book also teaches an amazing course on statistics, and the lectures are all available on YouTube: <a href="https://www.youtube.com/playlist?list=PLDcUM9US4XdPz-KxHM4XHt7uUVGWWVSus" class="uri">https://www.youtube.com/playlist?list=PLDcUM9US4XdPz-KxHM4XHt7uUVGWWVSus</a>. Highly recommended.</p>
<p>On that topic–Bayesian statistics–the current “bible” is the third edition of <a href="http://www.stat.columbia.edu/~gelman/book/"><em>Bayesian Data Analysis</em></a> by Gelman and colleagues <span class="citation" data-cites="gelmanBayesianDataAnalysis2013">(Gelman et al. 2013)</span>. It is also freely available as a PDF on the book’s website: <a href="http://www.stat.columbia.edu/~gelman/book/" class="uri">http://www.stat.columbia.edu/~gelman/book/</a>.</p>
</section>
<section id="bonus-round-actually-doing-statistics" class="level2">
<h2 class="anchored" data-anchor-id="bonus-round-actually-doing-statistics">Bonus round: Actually doing statistics</h2>
<p>For this, you will need to make a computer do stuff. There’s very little to say about this because the 2nd edition of <a href="https://r4ds.hadley.nz/"><em>R for Data Science</em></a> <span class="citation" data-cites="wickhamDataScienceImport2016">(Wickham, Çetinkaya-Rundel, and Grolemund 2016)</span> just is that good. The (online; free) book takes you by the hand, helps you open up a software suite, and then do <em>magic</em> with it.</p>
</section>
<section id="bonus-round-2-multilevel-regression" class="level2">
<h2 class="anchored" data-anchor-id="bonus-round-2-multilevel-regression">Bonus round 2: Multilevel regression</h2>
<p>Generalized Linear <em>Mixed</em> Model. Hierarchical models. Hierarchical <em>Bayesian</em> Models. Multilevel models. Random effect models. Models with models in them. It’s just what we do and let’s call it multilevel regression. For most data analysis problems you will likely want to apply some variation of this theme. Actually the book <em>Statistical rethinking</em> above is a great read on this topic, but I thought I would mention <a href="http://www.stat.columbia.edu/~gelman/arm/"><em>Data Analysis Using Regression and Multilevel/Hierarchical Models</em></a> <span class="citation" data-cites="gelmanDataAnalysisUsing2007">(Gelman and Hill 2007)</span> because it is a damn good book. The only reason I’m leaving it here and not as the second book on this page is that it is somewhat outdated regarding some of the software presented. The upshot is that a completely revised version of this book should be out sometime soon. Once that happens, this will be up there right after <em>Regression and other stories</em>.</p>



</section>
</section>

<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-bibliography"><h2 class="anchored quarto-appendix-heading">References</h2><div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="0">
<div id="ref-baguleySeriousStatsGuide2012" class="csl-entry">
Baguley, T. 2012. <em>Serious Stats: A Guide to Advanced Statistics for the Behavioral Sciences</em>. <span>Basingstoke</span>: <span>Palgrave Macmillan</span>. <a href="http://irep.ntu.ac.uk/id/eprint/16540/">http://irep.ntu.ac.uk/id/eprint/16540/</a>.
</div>
<div id="ref-cetinkaya-rundelIntroductionModernStatistics2021" class="csl-entry">
Çetinkaya-Rundel, Mine, and Johanna Hardin. 2021. <em>Introduction to <span>Modern Statistics</span></em>. OpenIntro. <a href="https://openintro-ims.netlify.app/">https://openintro-ims.netlify.app/</a>.
</div>
<div id="ref-foxAppliedRegressionAnalysis2015" class="csl-entry">
Fox, John. 2015. <em>Applied <span>Regression Analysis</span> and <span>Generalized Linear Models</span></em>. <span>SAGE Publications</span>. <a href="https://books.google.com?id=cjB3BwAAQBAJ">https://books.google.com?id=cjB3BwAAQBAJ</a>.
</div>
<div id="ref-gelmanBayesianDataAnalysis2013" class="csl-entry">
Gelman, Andrew, John B. Carlin, Hal S. Stern, David B. Dunson, Aki Vehtari, and Donald B. Rubin. 2013. <em>Bayesian <span>Data Analysis</span>, <span>Third Edition</span></em>. <span>Boca Raton</span>: <span>Chapman and Hall/CRC</span>. <a href="http://www.stat.columbia.edu/~gelman/book/">http://www.stat.columbia.edu/~gelman/book/</a>.
</div>
<div id="ref-gelmanDataAnalysisUsing2007" class="csl-entry">
Gelman, Andrew, and Jennifer Hill. 2007. <em>Data <span>Analysis Using Regression</span> and <span>Multilevel</span>/<span>Hierarchical Models</span></em>. <span>New York, NY</span>: <span>Cambridge University Press</span>. <a href="http://www.stat.columbia.edu/~gelman/arm/">http://www.stat.columbia.edu/~gelman/arm/</a>.
</div>
<div id="ref-gelmanRegressionOtherStories2020" class="csl-entry">
Gelman, Andrew, Jennifer Hill, and Aki Vehtari. 2020. <em>Regression and <span>Other Stories</span></em>. <span>Cambridge University Press</span>. <a href="https://avehtari.github.io/ROS-Examples/">https://avehtari.github.io/ROS-Examples/</a>.
</div>
<div id="ref-kruschkeDoingBayesianData2014" class="csl-entry">
Kruschke, John K. 2014. <em>Doing <span>Bayesian Data Analysis</span>: <span>A Tutorial Introduction</span> with <span>R</span></em>. 2nd Edition. <span>Burlington, MA</span>: <span>Academic Press</span>. <a href="https://sites.google.com/site/doingbayesiandataanalysis/">https://sites.google.com/site/doingbayesiandataanalysis/</a>.
</div>
<div id="ref-mcelreathStatisticalRethinkingBayesian2020" class="csl-entry">
McElreath, Richard. 2020. <em>Statistical Rethinking: A <span>Bayesian</span> Course with Examples in <span>R</span> and <span>Stan</span></em>. 2nd ed. <span>CRC</span> Texts in Statistical Science. <span>Boca Raton</span>: <span>Taylor and Francis, CRC Press</span>. <a href="https://xcelab.net/rm/statistical-rethinking/">https://xcelab.net/rm/statistical-rethinking/</a>.
</div>
<div id="ref-wickhamDataScienceImport2016" class="csl-entry">
Wickham, Hadley, Mine Çetinkaya-Rundel, and Garrett Grolemund. 2016. <em>R for <span>Data Science</span>: <span>Import</span>, <span>Tidy</span>, <span>Transform</span>, <span>Visualize</span>, and <span>Model Data</span></em>. <span>"O’Reilly Media, Inc."</span>. <a href="https://r4ds.hadley.nz/">https://r4ds.hadley.nz/</a>.
</div>
</div></section><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{vuorre2024,
  author = {Vuorre, Matti},
  title = {A Quantitative Methods Syllabus},
  date = {2024-01-19},
  url = {https://vuorre.com/posts/methods-syllabus/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-vuorre2024" class="csl-entry quarto-appendix-citeas">
Vuorre, Matti. 2024. <span>“A Quantitative Methods Syllabus.”</span>
January 19, 2024. <a href="https://vuorre.com/posts/methods-syllabus/">https://vuorre.com/posts/methods-syllabus/</a>.
</div></div></section></div> ]]></description>
  <category>research</category>
  <category>statistics</category>
  <guid>https://vuorre.com/posts/methods-syllabus/</guid>
  <pubDate>Thu, 18 Jan 2024 23:00:00 GMT</pubDate>
  <media:content url="https://vuorre.com/posts/methods-syllabus/images/edge2edge-media-uKlneQRwaxY-unsplash.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Yet another data request email</title>
  <dc:creator>Matti Vuorre</dc:creator>
  <link>https://vuorre.com/posts/yet-another-data-request-email/</link>
  <description><![CDATA[ 





<div class="callout callout-style-default callout-note no-icon callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>Latest update: I tried emailing some authors and tried submitting another enquiry through the system but never heard back from anyone. Sigh. I don’t have time for this shit.</p>
</div>
</div>
<p>In “Associations Between Infant Screen Use, Electroencephalography Markers, and Cognitive Outcomes” <span class="citation" data-cites="lawAssociationsInfantScreen2023">Law et al. (2023)</span> write that “Screen time at age 12 months contributed to multiple 9-year attention and executive functioning measures (<img src="https://latex.codecogs.com/png.latex?%5Ceta%5E2">, 0.03-0.16; Cohen d, 0.35-0.87)”. This is potentially huge news, for at least two reasons:</p>
<ol type="1">
<li><p>There isn’t very much literature on such longitudinal within-person associations between “screen time” <span class="citation" data-cites="k.kayeConceptualMethodologicalMayhem2020">(K. Kaye et al. 2020)</span> and psychosocial outcomes in a time frame spanning infancy to childhood. Studying this association is very important in trying to understand how digital technologies in extremely sensitive developmental periods might affect later life outcomes. So this study potentially provides some really important evidence on the effects of “screen time”.</p></li>
<li><p>The effects are <em>huge</em>. <img src="https://latex.codecogs.com/png.latex?%5Ceta%5E2"> is a metric assessing the proportion of variability in the outcome that is explained by the predictor. Here, the finding is that infants’ screen time can explain up to 16% of variability in cognitive functioning at age 9.</p></li>
</ol>
<p>Naturally, scientists studying the effects of digital technologies should be very interested in these findings. As the authors write (emphasis mine):</p>
<blockquote class="blockquote">
<p>In short, increased screen time in infancy is associated with impairments in cognitive processes critical for health, academic achievement, and future work success. However, the findings from this cohort study do not prove causation. Screen time likely represents a measurable contextual characteristic of a family or a proxy for the quality of parent-child interaction. <em>Replication of this study’s findings</em> and randomized clinical trials are warranted.</p>
</blockquote>
<p>As a first step, I wanted to see and reproduce the computations leading to those effect size estimates. Basic reproduction of analyses is often considered an essential first step in replicating a study. Then, I wanted to extend their analysis by examining the impact of potential measurement error in the infant screen time measure (such self- [or here, parent-] reports are known to be somewhat inaccurate <span class="citation" data-cites="parrySystematicReviewMetaanalysis2021">(Parry et al. 2021)</span>) on the associations.</p>
<p>I went ahead to the article’s website, and looked at Supplement 2. Data sharing statement. It states:</p>
<blockquote class="blockquote">
<p>Data available: No Explanation for why data not available: This cohort study requires ethics approval for each specific research question before data may be shared. The data used in this cohort are described in https://gustodatavault.sg/. The data will be made available to researchers who provide a methodologically sound proposal.</p>
</blockquote>
<p>That’s great. I understand that these data are potentially very sensitive, and the people curating these data are right in protecting their participants’ privacy. It is also great to see that the data will be shared with serious researchers. I have a clear and methodologically sound proposal for analysing these data:</p>
<blockquote class="blockquote">
<p>Importance: Law et al.&nbsp;(2023) report potentially very consequential results regarding associations between infant screen time and later psychosocial functioning. It is imperative, then, to reproduce the analyses and examine their underlying assumptions. Objective: Reproduce the analyses in Law et al.&nbsp;(2023) and examine the impact of assuming no measurement error in the screen time measure at infancy on resulting associations between screen time and psychological functioning at age 9. Methodology: Statistical analyses as reported in Law et al.&nbsp;(2023), with a sensitivity analysis with varying levels of measurement error in age 12 months “screen time”. Proposed outcome: A pre-print deposited on https://psyarxiv.com/ reporting the results and implications of a. the reproduction analysis and b. the sensitivity analysis.</p>
</blockquote>
<p>I clicked through to the data website (<a href="https://gustodatavault.sg/about/request-for-data" class="uri">https://gustodatavault.sg/about/request-for-data</a>), and created an account. I am now waiting to have my account approved so that I can proceed with submitting my data request. Stay tuned!</p>




<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-bibliography"><h2 class="anchored quarto-appendix-heading">References</h2><div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="0">
<div id="ref-k.kayeConceptualMethodologicalMayhem2020" class="csl-entry">
K. Kaye, Linda, Amy Orben, David A. Ellis, Simon C. Hunter, and Stephen Houghton. 2020. <span>“The <span>Conceptual</span> and <span>Methodological Mayhem</span> of <span>‘<span>Screen Time</span>’</span>.”</span> <em>International Journal of Environmental Research and Public Health</em> 17 (10, 10): 3661. <a href="https://doi.org/10.3390/ijerph17103661">https://doi.org/10.3390/ijerph17103661</a>.
</div>
<div id="ref-lawAssociationsInfantScreen2023" class="csl-entry">
Law, Evelyn C., Meredith X. Han, Zhuoyuan Lai, Shuping Lim, Zi Yan Ong, Valerie Ng, Laurel J. Gabard-Durnam, et al. 2023. <span>“Associations <span>Between Infant Screen Use</span>, <span>Electroencephalography Markers</span>, and <span>Cognitive Outcomes</span>.”</span> <em>JAMA Pediatrics</em> 177 (3): 311–18. <a href="https://doi.org/10.1001/jamapediatrics.2022.5674">https://doi.org/10.1001/jamapediatrics.2022.5674</a>.
</div>
<div id="ref-parrySystematicReviewMetaanalysis2021" class="csl-entry">
Parry, Douglas A., Brittany I. Davidson, Craig J. R. Sewall, Jacob T. Fisher, Hannah Mieczkowski, and Daniel S. Quintana. 2021. <span>“A Systematic Review and Meta-Analysis of Discrepancies Between Logged and Self-Reported Digital Media Use.”</span> <em>Nature Human Behaviour</em>, May, 1–13. <a href="https://doi.org/10.1038/s41562-021-01117-5">https://doi.org/10.1038/s41562-021-01117-5</a>.
</div>
</div></section><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{vuorre2023,
  author = {Vuorre, Matti},
  title = {Yet Another Data Request Email},
  date = {2023-03-24},
  url = {https://vuorre.com/posts/yet-another-data-request-email/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-vuorre2023" class="csl-entry quarto-appendix-citeas">
Vuorre, Matti. 2023. <span>“Yet Another Data Request Email.”</span>
March 24, 2023. <a href="https://vuorre.com/posts/yet-another-data-request-email/">https://vuorre.com/posts/yet-another-data-request-email/</a>.
</div></div></section></div> ]]></description>
  <category>research</category>
  <guid>https://vuorre.com/posts/yet-another-data-request-email/</guid>
  <pubDate>Thu, 23 Mar 2023 23:00:00 GMT</pubDate>
  <media:content url="https://vuorre.com/posts/yet-another-data-request-email/images/orben-przybylski-2019-fig3.png" medium="image" type="image/png" height="113" width="144"/>
</item>
<item>
  <title>Latent mean centering with brms</title>
  <dc:creator>Matti Vuorre</dc:creator>
  <link>https://vuorre.com/posts/latent-mean-centering/</link>
  <description><![CDATA[ 





<div class="cell">
<details class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Packages</span></span>
<span id="cb1-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(knitr)</span>
<span id="cb1-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(brms)</span>
<span id="cb1-4"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(ggthemes)</span>
<span id="cb1-5"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(scales)</span>
<span id="cb1-6"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(posterior)</span>
<span id="cb1-7"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(tidyverse)</span>
<span id="cb1-8"></span>
<span id="cb1-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Plotting theme</span></span>
<span id="cb1-10"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme_set</span>(</span>
<span id="cb1-11">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme_few</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb1-12">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme</span>(</span>
<span id="cb1-13">      <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">axis.title.y =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">element_blank</span>(),</span>
<span id="cb1-14">      <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">legend.title =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">element_blank</span>(),</span>
<span id="cb1-15">      <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">panel.grid.major =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">element_line</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">linetype =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dotted"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">linewidth =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>),</span>
<span id="cb1-16">      <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">legend.position =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"bottom"</span>,</span>
<span id="cb1-17">      <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">legend.justification =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"left"</span></span>
<span id="cb1-18">    )</span>
<span id="cb1-19">)</span>
<span id="cb1-20"></span>
<span id="cb1-21"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Download and uncompress McNeish and Hamaker materials if not yet done</span></span>
<span id="cb1-22"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dir.create</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"cache"</span>)</span>
<span id="cb1-23">path <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"materials/materials.zip"</span></span>
<span id="cb1-24"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">file.exists</span>(path)) {</span>
<span id="cb1-25">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dir.create</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"materials"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">showWarnings =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span>)</span>
<span id="cb1-26">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">download.file</span>(</span>
<span id="cb1-27">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://files.osf.io/v1/resources/wuprx/providers/osfstorage/5bfc839601593f0016774697/?zip="</span>,</span>
<span id="cb1-28">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">destfile =</span> path</span>
<span id="cb1-29">  )</span>
<span id="cb1-30">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">unzip</span>(path, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">exdir =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"materials"</span>)</span>
<span id="cb1-31">}</span></code></pre></div></div>
</details>
</div>
<section id="introduction" class="level2">
<h2 class="anchored" data-anchor-id="introduction">Introduction</h2>
<p>Within-cluster centering, or <em>person-mean centering</em> (psychologists’ clusters are typically persons), is an easy data processing step that allows separating within-person from between-person associations. For example, consider the example data of 100 people’s ratings of urge to smoke and depression, collected over 50 days with one response per day <span class="citation" data-cites="mcneishPrimerTwolevelDynamic2020">(McNeish and Hamaker 2020)</span> <sup>1</sup>, shown in Table&nbsp;1 and Figure&nbsp;1.</p>
<div class="cell">
<details class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb2-1">dat <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">read_csv</span>(</span>
<span id="cb2-2">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"materials/Data/Two-Level Data.csv"</span>,</span>
<span id="cb2-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">col_names =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"urge"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dep"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"js"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"hs"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"person"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"time"</span>)</span>
<span id="cb2-4">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>hs, <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>js) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">relocate</span>(person, time, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(</span>
<span id="cb2-8">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">person =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">factor</span>(person),</span>
<span id="cb2-9">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">time =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as.integer</span>(time)</span>
<span id="cb2-10">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-11">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(</span>
<span id="cb2-12">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">u_lag =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">lag</span>(urge),</span>
<span id="cb2-13">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dep_lag =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">lag</span>(dep),</span>
<span id="cb2-14">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.by =</span> person</span>
<span id="cb2-15">  )</span></code></pre></div></div>
</details>
</div>
<div class="cell">
<div id="tbl-data" class="cell quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-tbl figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-tbl" id="tbl-data-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Table&nbsp;1: Example longitudinal data (McNeish &amp; Hamaker, 2020); first three rows from two random participants.
</figcaption>
<div aria-describedby="tbl-data-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell-output-display">
<table class="do-not-create-environment cell caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">person</th>
<th style="text-align: right;">time</th>
<th style="text-align: right;">urge</th>
<th style="text-align: right;">dep</th>
<th style="text-align: right;">u_lag</th>
<th style="text-align: right;">dep_lag</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">1</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">0.34</td>
<td style="text-align: right;">0.43</td>
<td style="text-align: right;">NA</td>
<td style="text-align: right;">NA</td>
</tr>
<tr class="even">
<td style="text-align: left;">1</td>
<td style="text-align: right;">2</td>
<td style="text-align: right;">-0.48</td>
<td style="text-align: right;">-0.68</td>
<td style="text-align: right;">0.34</td>
<td style="text-align: right;">0.43</td>
</tr>
<tr class="odd">
<td style="text-align: left;">1</td>
<td style="text-align: right;">3</td>
<td style="text-align: right;">-4.44</td>
<td style="text-align: right;">-1.49</td>
<td style="text-align: right;">-0.48</td>
<td style="text-align: right;">-0.68</td>
</tr>
<tr class="even">
<td style="text-align: left;">2</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">1.65</td>
<td style="text-align: right;">0.68</td>
<td style="text-align: right;">NA</td>
<td style="text-align: right;">NA</td>
</tr>
<tr class="odd">
<td style="text-align: left;">2</td>
<td style="text-align: right;">2</td>
<td style="text-align: right;">0.31</td>
<td style="text-align: right;">1.49</td>
<td style="text-align: right;">1.65</td>
<td style="text-align: right;">0.68</td>
</tr>
<tr class="even">
<td style="text-align: left;">2</td>
<td style="text-align: right;">3</td>
<td style="text-align: right;">0.46</td>
<td style="text-align: right;">0.03</td>
<td style="text-align: right;">0.31</td>
<td style="text-align: right;">1.49</td>
</tr>
</tbody>
</table>
</div>
</div>
</figure>
</div>
</div>
<p>Table&nbsp;1 shows the original data values. Those could then be transformed to person-means and person-mean centered deviations with simple data processing. However, the person-mean is an unknown quantity, and centering on the observed value rather than an estimate of the true “latent” quantity can be problematic. Specifically, observed mean centering leads to Nickell’s (negative bias in autoregressive effects) and Lüdtke’s (bias in other time-varying effects) biases <span class="citation" data-cites="mcneishPrimerTwolevelDynamic2020">(McNeish and Hamaker 2020, 617–18)</span>.</p>
<div class="cell">
<details class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb3-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">set.seed</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">999</span>)</span>
<span id="cb3-2">pids <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">factor</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sample</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>))</span>
<span id="cb3-3"></span>
<span id="cb3-4">dat <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(person <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%in%</span> pids) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_longer</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(urge, dep)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rename</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Time =</span> time) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">factor</span>(name, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">labels =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Depression"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Urge"</span>))) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(Time, value, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">col =</span> name)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb3-10">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_line</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">linewidth =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb3-11">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">facet_wrap</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"person"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">nrow =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">labeller =</span> label_both)</span></code></pre></div></div>
</details>
<div class="cell-output-display">
<div id="fig-data" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-data-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/latent-mean-centering/index_files/figure-html/fig-data-1.png" class="img-fluid figure-img" width="672">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-data-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;1: Four persons’ depression and urge to smoke over time
</figcaption>
</figure>
</div>
</div>
</div>
<p>So, what to do? McNeish and Hamaker <span class="citation" data-cites="mcneishPrimerTwolevelDynamic2020">(2020)</span> and others discuss latent mean centering, which accounts for uncertainty in the person-means appropriately, and thus debiases the estimated coefficients. Latent mean centering is done inside the model, and means treating the means as estimated parameters. However, I have only been able to find examples that do this latent mean centering in MPlus <span class="citation" data-cites="mcneishPrimerTwolevelDynamic2020">(McNeish and Hamaker 2020)</span> and Stan (<a href="https://experienced-sampler.netlify.app/post/stan-hierarchical-ar/" class="uri">https://experienced-sampler.netlify.app/post/stan-hierarchical-ar/</a>). My goal here is to show how latent mean centering can be done in the <a href="https://mc-stan.org">Stan</a> front-end R package <a href="https://paul-buerkner.github.io/brms/">brms</a>.</p>
</section>
<section id="univariate-latent-means-model" class="level2">
<h2 class="anchored" data-anchor-id="univariate-latent-means-model">Univariate latent means model</h2>
<p>We begin with a univariate model of the urge to smoke. This model examines the degree of autocorrelation in the urge to smoke and how it varies between people. For individual <em>i</em> in 1…I=100 and time point <em>t</em> in 1…T=50, we model <code>urge</code> (U) as normally distributed. We model the mean on person-specific intercepts <img src="https://latex.codecogs.com/png.latex?%5Calpha_i"> and slopes <img src="https://latex.codecogs.com/png.latex?%5Cphi_i"> of that person’s within-person centered <code>urge</code> at a previous time point (<img src="https://latex.codecogs.com/png.latex?U%5Ec_%7Bit-1%7D">). I model person-specific deviations as multivariate normal but do not model correlations between the intercepts and slopes for consistency with <span class="citation" data-cites="mcneishPrimerTwolevelDynamic2020">(McNeish and Hamaker 2020)</span>.</p>
<p><span id="eq-1"><img src="https://latex.codecogs.com/png.latex?%0A%5Cbegin%7Balign%7D%0AU_%7Bit%7D%20&amp;%5Csim%20N(%5Calpha_i%20+%20%5Cphi_i%20U%5Ec_%7Bit-1%7D,%20%5Csigma%5E2),%20%5C%5C%0AU%5E%7Bc%7D_%7Bit-1%7D%20&amp;=%20U%5E%7B%5Ctext%7Braw%7D%7D_%7Bit-1%7D%20-%20%5Calpha_i,%20%5C%5C%0A%5Calpha_i%20&amp;=%20%5Cgamma_%7B0%7D%20+%20u_%7B0i%7D,%20%5C%5C%0A%5Cphi_i%20&amp;=%20%5Cgamma_%7B1%7D%20+%20u_%7B1i%7D,%20%5C%5C%0A%5Cbegin%7Bbmatrix%7D%0A%20%20u_%7B0i%7D%20%5C%5C%20u_%7B1i%7D%0A%5Cend%7Bbmatrix%7D%20&amp;%5Csim%20MVN%5Cleft(%0A%20%20%5Cbegin%7Bbmatrix%7D%0A%20%20%20%200%20%5C%5C%200%0A%20%20%5Cend%7Bbmatrix%7D,%0A%20%20%5Cbegin%7Bpmatrix%7D%0A%20%20%5Ctau_%5Calpha%20%5C%20&amp;%20%5C%5C%200%20%5C%20&amp;%5Ctau_%5Cphi%0A%20%20%5Cend%7Bpmatrix%7D%0A%5Cright).%0A%5Cend%7Balign%7D%0A%5Ctag%7B1%7D"></span></p>
<p>Let us pay some attention to the issue of within-person centering in Equation&nbsp;1. Instead of decomposing urge to smoke into its within- and between-person components before fitting the model, we use “latent mean centering”. What this means is that we estimate the person means (<img src="https://latex.codecogs.com/png.latex?%5Calpha">) along with other model parameters, and subtract those means from the observed values (line 2 in above). I refer to the latent person-mean centered lagged urge to smoke as <img src="https://latex.codecogs.com/png.latex?U%5Ec_%7Bit-1%7D">.</p>
<p>I use the R package brms to estimate this model. The following code chunk shows how to specify this model inside brms’ <code>bf()</code> (“brmsformula”) function. In the first line, we specify a regression equation for <code>urge</code>. Everything on the right-hand side of this formula (to the right of the tilde) is treated as a regression coefficient to be estimated from data unless it is the exact name of a variable in the data. Thus we will be estimating an <code>alpha</code> (intercept) and a <code>phi</code> (the autoregressive coefficient).</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb4-1">model <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bf</span>(</span>
<span id="cb4-2">  urge <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> alpha <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> phi <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (u_lag <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> alpha),</span>
<span id="cb4-3">  alpha <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> phi <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> person),</span>
<span id="cb4-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">nl =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span></span>
<span id="cb4-5">)</span></code></pre></div></div>
</details>
</div>
<p>One unusual part in this syntax is <code>(u_lag - alpha)</code>. It just subtracts <code>alpha</code> from each lagged urge value in creating the predictor for <code>phi</code>. That is “latent mean centering”. This first line can be considered the “level 1” equation or rather the <em>nonlinear</em> part of the model.</p>
<p>The second line then specifies the “level 2” equation, or the linear equations to predict the parameters in the above (potentially) nonlinear level 1 model. Both regression parameters are modelled on a population level average (the gamma in Equation&nbsp;1) and person-specific deviations from it.</p>
<p>The fourth line specifying <code>nl = TRUE</code> is critical, because it allows us to specifically name parameters inside <code>bf()</code>, and thereby to e.g.&nbsp;construct the latent mean centered variable on the first row. We could also indicate the distribution that we assume for the data. But in this work we model everything as gaussian, which is the software default and thus doesn’t need to be separately indicated. We then sample from the model. Everything from here on is standard operating procedure.</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb5-1">fit <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">brm</span>(</span>
<span id="cb5-2">  model,</span>
<span id="cb5-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> dat,</span>
<span id="cb5-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">file =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"cache/brm-example-univariate"</span></span>
<span id="cb5-5">)</span></code></pre></div></div>
</details>
</div>
<p>The object <code>fit</code> now contains the estimated model (the data, posterior samples, and lots of brms-specific information). We can call <code>summary(fit)</code> to see a default summary of the model.</p>
<div class="cell">
<details class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb6-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summary</span>(fit)</span></code></pre></div></div>
</details>
<div class="cell-output cell-output-stdout">
<pre><code> Family: gaussian 
  Links: mu = identity 
Formula: urge ~ alpha + phi * (u_lag - alpha) 
         alpha ~ 1 + (1 | person)
         phi ~ 1 + (1 | person)
   Data: dat (Number of observations: 4900) 
  Draws: 4 chains, each with iter = 2000; warmup = 1000; thin = 1;
         total post-warmup draws = 4000

Multilevel Hyperparameters:
~person (Number of levels: 100) 
                    Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
sd(alpha_Intercept)     0.78      0.07     0.67     0.92 1.00      906     1707
sd(phi_Intercept)       0.15      0.02     0.11     0.19 1.00     2354     2767

Regression Coefficients:
                Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
alpha_Intercept    -0.01      0.08    -0.18     0.15 1.00      714     1207
phi_Intercept       0.20      0.02     0.16     0.25 1.00     2424     2654

Further Distributional Parameters:
      Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
sigma     1.57      0.02     1.54     1.60 1.00     6653     2873

Draws were sampled using sample(hmc). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).</code></pre>
</div>
</div>
<p>The first few rows above print information about the model (the formulas, data, and number of posterior samples). Then, “Multilevel Hyperparameters” are standard deviations (and correlations, if estimated) of the parameters that we allowed to vary across individuals (as indicated by <code>~person</code>). For each of those parameters, one row indicates its posterior summary statistics; “Estimate” is the posterior mean, “Est.Error” is the posterior standard deviation, “l-” and “u-95% CI” are the lower and upper bounds of the 95% credibility interval (so the 2.5 and 97.5 percentiles of the posterior samples). Then, Rhat is the convergence metric which should be smaller than 1.05 (optimally 1.00) to indicate that the estimation algorithm has converged. “Bulk_” and “Tail_ESS” indicate the effective sample sizes of the posterior draws, and should be pretty large.</p>
<p>The “Regression Coefficients” indicate the same information but for the means of the person-specific parameters’ distributions; or the “fixed effects”. For the average person, there is a positive autocorrelation in these data. Finally, the “Further Distributional Parameters” indicate parameters that are specific to the outcome distribution. We used the default gaussian distribution, and thus get an estimated residual standard deviation.</p>
<p>Going forward we will create a small function to print out model summaries. It will take samples of the population level, group-level, and family-specific parameters, and return their 50th (median), 2.5th, and 97.5th quantiles.</p>
<div class="cell">
<details class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb8-1">sm <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(x) {</span>
<span id="cb8-2">  x <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb8-3">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_draws_df</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">variable =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"b_"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sd_"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sigma"</span>), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">regex =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb8-4">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise_draws</span>(</span>
<span id="cb8-5">      <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">quantile2</span>(.x, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(.<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">025</span>, .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">975</span>))</span>
<span id="cb8-6">    ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb8-7">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">variable =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_remove_all</span>(variable, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"_Intercept"</span>))</span>
<span id="cb8-8">}</span></code></pre></div></div>
</details>
</div>
<p>We show the results in Table&nbsp;2.</p>
<div class="cell">
<details class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb9-1">fit <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sm</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span></code></pre></div></div>
</details>
<div id="tbl-model-1" class="cell quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-tbl figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-tbl" id="tbl-model-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Table&nbsp;2: Summaries of main parameters from the example univariate model.
</figcaption>
<div aria-describedby="tbl-model-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell-output-display">
<table class="do-not-create-environment cell caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">variable</th>
<th style="text-align: right;">q50</th>
<th style="text-align: right;">q2.5</th>
<th style="text-align: right;">q97.5</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">b_alpha</td>
<td style="text-align: right;">-0.01</td>
<td style="text-align: right;">-0.18</td>
<td style="text-align: right;">0.15</td>
</tr>
<tr class="even">
<td style="text-align: left;">b_phi</td>
<td style="text-align: right;">0.21</td>
<td style="text-align: right;">0.16</td>
<td style="text-align: right;">0.25</td>
</tr>
<tr class="odd">
<td style="text-align: left;">sd_person__alpha</td>
<td style="text-align: right;">0.78</td>
<td style="text-align: right;">0.67</td>
<td style="text-align: right;">0.92</td>
</tr>
<tr class="even">
<td style="text-align: left;">sd_person__phi</td>
<td style="text-align: right;">0.15</td>
<td style="text-align: right;">0.11</td>
<td style="text-align: right;">0.19</td>
</tr>
<tr class="odd">
<td style="text-align: left;">sigma</td>
<td style="text-align: right;">1.57</td>
<td style="text-align: right;">1.54</td>
<td style="text-align: right;">1.60</td>
</tr>
</tbody>
</table>
</div>
</div>
</figure>
</div>
</div>
</section>
<section id="multilevel-ar1-model" class="level2">
<h2 class="anchored" data-anchor-id="multilevel-ar1-model">Multilevel AR(1) Model</h2>
<p>We then replicate the two-level AR(1) model in <span class="citation" data-cites="mcneishPrimerTwolevelDynamic2020">McNeish and Hamaker (2020)</span> (equations 4a-c) that predicts urge from a time-lagged urge and depression. The model is</p>
<p><span id="eq-2"><img src="https://latex.codecogs.com/png.latex?%0A%5Cbegin%7Balign%7D%0AU_%7Bit%7D%20&amp;%5Csim%20N(%5Calpha_i%20+%20%5Cphi_i%20U%5Ec_%7Bit-1%7D%20+%20%5Cbeta_i%20D%5Ec_%7Bit%7D,%20%5Csigma%5E2),%20%5C%5C%0AU%5E%7Bc%7D_%7Bit%7D%20&amp;=%20U%5E%7B%5Ctext%7Braw%7D%7D_%7Bit%7D%20-%20%5Calpha%5EU_i,%20%5C%5C%0AD%5E%7Bc%7D_%7Bit%7D%20&amp;=%20D%5E%7B%5Ctext%7Braw%7D%7D_%7Bit%7D%20-%20%5Calpha%5ED_i,%20%5C%5C%0A%5Calpha%5EU_i%20&amp;=%20%5Cgamma_%7B0%7D%20+%20u_%7B0i%7D,%20%5C%5C%0A%5Calpha%5ED_i%20&amp;=%20%5Cgamma_%7B1%7D%20+%20u_%7B1i%7D,%20%5C%5C%0A%5Cphi_i%20&amp;=%20%5Cgamma_%7B2%7D%20+%20u_%7B2i%7D,%20%5C%5C%0A%5Cbeta_i%20&amp;=%20%5Cgamma_%7B3%7D%20+%20u_%7B3i%7D,%20%5C%5C%0A%5Cbegin%7Bbmatrix%7D%0A%20%20u_%7B0i%7D%20%5C%5C%20u_%7B1i%7D%20%5C%5C%20u_%7B2i%7D%20%5C%5C%20u_%7B3i%7D%0A%5Cend%7Bbmatrix%7D%20&amp;%5Csim%20MVN%5Cleft(%0A%20%20%5Cbegin%7Bbmatrix%7D%0A%20%20%20%200%20%5C%5C%200%20%5C%5C%200%20%5C%5C%200%0A%20%20%5Cend%7Bbmatrix%7D,%0A%20%20%5Cbegin%7Bpmatrix%7D%0A%20%20%20%20%5Ctau_%7B%5Calpha%5EU%7D%20%5C%20&amp;%20%5C%20&amp;%20&amp;%20%5C%5C%0A%20%20%20%200%20%5C%20&amp;%5Ctau_%7B%5Calpha%5ED%7D%20%5C%20&amp;%20%5C%20&amp;%20%5C%5C%0A%20%20%20%200%20%5C%20&amp;0%20%5C%20&amp;%5Ctau_%5Cphi%20%5C%20&amp;%20%5C%5C%0A%20%20%20%200%20%5C%20&amp;0%20%5C%20&amp;0%20%5C%20&amp;%5Ctau_%5Cbeta%0A%20%20%5Cend%7Bpmatrix%7D%0A%5Cright)%0A%5Cend%7Balign%7D%0A%5Ctag%7B2%7D"></span></p>
<p>We then see from Equation&nbsp;2 that we need to refer to different outcomes’ parameters across model formulas. That is, when predicting the urge to smoke, we need a way to refer to the (latent) mean of depression so that we can appropriately center the depression predictor. Currently brms does not support sharing parameters across formulas for different outcomes, but we can overcome this limitation with a small data wrangling trick</p>
<p>That is, we “stack” our data into the long format with respect to the two different outcomes, urge to smoke and depression. Then, on each row we have all variables from that measurement occasion, in addition to new ones that indicate the value of the outcome, and which outcome it refers to (Table&nbsp;3).</p>
<div class="cell">
<details class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb10-1">dat <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> dat <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_longer</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(urge, dep), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_to =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"outcome"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_to =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"y"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(</span>
<span id="cb10-4">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">i_urge =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(outcome <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"urge"</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>),</span>
<span id="cb10-5">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">i_dep =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(outcome <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dep"</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span>
<span id="cb10-6">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-7">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Include predictors from each row</span></span>
<span id="cb10-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">left_join</span>(dat)</span>
<span id="cb10-9"></span>
<span id="cb10-10">dat <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-11">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-12">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span></code></pre></div></div>
</details>
<div id="tbl-data-2" class="cell quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-tbl figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-tbl" id="tbl-data-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Table&nbsp;3: Rearranged data for multivariate models.
</figcaption>
<div aria-describedby="tbl-data-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell-output-display">
<table class="do-not-create-environment cell caption-top table table-sm table-striped small">
<colgroup>
<col style="width: 10%">
<col style="width: 7%">
<col style="width: 9%">
<col style="width: 12%">
<col style="width: 12%">
<col style="width: 9%">
<col style="width: 10%">
<col style="width: 9%">
<col style="width: 9%">
<col style="width: 9%">
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">person</th>
<th style="text-align: right;">time</th>
<th style="text-align: right;">u_lag</th>
<th style="text-align: right;">dep_lag</th>
<th style="text-align: left;">outcome</th>
<th style="text-align: right;">y</th>
<th style="text-align: right;">i_urge</th>
<th style="text-align: right;">i_dep</th>
<th style="text-align: right;">urge</th>
<th style="text-align: right;">dep</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">1</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">NA</td>
<td style="text-align: right;">NA</td>
<td style="text-align: left;">urge</td>
<td style="text-align: right;">0.34</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">0.34</td>
<td style="text-align: right;">0.43</td>
</tr>
<tr class="even">
<td style="text-align: left;">1</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">NA</td>
<td style="text-align: right;">NA</td>
<td style="text-align: left;">dep</td>
<td style="text-align: right;">0.43</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">0.34</td>
<td style="text-align: right;">0.43</td>
</tr>
<tr class="odd">
<td style="text-align: left;">1</td>
<td style="text-align: right;">2</td>
<td style="text-align: right;">0.34</td>
<td style="text-align: right;">0.43</td>
<td style="text-align: left;">urge</td>
<td style="text-align: right;">-0.48</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">-0.48</td>
<td style="text-align: right;">-0.68</td>
</tr>
<tr class="even">
<td style="text-align: left;">1</td>
<td style="text-align: right;">2</td>
<td style="text-align: right;">0.34</td>
<td style="text-align: right;">0.43</td>
<td style="text-align: left;">dep</td>
<td style="text-align: right;">-0.68</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">-0.48</td>
<td style="text-align: right;">-0.68</td>
</tr>
<tr class="odd">
<td style="text-align: left;">1</td>
<td style="text-align: right;">3</td>
<td style="text-align: right;">-0.48</td>
<td style="text-align: right;">-0.68</td>
<td style="text-align: left;">urge</td>
<td style="text-align: right;">-4.44</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">-4.44</td>
<td style="text-align: right;">-1.49</td>
</tr>
<tr class="even">
<td style="text-align: left;">1</td>
<td style="text-align: right;">3</td>
<td style="text-align: right;">-0.48</td>
<td style="text-align: right;">-0.68</td>
<td style="text-align: left;">dep</td>
<td style="text-align: right;">-1.49</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">-4.44</td>
<td style="text-align: right;">-1.49</td>
</tr>
</tbody>
</table>
</div>
</div>
</figure>
</div>
</div>
<p>Given these data, we then reparameterize Equation&nbsp;2 to also model depression in an otherwise identical model (Equation&nbsp;3).</p>
<p><span id="eq-3"><img src="https://latex.codecogs.com/png.latex?%0A%5Cbegin%7Balign%7D%0AY_%7Bit%7D%20&amp;%5Csim%20N(%5Cmu,%20%5Csigma%5E2)%20%5C%5C%0A%5Cmu%20&amp;=%20I_%7B%5Ctext%7Burge%7D%7D(%5Calpha_%7B1i%7D%20+%20%5Cphi_i%20U%5Ec_%7Bit-1%7D%20+%20%5Cbeta_i%20D%5Ec_%7Bit%7D)%20+%20I_%7B%5Ctext%7Bdep%7D%7D%5Calpha_%7B2i%7D%20%5C%5C%0A%5Csigma%20&amp;=%20%5Ctext%7Bexp%7D(I_%7B%5Ctext%7Burge%7D%7D%5Csigma_1%20+%20I_%7B%5Ctext%7Bdep%7D%7D%5Csigma_2)%20%5C%5C%0AU%5E%7Bc%7D_%7Bit%7D%20&amp;=%20U%5E%7B%5Ctext%7Braw%7D%7D_%7Bit%7D%20-%20%5Calpha_%7B1i%7D,%20%5C%5C%0AD%5E%7Bc%7D_%7Bit%7D%20&amp;=%20D%5E%7B%5Ctext%7Braw%7D%7D_%7Bit%7D%20-%20%5Calpha_%7B2i%7D,%20%5C%5C%0A%5Calpha_%7B1i%7D%20&amp;=%20%5Cgamma_%7B0%7D%20+%20u_%7B0i%7D,%20%5C%5C%0A%5Calpha_%7B2i%7D%20&amp;=%20%5Cgamma_%7B1%7D%20+%20u_%7B1i%7D,%20%5C%5C%0A%5Cphi_i%20&amp;=%20%5Cgamma_%7B2%7D%20+%20u_%7B2i%7D,%20%5C%5C%0A%5Cbeta_i%20&amp;=%20%5Cgamma_%7B3%7D%20+%20u_%7B3i%7D,%20%5C%5C%0A%5Cbegin%7Bbmatrix%7D%0A%20%20u_%7B0i%7D%20%5C%5C%20u_%7B1i%7D%20%5C%5C%20u_%7B2i%7D%20%5C%5C%20u_%7B3i%7D%0A%5Cend%7Bbmatrix%7D%20&amp;%5Csim%20MVN%5Cleft(%0A%20%20%5Cbegin%7Bbmatrix%7D%0A%20%20%20%200%20%5C%5C%200%20%5C%5C%200%20%5C%5C%200%0A%20%20%5Cend%7Bbmatrix%7D,%0A%20%20%5Cbegin%7Bpmatrix%7D%0A%20%20%20%20%5Ctau_%7B%5Calpha1%7D%20%5C%20&amp;%20%5C%20&amp;%20&amp;%20%5C%5C%0A%20%20%20%200%20%5C%20&amp;%5Ctau_%7B%5Calpha2%7D%20%5C%20&amp;%20%5C%20&amp;%20%5C%5C%0A%20%20%20%200%20%5C%20&amp;0%20%5C%20&amp;%5Ctau_%5Cphi%20%5C%20&amp;%20%5C%5C%0A%20%20%20%200%20%5C%20&amp;0%20%5C%20&amp;0%20%5C%20&amp;%5Ctau_%5Cbeta%0A%20%20%5Cend%7Bpmatrix%7D%0A%5Cright)%0A%5Cend%7Balign%7D%0A%5Ctag%7B3%7D"></span></p>
<p>That is, I model <code>y</code> that is either <code>urge</code> or <code>dep</code> as indicated by <code>i_urge</code> and <code>i_dep</code> respectively. So, below <code>alpha1</code>, <code>phi</code>, and <code>beta</code> to apply to <code>urge</code>, but <code>alpha2</code> to <code>dep</code>.</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb11-1">bform <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bf</span>(</span>
<span id="cb11-2">  y <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span></span>
<span id="cb11-3">    i_urge <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span></span>
<span id="cb11-4">      (alpha1 <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> phi <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (u_lag <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> alpha1) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> beta <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (dep <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> alpha2)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb11-5">      i_dep <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> alpha2,</span>
<span id="cb11-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">nlf</span>(sigma <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> i_urge <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> sigma1 <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> i_dep <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> sigma2),</span>
<span id="cb11-7">  alpha1 <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> phi <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> beta <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> alpha2 <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> person),</span>
<span id="cb11-8">  sigma1 <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> sigma2 <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,</span>
<span id="cb11-9">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">nl =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span></span>
<span id="cb11-10">)</span></code></pre></div></div>
</details>
</div>
<p>Notice that essentially there are two models of <code>y</code> depending on the values of <code>i_urge</code> and <code>i_dep</code>. Critically, this also needs to extend to different models of the residual standard deviations. That is accomplished inside <code>nlf()</code>, where I model <code>sigma</code> on the two indicators. By default, sigmas are modelled through the log-link function, and notice that I only include a global intercept for each <code>sigma1</code> and <code>sigma2</code>; that is they are not further modelled on covariates. This is not pretty, but as we will see it works.</p>
<p>I then sample from the model.</p>
<div class="cell">
<details class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb12-1">fit <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">brm</span>(</span>
<span id="cb12-2">  bform,</span>
<span id="cb12-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> dat,</span>
<span id="cb12-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">control =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">list</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">adapt_delta =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.95</span>),</span>
<span id="cb12-5">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">file =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"cache/brm-example-4"</span></span>
<span id="cb12-6">)</span></code></pre></div></div>
</details>
</div>
<p>And then compare the model summary to <span class="citation" data-cites="mcneishPrimerTwolevelDynamic2020">McNeish and Hamaker (2020)</span>. We can see the estimates match to within differences in priors and MCSE (Table&nbsp;4). Note in the code below I transform standard deviations by first exponentiating draws of residual standard deviations, and then square to put them on the variance scale as in <span class="citation" data-cites="mcneishPrimerTwolevelDynamic2020">McNeish and Hamaker (2020)</span>.</p>
<div class="cell">
<details class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb13-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_draws_df</span>(fit, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">variable =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"b_"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sd_"</span>), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">regex =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(</span>
<span id="cb13-3">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">across</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">starts_with</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sd_"</span>), <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> .<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">^</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>),</span>
<span id="cb13-4">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">across</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">starts_with</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"b_sigma"</span>), <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">exp</span>(.)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">^</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb13-5">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise_draws</span>(</span>
<span id="cb13-7">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">brms =</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">quantile2</span>(., <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">probs =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(.<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">025</span>, .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">975</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-8">      <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">number</span>(.<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">01</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-9">      <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_glue_data</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"{q50} [{q2.5}, {q97.5}]"</span>)</span>
<span id="cb13-10">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-11">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(</span>
<span id="cb13-12">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">variable =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_replace</span>(variable, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sd_person__"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"var_"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-13">      <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_remove_all</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"_Intercept"</span>),</span>
<span id="cb13-14">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">M&amp;H (2020)</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(</span>
<span id="cb13-15">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"-0.01 [-0.18, 0.16]"</span>,</span>
<span id="cb13-16">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">" 0.21 [0.17, 0.24]"</span>,</span>
<span id="cb13-17">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">" 0.80 [0.61, 0.95]"</span>,</span>
<span id="cb13-18">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">" 0.01 [-0.02, 0.04]"</span>,</span>
<span id="cb13-19">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">" 1.14 [1.09, 1.19]"</span>,</span>
<span id="cb13-20">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span>,</span>
<span id="cb13-21">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">" 0.60 [0.44, 0.83]"</span>,</span>
<span id="cb13-22">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">" 0.02 [0.01, 0.03]"</span>,</span>
<span id="cb13-23">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">" 0.79 [0.61, 0.95]"</span>,</span>
<span id="cb13-24">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">" 0.01 [0.00, 0.01]"</span></span>
<span id="cb13-25">    )</span>
<span id="cb13-26">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-27">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span></code></pre></div></div>
</details>
<div id="tbl-ml" class="cell quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-tbl figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-tbl" id="tbl-ml-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Table&nbsp;4: Multilevel AR(1) model results.
</figcaption>
<div aria-describedby="tbl-ml-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell-output-display">
<table class="do-not-create-environment cell caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">variable</th>
<th style="text-align: left;">brms</th>
<th style="text-align: left;">M&amp;H (2020)</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">b_alpha1</td>
<td style="text-align: left;">-0.01 [-0.16, 0.16]</td>
<td style="text-align: left;">-0.01 [-0.18, 0.16]</td>
</tr>
<tr class="even">
<td style="text-align: left;">b_phi</td>
<td style="text-align: left;">0.21 [0.18, 0.25]</td>
<td style="text-align: left;">0.21 [0.17, 0.24]</td>
</tr>
<tr class="odd">
<td style="text-align: left;">b_beta</td>
<td style="text-align: left;">0.79 [0.62, 0.96]</td>
<td style="text-align: left;">0.80 [0.61, 0.95]</td>
</tr>
<tr class="even">
<td style="text-align: left;">b_alpha2</td>
<td style="text-align: left;">0.00 [-0.02, 0.03]</td>
<td style="text-align: left;">0.01 [-0.02, 0.04]</td>
</tr>
<tr class="odd">
<td style="text-align: left;">b_sigma1</td>
<td style="text-align: left;">1.14 [1.10, 1.19]</td>
<td style="text-align: left;">1.14 [1.09, 1.19]</td>
</tr>
<tr class="even">
<td style="text-align: left;">b_sigma2</td>
<td style="text-align: left;">1.00 [0.96, 1.04]</td>
<td style="text-align: left;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;">var_alpha1</td>
<td style="text-align: left;">0.59 [0.44, 0.81]</td>
<td style="text-align: left;">0.60 [0.44, 0.83]</td>
</tr>
<tr class="even">
<td style="text-align: left;">var_phi</td>
<td style="text-align: left;">0.02 [0.01, 0.03]</td>
<td style="text-align: left;">0.02 [0.01, 0.03]</td>
</tr>
<tr class="odd">
<td style="text-align: left;">var_beta</td>
<td style="text-align: left;">0.77 [0.59, 1.03]</td>
<td style="text-align: left;">0.79 [0.61, 0.95]</td>
</tr>
<tr class="even">
<td style="text-align: left;">var_alpha2</td>
<td style="text-align: left;">0.00 [0.00, 0.01]</td>
<td style="text-align: left;">0.01 [0.00, 0.01]</td>
</tr>
</tbody>
</table>
</div>
</div>
</figure>
</div>
</div>
</section>
<section id="conclusion" class="level1">
<h1>Conclusion</h1>
<p>Because it is easy to specify latent means in brms, I think I will be using them much more often from now on, especially if my sample size per person is small. I don’t think this will make much of a difference after that sample size is greater than, say, the magic number 30.</p>
<p>Let me know if you have any comments!</p>
</section>




<div id="quarto-appendix" class="default"><section id="history" class="level1 appendix"><h2 class="anchored quarto-appendix-heading">History</h2><div class="quarto-appendix-contents">

<div class="callout callout-style-default callout-note no-icon callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>Earlier versions of this post contained syntax errors. The data stacking trick was suggested to me by Mauricio Garnier-Villarreal (thanks!)</p>
<p>While drafting this entry, I asked for help with coding this up in brms on the Stan forums: <a href="https://discourse.mc-stan.org/t/latent-mean-centering-latent-covariate-models-in-brms/29424" class="uri">https://discourse.mc-stan.org/t/latent-mean-centering-latent-covariate-models-in-brms/29424</a>. I couldn’t have figured it out without the help of all those people who answered. Thanks!</p>
<p>The earlier drafts and mistakes I made in coding the brms model up can be found in the <a href="https://github.com/mvuorre/mvuorre.github.io/commits/main/posts/stan-latent-mean-centering/index.qmd">Git history</a> of this file <span class="emoji" data-emoji="smile">😄</span></p>
</div>
</div>
</div></section><section id="see-also" class="level1 appendix"><h2 class="anchored quarto-appendix-heading">See also</h2><div class="quarto-appendix-contents">

<p>I’ve found these prior discussions useful</p>
<ul>
<li><a href="https://quantscience.rbind.io/2020/02/04/bayesian-mlm-with-group-mean-centering/#group-mean-centering-treating-group-means-as-latent-variables" class="uri">https://quantscience.rbind.io/2020/02/04/bayesian-mlm-with-group-mean-centering/#group-mean-centering-treating-group-means-as-latent-variables</a></li>
<li><a href="https://discourse.mc-stan.org/t/treat-the-cluster-mean-of-a-predictor-variable-as-a-latent-variable-hierarchical-linear-models/15001/5" class="uri">https://discourse.mc-stan.org/t/treat-the-cluster-mean-of-a-predictor-variable-as-a-latent-variable-hierarchical-linear-models/15001/5</a></li>
<li><a href="https://discourse.mc-stan.org/t/modeling-latent-means-in-brms-for-multilevel-group-mean-centering/12642/3" class="uri">https://discourse.mc-stan.org/t/modeling-latent-means-in-brms-for-multilevel-group-mean-centering/12642/3</a></li>
<li><a href="https://scottclaessens.github.io/blog/2020/brmsLV/" class="uri">https://scottclaessens.github.io/blog/2020/brmsLV/</a></li>
<li><a href="https://discourse.mc-stan.org/t/mi-with-non-linear-model/11227" class="uri">https://discourse.mc-stan.org/t/mi-with-non-linear-model/11227</a></li>
</ul>



</div></section><section class="quarto-appendix-contents" id="quarto-bibliography"><h2 class="anchored quarto-appendix-heading">References</h2><div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="0">
<div id="ref-mcneishPrimerTwolevelDynamic2020" class="csl-entry">
McNeish, Daniel, and Ellen L. Hamaker. 2020. <span>“A Primer on Two-Level Dynamic Structural Equation Models for Intensive Longitudinal Data in <span>Mplus</span>.”</span> <em>Psychological Methods</em> 25 (5): 610–35. <a href="https://doi.org/10.1037/met0000250">https://doi.org/10.1037/met0000250</a>.
</div>
</div></section><section id="footnotes" class="footnotes footnotes-end-of-document"><h2 class="anchored quarto-appendix-heading">Footnotes</h2>

<ol>
<li id="fn1"><p>Grab a free copy at <a href="https://osf.io/j56bm/download" class="uri">https://osf.io/j56bm/download</a>. I couldn’t figure if this example data is real or simulated, or what the measurement instruments were.↩︎</p></li>
</ol>
</section><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{vuorre2023,
  author = {Vuorre, Matti},
  title = {Latent Mean Centering with Brms},
  date = {2023-01-01},
  url = {https://vuorre.com/posts/latent-mean-centering/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-vuorre2023" class="csl-entry quarto-appendix-citeas">
Vuorre, Matti. 2023. <span>“Latent Mean Centering with Brms.”</span>
January 1, 2023. <a href="https://vuorre.com/posts/latent-mean-centering/">https://vuorre.com/posts/latent-mean-centering/</a>.
</div></div></section></div> ]]></description>
  <category>r</category>
  <category>statistics</category>
  <guid>https://vuorre.com/posts/latent-mean-centering/</guid>
  <pubDate>Sat, 31 Dec 2022 23:00:00 GMT</pubDate>
  <media:content url="https://vuorre.com/posts/latent-mean-centering/index_files/figure-html/fig-data-1.png" medium="image" type="image/png" height="58" width="144"/>
</item>
<item>
  <title>How I like to set up my computer</title>
  <dc:creator>Matti Vuorre</dc:creator>
  <link>https://vuorre.com/posts/computer-setup-dotfiles/</link>
  <description><![CDATA[ 





<p>Like many people in academia, I spend much of my working time in front of computers. It’s then important to me that everything is <em>just</em> the way I want it, software is easily available and updated, and that my terminal looks nice <span class="emoji" data-emoji="mage">🧙</span>.</p>
<p>This blog post is an adaptation of a document that I’ve saved for myself in the eventual case that I have to wipe my computer and reinstall everything, or if I get a new computer. I use Macs, but some of these things also work on Linux. Nothing here will work for Windows machines.</p>
<section id="macos-setup" class="level1">
<h1>MacOS setup</h1>
<p>This aims to be succinct and quick, using homebrew to install as much as possible from the command line.</p>
<section id="software" class="level2">
<h2 class="anchored" data-anchor-id="software">Software</h2>
<p>Fire up the terminal and install <a href="https://brew.sh/">homebrew</a>. The command is currently</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">/bin/bash</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-c</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">curl</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-fsSL</span> https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">)</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span></span></code></pre></div></div>
<p>but I would check the website before running that. Then install some stuff. First the GUI stuff that I use:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb2-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># GUI apps</span></span>
<span id="cb2-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">brew</span> install <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--cask</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb2-3">  firefox iterm2 microsoft-office <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb2-4">  zotero obsidian todoist sublime-text <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb2-5">  mactex rectangle alfred slack zoom <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb2-6">  visual-studio-code docker monitorcontrol</span></code></pre></div></div>
<p>Then the terminal and command line things that I like to use:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb3-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Terminal and CLI things</span></span>
<span id="cb3-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">brew</span> install <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb3-3">  tailscale starship bat <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb3-4">  btop lsd dua syncthing</span></code></pre></div></div>
<p>And then a bunch of fonts. There’s probably more now but I’ve forgotten. The more the merrier <span class="emoji" data-emoji="smile">😄</span>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb4-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">brew</span> tap homebrew/cask-fonts</span>
<span id="cb4-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">brew</span> install svn</span>
<span id="cb4-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">brew</span> install <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--cask</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-4">  font-fantasque-sans-mono font-fantasque-sans-mono-nerd-font <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-5">  font-noto-sans font-noto-serif font-noto-mono font-noto-mono-for-powerline <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-6">  font-noto-emoji font-hasklug-nerd-font font-anonymice-nerd-font <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-7">  font-meslo-lg-nerd-font font-fira-code font-fira-mono font-fira-sans <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-8">  font-fira-sans-condensed font-pt-mono font-pt-sans font-pt-sans-narrow <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-9">  font-pt-serif font-pt-sans-caption font-pt-serif-caption</span></code></pre></div></div>
</section>
<section id="terminal" class="level2">
<h2 class="anchored" data-anchor-id="terminal">Terminal</h2>
<p>I then set up my terminal environment. I use <a href="https://iterm2.com/">iTerm2</a> and the <a href="https://starship.rs/">Starship</a> prompt. I also pick up some nice iTerm2 color themes from <a href="https://iterm2colorschemes.com/" class="uri">https://iterm2colorschemes.com/</a>.</p>
<p>Now I can open up VS Code in the current working directory with <code>code .</code>, or get nice outputs when listing working directory contents (I’ve aliased <code>l</code> to <code>lsd -la</code> in <code>~/.zshrc</code>):</p>
<p><img src="https://vuorre.com/posts/computer-setup-dotfiles/images/terminal.png" class="img-fluid"></p>
</section>
<section id="r" class="level2">
<h2 class="anchored" data-anchor-id="r">R</h2>
<p>Then onto the serious stuff <span class="emoji" data-emoji="gem">💎</span></p>
<ul>
<li><p>I install R from <a href="https://cran.r-project.org/">CRAN</a> because I (sometimes) want to use specific versions. Also I need to remember to get the appropriate M1 version more often <span class="emoji" data-emoji="smile">😄</span>.</p></li>
<li><p>RStudio: I use the <a href="https://dailies.rstudio.com/">daily development version</a> of RStudio. I don’t install this with homebrew because it sometimes has issues with using the right R version.</p></li>
<li><p>I also used to make sure that I’m using the faster Apple provided <a href="https://cran.r-project.org/bin/macosx/RMacOSX-FAQ.html#Which-BLAS-is-used-and-how-can-it-be-changed_003f">BLAS</a> (20x faster for some operations). I can’t remember if I’ve done that this time though and am now afraid to check.</p></li>
</ul>
<p>I then immediately open RStudio and install my “base” packages that I use all the time.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb5-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">install.packages</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"pak"</span>)</span>
<span id="cb5-2">pak<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pkg_install</span>(</span>
<span id="cb5-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(</span>
<span id="cb5-4">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"usethis"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"tidyverse"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"brms"</span>, </span>
<span id="cb5-5">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"kableExtra"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"janitor"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"here"</span>, </span>
<span id="cb5-6">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"scales"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gtsummary"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"multidplyr"</span>, </span>
<span id="cb5-7">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ggtext"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"parameters"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"tidybayes"</span>, </span>
<span id="cb5-8">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ggstance"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ggdist"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"patchwork"</span>, </span>
<span id="cb5-9">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ggforce"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ggh4x"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"lavaan"</span>, </span>
<span id="cb5-10">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"emmeans"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ggstance"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"renv"</span>, </span>
<span id="cb5-11">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"furrr"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"remotes"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"kableExtra"</span>,</span>
<span id="cb5-12">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gt"</span></span>
<span id="cb5-13">  )</span>
<span id="cb5-14">)</span></code></pre></div></div>
</section>
<section id="utilities" class="level2">
<h2 class="anchored" data-anchor-id="utilities">Utilities</h2>
<p>I use <a href="https://apps.apple.com/us/app/amphetamine/id937984704?mt=12">Amphetamine</a> to make sure my computer never sleeps (unless I tell it to.) Amphetamine is not available on homebrew.</p>
<section id="zotero" class="level3">
<h3 class="anchored" data-anchor-id="zotero">Zotero</h3>
<p>I love Zotero, and it has some stellar plugins:</p>
<ul>
<li>Install the Zotero SciHub add-on so I can access papers <a href="https://github.com/ethanwillis/zotero-scihub" class="uri">https://github.com/ethanwillis/zotero-scihub</a></li>
<li>Better BibTex <a href="https://retorque.re/zotero-better-bibtex/installation/" class="uri">https://retorque.re/zotero-better-bibtex/installation/</a>
<ul>
<li>This will automatically help manage bibtex keys</li>
<li>Possible to live-update a .bib file for e.g.&nbsp;syncing to somewhere</li>
</ul></li>
<li>Zutilo <a href="https://github.com/wshanks/Zutilo" class="uri">https://github.com/wshanks/Zutilo</a>, but I can’t now remember what it even does</li>
<li>ZotFile
<ul>
<li>Point Zotero to my pdfs on ~/Sync/ZoteroPDF (Syncthing directory)</li>
<li>check change to lower case, replace blanks, max length 60 in zotfile settings</li>
</ul></li>
<li>Use <a href="https://github.com/retorquere/zotero-storage-scanner" class="uri">https://github.com/retorquere/zotero-storage-scanner</a> to e.g.&nbsp;get rid of broken attachments</li>
</ul>
</section>
</section>
<section id="general-things" class="level2">
<h2 class="anchored" data-anchor-id="general-things">General Things</h2>
<p>I then turn on Dock hiding in Mac settings. Have I told you that the Ventura update totally destroyed the Settings menu, and I am now seriously considering switching to Linux? Well I did now. I also rename the computer to something dumb in System settings &gt; Sharing &gt; Computer Name.</p>
</section>
<section id="dotfiles-and-configuration-files" class="level2">
<h2 class="anchored" data-anchor-id="dotfiles-and-configuration-files">Dotfiles and configuration files</h2>
<p>I also have a git repo with some dotfiles and configurations I use, but it’s currently private. It mainly creates some terminal aliases and theme options, and git global configurations. I just backup existing files and copy from the repo to wherever they need to be, but there are more complicated workflows too.</p>
</section>
</section>
<section id="conclusion" class="level1">
<h1>Conclusion</h1>
<p>After this I usually have a pretty useful computer. Because of homebrew its quite fast too.</p>

</section>

<div id="quarto-appendix" class="default"><section id="credits" class="level2 appendix"><h2 class="anchored quarto-appendix-heading">Credits</h2><div class="quarto-appendix-contents">

<p>Inspired by <a href="https://gist.github.com/gadenbuie/a14cab3d075901d8b25cbaf9e1f1fa7d" class="uri">https://gist.github.com/gadenbuie/a14cab3d075901d8b25cbaf9e1f1fa7d</a>.</p>


</div></section><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{vuorre2022,
  author = {Vuorre, Matti},
  title = {How {I} Like to Set up My Computer},
  date = {2022-12-08},
  url = {https://vuorre.com/posts/computer-setup-dotfiles/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-vuorre2022" class="csl-entry quarto-appendix-citeas">
Vuorre, Matti. 2022. <span>“How I Like to Set up My Computer.”</span>
December 8, 2022. <a href="https://vuorre.com/posts/computer-setup-dotfiles/">https://vuorre.com/posts/computer-setup-dotfiles/</a>.
</div></div></section></div> ]]></description>
  <category>workflow</category>
  <guid>https://vuorre.com/posts/computer-setup-dotfiles/</guid>
  <pubDate>Wed, 07 Dec 2022 23:00:00 GMT</pubDate>
  <media:content url="https://vuorre.com/posts/computer-setup-dotfiles/images/terminal.png" medium="image" type="image/png" height="74" width="144"/>
</item>
<item>
  <title>Tidymultiverse</title>
  <dc:creator>Matti Vuorre</dc:creator>
  <link>https://vuorre.com/posts/parallel-multiverse/</link>
  <description><![CDATA[ 





<section id="introduction" class="level1">
<h1>Introduction</h1>
<p>The results of statistical analyses often depend on analysts’ (sometimes arbitrary) decisions, such as which covariates to model or what subsets of data to analyse. Multiverse, or specification curve, analysis is a method whereby the analysts don’t only conduct and report the results from one model, but instead conduct all the relevant and plausible analyses and report all the results <span class="citation" data-cites="simonsohnSpecificationCurveAnalysis2020 steegenIncreasingTransparencyMultiverse2016">(Simonsohn, Simmons, and Nelson 2020; Steegen et al. 2016)</span>.</p>
<p>For example, <span class="citation" data-cites="orbenAssociationAdolescentWellbeing2019">Orben and Przybylski (2019)</span> showed, through analyzing the same datasets in thousands of different ways, that conclusions regarding the association between the psychological well-being of adolescents and their digital technology use critically depend on (mostly) arbitrary decisions in how and which data are analysed (Figure&nbsp;1).</p>
<div class="cell">
<div class="cell-output-display">
<div id="fig-op3" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-op3-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/parallel-multiverse/images/orben-przybylski-2019-fig3.png" class="img-fluid figure-img" width="944">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-op3-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;1: Figure 3 from <span class="citation" data-cites="orbenAssociationAdolescentWellbeing2019">Orben and Przybylski (2019)</span>. Reproduced 100% without permission, but I don’t think Dr Orben or Dr Przybylski would mind.
</figcaption>
</figure>
</div>
</div>
</div>
<p>This blog entry is about the technical aspects of conducting multiverse analyses in R. Specifically, I want to find out easy and flexible methods of specifying and conducting multiverse analyses <em>in parallel</em>. I have briefly examined the landscape of R packages that facilitate multiverse analyses, and found that none suited my needs perfectly. In this entry, I therefore try to outline a general and flexible <a href="https://www.tidyverse.org/">tidyverse</a>-centric <span class="citation" data-cites="tidyverse">(Wickham et al. 2019)</span> multiverse analysis pipeline. I eschew using external packages to maximize flexibility and speed (parallel processing).</p>
<p>Currently, I am aware of three R packages for conducting multiverse analyses. The <a href="https://github.com/MUCollective/multiverse/">multiverse</a> package <span class="citation" data-cites="multiverse-r">(Sarma et al. 2021)</span> provides extensive functionality for conducting and reporting multiverse analyses, including a “domain specific language” for analyses and reporting. However, while powerful, the package seems somewhat complicated (for the use cases that I have in mind). Frankly, after briefly reviewing the documentation, I don’t know how to use it (but it seems very cool!) <a href="https://github.com/mverseanalysis/mverse/">mverse</a> aims to make the multiverse package easier to use <span class="citation" data-cites="mverse">(Moon et al. 2022)</span>. I haven’t explored it much but it only seems to offer <code>lm()</code> and <code>glm()</code> models. <a href="https://github.com/masurp/specr">specr</a> (maybe most relevant for my use cases in psychology) provides a much simpler set of functions (with less flexibility, however <span class="citation" data-cites="specr">(Masur and Scharkow 2020)</span>).</p>
<p>Another downside of these packages is that they, with multiverse being an exception, don’t provide options for parallel computations. Parallelization is quite important because multiverse analyses can include (tens, hundreds) of thousands of analyses and can therefore take a long time to complete. I started a pull request that aimed to add that functionality to specr, but along the way found that it wasn’t so easy to implement with the current specr syntax and codebase, and my limited R skills.</p>
<p>While thinking about how to best contribute to specr, I realized that multiverse analyses don’t necessarily need extra functions, but can be easily implemented in familiar data analysis pipelines (<a href="https://dplyr.tidyverse.org/">dplyr</a> and <code>%&gt;%</code> <span class="citation" data-cites="dplyr">(Wickham et al. 2022)</span>; depending on how familiar you are with the tidyverse). This entry is part of my journey of trying to figure out how to flexibly conduct multiverse analyses in parallel in R, and demonstrates a flexible syntax for parallelizing multiverse analyses with <code>%&gt;%</code>lines.</p>
<p>I am not an expert in parallel processing by any means, so would love to know if you have any feedback on how I’ve implemented it below! Let me know in the comments <span class="emoji" data-emoji="smile">😄</span></p>
</section>
<section id="example-multiverse-analysis-with-specr" class="level1">
<h1>Example multiverse analysis with specr</h1>
<p>Let’s start with a simple toy example with two outcomes, two predictors, two covariates, and four subgroups, and no prior reason to choose between specifications. That is, we think that <code>y1</code> and <code>y2</code> are equally likely to represent our outcome construct of interest, <code>x1</code> and <code>x2</code> are equally likely to represent the predictor construct, and we can’t choose if or how to include the covariates <code>c1</code> and <code>c2</code> in the model. We might also consider the subgroups defined by <code>group</code> separately (and are not willing to do hierarchical models.) Let’s load the required libraries and show the example data (Table&nbsp;1):</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Packages</span></span>
<span id="cb1-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(kableExtra)</span>
<span id="cb1-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(scales)</span>
<span id="cb1-4"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(ggthemes)</span>
<span id="cb1-5"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(tictoc)</span>
<span id="cb1-6"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(tidyverse)</span>
<span id="cb1-7"></span>
<span id="cb1-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Pretty plots</span></span>
<span id="cb1-9"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme_set</span>(</span>
<span id="cb1-10">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme_few</span>(</span>
<span id="cb1-11">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">base_family =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Comic Sans MS"</span>,</span>
<span id="cb1-12">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">base_size =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span></span>
<span id="cb1-13">  )</span>
<span id="cb1-14">)</span>
<span id="cb1-15"></span>
<span id="cb1-16"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Pretty tables</span></span>
<span id="cb1-17">k2 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(x, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">full_width =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span>) {</span>
<span id="cb1-18">  x <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb1-19">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kbl</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb1-20">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable_classic_2</span>(</span>
<span id="cb1-21">      <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">html_font =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Arial"</span>,</span>
<span id="cb1-22">      <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">lightable_options =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"striped"</span>,</span>
<span id="cb1-23">      <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">full_width =</span> full_width</span>
<span id="cb1-24">    )</span>
<span id="cb1-25">}</span>
<span id="cb1-26"></span>
<span id="cb1-27"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Data generation</span></span>
<span id="cb1-28">generate_data <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">seed =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NA</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1e5</span>) {</span>
<span id="cb1-29">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(seed)) {</span>
<span id="cb1-30">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">set.seed</span>(seed)</span>
<span id="cb1-31">  }</span>
<span id="cb1-32">  dat <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tibble</span>(</span>
<span id="cb1-33">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x1 =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rnorm</span>(n),</span>
<span id="cb1-34">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x2 =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rnorm</span>(n),</span>
<span id="cb1-35">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y1 =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rnorm</span>(n) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x1 <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,</span>
<span id="cb1-36">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y2 =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rnorm</span>(n) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x1 <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>,</span>
<span id="cb1-37">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">c1 =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rnorm</span>(n) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x1 <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>,</span>
<span id="cb1-38">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">c2 =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rnorm</span>(n),</span>
<span id="cb1-39">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">group =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sample</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"a"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"b"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"c"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"d"</span>), n, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">replace =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>)</span>
<span id="cb1-40">  )</span>
<span id="cb1-41">}</span>
<span id="cb1-42">dat <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">generate_data</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>)</span></code></pre></div></div>
</details>
</div>
<div class="cell">
<div id="tbl-data" class="cell quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-tbl figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-tbl" id="tbl-data-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Table&nbsp;1: Example data (n = 100,000; 5.3 Mb on disk)
</figcaption>
<div aria-describedby="tbl-data-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell-output-display">
<table class="lightable-classic-2 lightable-striped do-not-create-environment cell caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: right;" data-quarto-table-cell-role="th">x1</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">x2</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">y1</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">y2</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">c1</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">c2</th>
<th style="text-align: left;" data-quarto-table-cell-role="th">group</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;">-0.77</td>
<td style="text-align: right;">1.10</td>
<td style="text-align: right;">-0.36</td>
<td style="text-align: right;">-1.23</td>
<td style="text-align: right;">0.78</td>
<td style="text-align: right;">-0.77</td>
<td style="text-align: left;">d</td>
</tr>
<tr class="even">
<td style="text-align: right;">-0.82</td>
<td style="text-align: right;">-1.68</td>
<td style="text-align: right;">-0.50</td>
<td style="text-align: right;">-0.79</td>
<td style="text-align: right;">-1.08</td>
<td style="text-align: right;">-0.81</td>
<td style="text-align: left;">b</td>
</tr>
<tr class="odd">
<td style="text-align: right;">-0.14</td>
<td style="text-align: right;">-1.89</td>
<td style="text-align: right;">-0.67</td>
<td style="text-align: right;">0.71</td>
<td style="text-align: right;">-0.89</td>
<td style="text-align: right;">-0.66</td>
<td style="text-align: left;">b</td>
</tr>
<tr class="even">
<td style="text-align: right;">-0.28</td>
<td style="text-align: right;">-0.98</td>
<td style="text-align: right;">0.68</td>
<td style="text-align: right;">-1.40</td>
<td style="text-align: right;">1.24</td>
<td style="text-align: right;">-0.25</td>
<td style="text-align: left;">c</td>
</tr>
<tr class="odd">
<td style="text-align: right;">0.44</td>
<td style="text-align: right;">-0.10</td>
<td style="text-align: right;">0.83</td>
<td style="text-align: right;">0.11</td>
<td style="text-align: right;">-0.78</td>
<td style="text-align: right;">-0.45</td>
<td style="text-align: left;">d</td>
</tr>
<tr class="even">
<td style="text-align: right;">-1.19</td>
<td style="text-align: right;">-0.54</td>
<td style="text-align: right;">-0.38</td>
<td style="text-align: right;">2.10</td>
<td style="text-align: right;">1.42</td>
<td style="text-align: right;">1.11</td>
<td style="text-align: left;">b</td>
</tr>
</tbody>
</table>
</div>
</div>
</figure>
</div>
</div>
<p>We can specify a fully crossed multiverse analysis over outcomes, predictors, and covariates, easily with specr. Also, to make the example a bit more interesting (slower!) for later examples, I’ll estimate the model using two functions (<code>lm()</code> and <code>glm()</code> which in this case give the same results, but the latter is much slower). I time the multiverse analysis using tictoc. Table&nbsp;2 shows the first few rows of the results.</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb2-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(specr)</span>
<span id="cb2-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tic</span>()</span>
<span id="cb2-3">results_specr <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">run_specs</span>(</span>
<span id="cb2-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">df =</span> dat,</span>
<span id="cb2-5">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"y1"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"y2"</span>),</span>
<span id="cb2-6">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"x1"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"x2"</span>),</span>
<span id="cb2-7">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">model =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"lm"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"glm"</span>),</span>
<span id="cb2-8">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">controls =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"c1"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"c2"</span>),</span>
<span id="cb2-9">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">subsets =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">list</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">group =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">unique</span>(dat<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>group))</span>
<span id="cb2-10">)</span>
<span id="cb2-11"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">toc</span>()</span></code></pre></div></div>
</details>
<div class="cell-output cell-output-stdout">
<pre><code>29.142 sec elapsed</code></pre>
</div>
</div>
<div class="cell">
<details class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb4-1">results_specr <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb4-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb4-3">  .[, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>] <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb4-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kbl</span>(</span>
<span id="cb4-5">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span></span>
<span id="cb4-6">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb4-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable_classic_2</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">html_font =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Arial"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">full_width =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span>)</span></code></pre></div></div>
</details>
<div id="tbl-specr" class="cell quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-tbl figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-tbl" id="tbl-specr-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Table&nbsp;2: First six rows of multiverse numerical results from specr
</figcaption>
<div aria-describedby="tbl-specr-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell-output-display">
<table class="lightable-classic-2 do-not-create-environment cell caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;" data-quarto-table-cell-role="th">x</th>
<th style="text-align: left;" data-quarto-table-cell-role="th">y</th>
<th style="text-align: left;" data-quarto-table-cell-role="th">model</th>
<th style="text-align: left;" data-quarto-table-cell-role="th">controls</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">estimate</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">std.error</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">statistic</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">p.value</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">conf.low</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">conf.high</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">lm</td>
<td style="text-align: left;">c1 + c2</td>
<td style="text-align: right;">0.09</td>
<td style="text-align: right;">0.01</td>
<td style="text-align: right;">13.96</td>
<td style="text-align: right;">0.00</td>
<td style="text-align: right;">0.08</td>
<td style="text-align: right;">0.11</td>
</tr>
<tr class="even">
<td style="text-align: left;">x2</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">lm</td>
<td style="text-align: left;">c1 + c2</td>
<td style="text-align: right;">0.00</td>
<td style="text-align: right;">0.01</td>
<td style="text-align: right;">0.48</td>
<td style="text-align: right;">0.63</td>
<td style="text-align: right;">-0.01</td>
<td style="text-align: right;">0.02</td>
</tr>
<tr class="odd">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y2</td>
<td style="text-align: left;">lm</td>
<td style="text-align: left;">c1 + c2</td>
<td style="text-align: right;">0.20</td>
<td style="text-align: right;">0.01</td>
<td style="text-align: right;">29.79</td>
<td style="text-align: right;">0.00</td>
<td style="text-align: right;">0.18</td>
<td style="text-align: right;">0.21</td>
</tr>
<tr class="even">
<td style="text-align: left;">x2</td>
<td style="text-align: left;">y2</td>
<td style="text-align: left;">lm</td>
<td style="text-align: left;">c1 + c2</td>
<td style="text-align: right;">0.01</td>
<td style="text-align: right;">0.01</td>
<td style="text-align: right;">0.79</td>
<td style="text-align: right;">0.43</td>
<td style="text-align: right;">-0.01</td>
<td style="text-align: right;">0.02</td>
</tr>
<tr class="odd">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">glm</td>
<td style="text-align: left;">c1 + c2</td>
<td style="text-align: right;">0.09</td>
<td style="text-align: right;">0.01</td>
<td style="text-align: right;">13.96</td>
<td style="text-align: right;">0.00</td>
<td style="text-align: right;">0.08</td>
<td style="text-align: right;">0.11</td>
</tr>
<tr class="even">
<td style="text-align: left;">x2</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">glm</td>
<td style="text-align: left;">c1 + c2</td>
<td style="text-align: right;">0.00</td>
<td style="text-align: right;">0.01</td>
<td style="text-align: right;">0.48</td>
<td style="text-align: right;">0.63</td>
<td style="text-align: right;">-0.01</td>
<td style="text-align: right;">0.02</td>
</tr>
</tbody>
</table>
</div>
</div>
</figure>
</div>
</div>
<p>Another great thing about this package is that you can easily draw specification curve figures (Figure&nbsp;2)</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb5-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">plot_specs</span>(</span>
<span id="cb5-2">  results_specr,</span>
<span id="cb5-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">choices =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"x"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"y"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"model"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"controls"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"subsets"</span>)</span>
<span id="cb5-4">)</span></code></pre></div></div>
</details>
<div class="cell-output-display">
<div id="fig-specr" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-specr-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/parallel-multiverse/index_files/figure-html/fig-specr-1.png" class="img-fluid figure-img" width="672">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-specr-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;2: Specification curve figure drawn from specr results
</figcaption>
</figure>
</div>
</div>
</div>
<p>However, even with this modest data set and 160 specifications, this took a while.</p>
<p>I first decided to take a stab at parallelizing <code>run_specs()</code>. This turned out to be a bit of a dead end because I couldn’t make the parallelization fit in with how <a href="https://github.com/masurp/specr/blob/master/R/run_specs.r"><code>run_specs()</code></a> works in the back-end.<sup>1</sup> So instead of shoehorning a parallel back-end to specr, I decided to implement the parallelization in a tidy pipeline. This pipeline, with no additional dependencies (apart from the tidyverse <span class="emoji" data-emoji="wink">😉</span>), works pretty well. It of course does not provide specr’s one-liners, but I believe the flexibility of this approach pays back for it.</p>
</section>
<section id="tidymultiverse" class="level1">
<h1>Tidymultiverse</h1>
<section id="specification-table" class="level2">
<h2 class="anchored" data-anchor-id="specification-table">Specification table</h2>
<p>The first step in a multiverse analysis is defining the grid of specifications.</p>
<p>The one difficulty here is that the dataset can also be part of the specifications (e.g.&nbsp;different outlier removal thresholds, or more generally any subsets or transformations of the data). If you include the dataset in the table of specifications, you would easily run out of memory (I learned this the hard way). So we will still iterate over the specs table, and pull relevant subsets of the data inside the function that iterates over the specs.</p>
<p>A flexible and easy way to declare the specifications is <code>expand_grid()</code>. This allows creating tables that cross all the variables declared therein. (There are related functions such as <code>expand()</code>, <code>crossing()</code>, and <code>nesting()</code> that allow for more flexibility.)</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb6-1">specs <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">expand_grid</span>(</span>
<span id="cb6-2">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"x1"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"x2"</span>),</span>
<span id="cb6-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"y1"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"y2"</span>),</span>
<span id="cb6-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">covariate =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"x1"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"x2"</span>),</span>
<span id="cb6-5">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">model =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"lm"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"glm"</span>)</span>
<span id="cb6-6">)</span></code></pre></div></div>
</details>
</div>
<div class="cell">
<div id="tbl-specs-1" class="cell quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-tbl figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-tbl" id="tbl-specs-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Table&nbsp;3: First six rows of example specifications table.
</figcaption>
<div aria-describedby="tbl-specs-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell-output-display">
<table class="lightable-classic-2 lightable-striped do-not-create-environment cell caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;" data-quarto-table-cell-role="th">x</th>
<th style="text-align: left;" data-quarto-table-cell-role="th">y</th>
<th style="text-align: left;" data-quarto-table-cell-role="th">covariate</th>
<th style="text-align: left;" data-quarto-table-cell-role="th">model</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">x1</td>
<td style="text-align: left;">lm</td>
</tr>
<tr class="even">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">x1</td>
<td style="text-align: left;">glm</td>
</tr>
<tr class="odd">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">x2</td>
<td style="text-align: left;">lm</td>
</tr>
<tr class="even">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">x2</td>
<td style="text-align: left;">glm</td>
</tr>
<tr class="odd">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y2</td>
<td style="text-align: left;">x1</td>
<td style="text-align: left;">lm</td>
</tr>
<tr class="even">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y2</td>
<td style="text-align: left;">x1</td>
<td style="text-align: left;">glm</td>
</tr>
</tbody>
</table>
</div>
</div>
</figure>
</div>
</div>
<p>But we could also just as well create a grid of formulas. Depending on your analysis, this might be a viable option</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb7-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">expand_grid</span>(</span>
<span id="cb7-2">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">formula =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"y1 ~ x1"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"y1 ~ x2"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"y1 ~ x1 + c1"</span>), <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># And so on</span></span>
<span id="cb7-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">model =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"lm"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"glm"</span>)</span>
<span id="cb7-4">)</span></code></pre></div></div>
</details>
</div>
<p>We will stick with specifying variables instead, for this example. We can include subgroups as well:</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb8-1">specs <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">expand_grid</span>(</span>
<span id="cb8-2">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"x1"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"x2"</span>),</span>
<span id="cb8-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"y1"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"y2"</span>),</span>
<span id="cb8-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">covariate =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"x1"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"x2"</span>),</span>
<span id="cb8-5">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">model =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"lm"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"glm"</span>),</span>
<span id="cb8-6">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Cross with all the unique values of `group` in the data</span></span>
<span id="cb8-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">distinct</span>(dat, group)</span>
<span id="cb8-8">)</span></code></pre></div></div>
</details>
</div>
<div class="cell">
<div id="tbl-specs-2" class="cell quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-tbl figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-tbl" id="tbl-specs-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Table&nbsp;4: First six rows of example specifications table with subgroups.
</figcaption>
<div aria-describedby="tbl-specs-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell-output-display">
<table class="lightable-classic-2 lightable-striped do-not-create-environment cell caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;" data-quarto-table-cell-role="th">x</th>
<th style="text-align: left;" data-quarto-table-cell-role="th">y</th>
<th style="text-align: left;" data-quarto-table-cell-role="th">covariate</th>
<th style="text-align: left;" data-quarto-table-cell-role="th">model</th>
<th style="text-align: left;" data-quarto-table-cell-role="th">group</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">x1</td>
<td style="text-align: left;">lm</td>
<td style="text-align: left;">d</td>
</tr>
<tr class="even">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">x1</td>
<td style="text-align: left;">lm</td>
<td style="text-align: left;">b</td>
</tr>
<tr class="odd">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">x1</td>
<td style="text-align: left;">lm</td>
<td style="text-align: left;">c</td>
</tr>
<tr class="even">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">x1</td>
<td style="text-align: left;">lm</td>
<td style="text-align: left;">a</td>
</tr>
<tr class="odd">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">x1</td>
<td style="text-align: left;">glm</td>
<td style="text-align: left;">d</td>
</tr>
<tr class="even">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">x1</td>
<td style="text-align: left;">glm</td>
<td style="text-align: left;">b</td>
</tr>
</tbody>
</table>
</div>
</div>
</figure>
</div>
</div>
<p>Now each row in the table specifies the modelling function (e.g.&nbsp;<code>lm()</code>), the subgroup, and the left-hand and right-hand side variables of the formula to put in the modelling function. Next, we need a function to also expand the covariates to all their combinations (I lifted much of this from the <a href="https://github.com/masurp/specr/blob/7d5a0c3664dd5d281ecaebb783ce75b638447205/R/setup_specs.r#L41">specr source</a>, I found it surprisingly hard to write):</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb9-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#' Expand a vector of covariate names to all their combinations</span></span>
<span id="cb9-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#'</span></span>
<span id="cb9-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#' For example expand_covariate(c("age", "sex")) returns</span></span>
<span id="cb9-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#' c("1", "age", "sex", "age + sex")</span></span>
<span id="cb9-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#'</span></span>
<span id="cb9-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#' @param covariate vector of covariate(s) e.g. c("age", "sex")</span></span>
<span id="cb9-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#'</span></span>
<span id="cb9-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#' @return a character vector of all predictor combinations</span></span>
<span id="cb9-9">expand_covariate <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(covariate) {</span>
<span id="cb9-10">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">list</span>(</span>
<span id="cb9-11">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"1"</span>,</span>
<span id="cb9-12">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">do.call</span>(</span>
<span id="cb9-13">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"c"</span>,</span>
<span id="cb9-14">      <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">map</span>(</span>
<span id="cb9-15">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">seq_along</span>(covariate),</span>
<span id="cb9-16">        <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">combn</span>(covariate, .x, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">FUN =</span> list)</span>
<span id="cb9-17">      )</span>
<span id="cb9-18">    ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb9-19">      <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">map</span>(<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">paste</span>(.x, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">collapse =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">" + "</span>))</span>
<span id="cb9-20">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb9-21">    unlist</span>
<span id="cb9-22">}</span></code></pre></div></div>
</details>
</div>
<p>Do let me know if you come up with something easier!</p>
<section id="the-specification-table" class="level3">
<h3 class="anchored" data-anchor-id="the-specification-table">The specification table</h3>
<p>Putting all this together, and creating the formulas from <code>y</code>, <code>x</code>, and <code>c</code> with <code>str_glue()</code>, we have completed the first part of our pipeline, creating the specifications:</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb10-1">specs <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">expand_grid</span>(</span>
<span id="cb10-2">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"x1"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"x2"</span>),</span>
<span id="cb10-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"y1"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"y2"</span>),</span>
<span id="cb10-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">covariate =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">expand_covariate</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"c1"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"c2"</span>)),</span>
<span id="cb10-5">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">model =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"lm"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"glm"</span>),</span>
<span id="cb10-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">distinct</span>(dat, group)</span>
<span id="cb10-7">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb10-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">formula =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_glue</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"{y} ~ {x} + {covariate}"</span>))</span></code></pre></div></div>
</details>
</div>
<div class="cell">
<div id="tbl-specs-3" class="cell quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-tbl figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-tbl" id="tbl-specs-3-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Table&nbsp;5: First six rows of example specifications table with subgroups and formulas.
</figcaption>
<div aria-describedby="tbl-specs-3-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell-output-display">
<table class="lightable-classic-2 lightable-striped do-not-create-environment cell caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;" data-quarto-table-cell-role="th">x</th>
<th style="text-align: left;" data-quarto-table-cell-role="th">y</th>
<th style="text-align: left;" data-quarto-table-cell-role="th">covariate</th>
<th style="text-align: left;" data-quarto-table-cell-role="th">model</th>
<th style="text-align: left;" data-quarto-table-cell-role="th">group</th>
<th style="text-align: left;" data-quarto-table-cell-role="th">formula</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">1</td>
<td style="text-align: left;">lm</td>
<td style="text-align: left;">d</td>
<td style="text-align: left;">y1 ~ x1 + 1</td>
</tr>
<tr class="even">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">1</td>
<td style="text-align: left;">lm</td>
<td style="text-align: left;">b</td>
<td style="text-align: left;">y1 ~ x1 + 1</td>
</tr>
<tr class="odd">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">1</td>
<td style="text-align: left;">lm</td>
<td style="text-align: left;">c</td>
<td style="text-align: left;">y1 ~ x1 + 1</td>
</tr>
<tr class="even">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">1</td>
<td style="text-align: left;">lm</td>
<td style="text-align: left;">a</td>
<td style="text-align: left;">y1 ~ x1 + 1</td>
</tr>
<tr class="odd">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">1</td>
<td style="text-align: left;">glm</td>
<td style="text-align: left;">d</td>
<td style="text-align: left;">y1 ~ x1 + 1</td>
</tr>
<tr class="even">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">1</td>
<td style="text-align: left;">glm</td>
<td style="text-align: left;">b</td>
<td style="text-align: left;">y1 ~ x1 + 1</td>
</tr>
</tbody>
</table>
</div>
</div>
</figure>
</div>
</div>
</section>
</section>
<section id="estimating-the-specifications" class="level2">
<h2 class="anchored" data-anchor-id="estimating-the-specifications">Estimating the specifications</h2>
<p>Having set up the specifications, all that is left to do is to iterate over them, while at the same time using the correct subsets of data. But before we do so, let’s first think about what we want the output to look like.</p>
<section id="outputs-and-errors" class="level3">
<h3 class="anchored" data-anchor-id="outputs-and-errors">Outputs and errors</h3>
<p>Currently, the output of <code>lm()</code> or <code>glm()</code> on each row will be a (g)lm object, from which we need to pull the information we need. In addition, the object will include the data used to estimate the model, and so the output might grow very large very quickly.</p>
<p>So it is best to just get the parameter(s) of interest when iterating over specs. To do that, we create functions to replace the model fitting functions with ones that estimate the model and then only return a table of parameters, and a count of observations in the model.</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb11-1">lm2 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(formula, data) {</span>
<span id="cb11-2">  fit <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">lm</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">formula =</span> formula, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> data)</span>
<span id="cb11-3">  out <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tidy</span>(fit, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">conf.int =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>) <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Tidy table of parameters</span></span>
<span id="cb11-4">  out <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">slice</span>(out, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>) <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Second row (slope parameter)</span></span>
<span id="cb11-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bind_cols</span>(out, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">nobs</span>(fit))</span>
<span id="cb11-6">}</span>
<span id="cb11-7"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">lm2</span>(y1 <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> x1, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> dat)</span></code></pre></div></div>
</details>
</div>
<div class="cell">
<div id="tbl-lm2-1" class="cell quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-tbl figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-tbl" id="tbl-lm2-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Table&nbsp;6: Output of <code>lm2(y1 ~ x1, data = dat)</code>.
</figcaption>
<div aria-describedby="tbl-lm2-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell-output-display">
<table class="lightable-classic-2 lightable-striped do-not-create-environment cell caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;" data-quarto-table-cell-role="th">term</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">estimate</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">std.error</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">statistic</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">p.value</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">conf.low</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">conf.high</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">n</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">x1</td>
<td style="text-align: right;">0.1</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">31.23</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">0.09</td>
<td style="text-align: right;">0.1</td>
<td style="text-align: right;">1e+05</td>
</tr>
</tbody>
</table>
</div>
</div>
</figure>
</div>
</div>
<p>We now have a neat function (<code>lm2()</code>) that fits the model and extracts the key parameter (Table&nbsp;6).</p>
<p>In addition, for a general solution, we should be able to handle errors. For example, some specifications might return 0 rows of data, which would break the iteration. To do so, we replace <code>lm2()</code> with a version that returns the output, or a tibble that says that zero observations were found (Table&nbsp;7).</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb12-1">lm2 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">possibly</span>(lm2, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">otherwise =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tibble</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>))</span>
<span id="cb12-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># See what it return when it gets bad input</span></span>
<span id="cb12-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">lm2</span>(group <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> x1, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> dat)</span></code></pre></div></div>
</details>
</div>
<div class="cell">
<div id="tbl-lm2-2" class="cell quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-tbl figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-tbl" id="tbl-lm2-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Table&nbsp;7: Output of <code>lm2(group ~ x1, data = dat)</code>.
</figcaption>
<div aria-describedby="tbl-lm2-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell-output-display">
<table class="lightable-classic-2 lightable-striped do-not-create-environment cell caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: right;" data-quarto-table-cell-role="th">n</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;">0</td>
</tr>
</tbody>
</table>
</div>
</div>
</figure>
</div>
</div>
<p>We also do this for <code>glm()</code>.</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb13-1">glm2 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(formula, data) {</span>
<span id="cb13-2">  fit <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">glm</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">formula =</span> formula, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> data)</span>
<span id="cb13-3">  out <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tidy</span>(fit, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">conf.int =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>)</span>
<span id="cb13-4">  out <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">slice</span>(out, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb13-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bind_cols</span>(out, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">nobs</span>(fit))</span>
<span id="cb13-6">}</span>
<span id="cb13-7">glm2 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">possibly</span>(glm2, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">otherwise =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tibble</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>))</span></code></pre></div></div>
</details>
</div>
<p>Generally, I would have done this before creating the specs table, but I was trying to start easy <span class="emoji" data-emoji="smile">😄</span>. For now, I just replace the model names in specs:</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb14-1">specs <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(specs, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">model =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">paste0</span>(model, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"2"</span>))</span></code></pre></div></div>
</details>
</div>
</section>
<section id="iterating-over-specs-with-pmap" class="level3">
<h3 class="anchored" data-anchor-id="iterating-over-specs-with-pmap">Iterating over specs with <code>pmap()</code></h3>
<p>We are now ready to iterate over specs, and apply <code>model</code> therein to the data and formula specified on each row. To do so, we pipe specs into <code>pmap()</code> (inside <code>mutate()</code>, which means that we are operating inside the specs data frame). <code>pmap()</code> takes a list of arguments, and passes them to a function, <code>pmap(list(a, b, c), ~some_function())</code>. But since we need to pull our function from a string within the list of arguments, our function is in fact the <code>do.call()</code> function caller. We can then pass all our arguments to the function called by <code>do.call()</code>. Freaky.</p>
<p>We will pass <code>list(model, formula, group)</code> to <code>do.call()</code>, that then uses the shorthand <code>..1</code>, <code>..2</code>, etc to take the first, second, etc, argument from the list. Critically, we can also put in another function (<code>filter()</code>) inside the <code>do.call()</code> argument list that will help us subset the data, based on the original arguments.</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb15-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tic</span>()</span>
<span id="cb15-2">results_dplyr <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> specs <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb15-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(</span>
<span id="cb15-4">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">out =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pmap</span>(</span>
<span id="cb15-5">      <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">list</span>(model, formula, group),</span>
<span id="cb15-6">      <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">do.call</span>(</span>
<span id="cb15-7">        ..<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,</span>
<span id="cb15-8">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">list</span>(</span>
<span id="cb15-9">          <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">formula =</span> ..<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>,</span>
<span id="cb15-10">          <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(dat, group <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> ..<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)</span>
<span id="cb15-11">        )</span>
<span id="cb15-12">      )</span>
<span id="cb15-13">    )</span>
<span id="cb15-14">  )</span>
<span id="cb15-15"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">toc</span>()</span></code></pre></div></div>
</details>
<div class="cell-output cell-output-stdout">
<pre><code>13.51 sec elapsed</code></pre>
</div>
</div>
<p>This then returns a copy of the specs table (<code>results_dplyr</code>) with an additional column <code>out</code>. But <code>out</code> is a data frame column, so to show the values next to our original specs, we can call <code>unnest()</code> (Table&nbsp;8).</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb17-1">results_dplyr <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> results_dplyr <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb17-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">unnest</span>(out)</span></code></pre></div></div>
</details>
</div>
<div class="cell">
<div id="tbl-mv-1" class="cell quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-tbl figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-tbl" id="tbl-mv-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Table&nbsp;8: First six rows of results from multiverse analysis.
</figcaption>
<div aria-describedby="tbl-mv-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell-output-display">
<table class="lightable-classic-2 lightable-striped do-not-create-environment cell caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;" data-quarto-table-cell-role="th">x</th>
<th style="text-align: left;" data-quarto-table-cell-role="th">y</th>
<th style="text-align: left;" data-quarto-table-cell-role="th">covariate</th>
<th style="text-align: left;" data-quarto-table-cell-role="th">model</th>
<th style="text-align: left;" data-quarto-table-cell-role="th">group</th>
<th style="text-align: left;" data-quarto-table-cell-role="th">formula</th>
<th style="text-align: left;" data-quarto-table-cell-role="th">term</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">estimate</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">std.error</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">statistic</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">p.value</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">conf.low</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">conf.high</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">n</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">1</td>
<td style="text-align: left;">lm2</td>
<td style="text-align: left;">d</td>
<td style="text-align: left;">y1 ~ x1 + 1</td>
<td style="text-align: left;">x1</td>
<td style="text-align: right;">0.09</td>
<td style="text-align: right;">0.01</td>
<td style="text-align: right;">14.78</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">0.08</td>
<td style="text-align: right;">0.11</td>
<td style="text-align: right;">24800</td>
</tr>
<tr class="even">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">1</td>
<td style="text-align: left;">lm2</td>
<td style="text-align: left;">b</td>
<td style="text-align: left;">y1 ~ x1 + 1</td>
<td style="text-align: left;">x1</td>
<td style="text-align: right;">0.11</td>
<td style="text-align: right;">0.01</td>
<td style="text-align: right;">16.98</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">0.09</td>
<td style="text-align: right;">0.12</td>
<td style="text-align: right;">25257</td>
</tr>
<tr class="odd">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">1</td>
<td style="text-align: left;">lm2</td>
<td style="text-align: left;">c</td>
<td style="text-align: left;">y1 ~ x1 + 1</td>
<td style="text-align: left;">x1</td>
<td style="text-align: right;">0.10</td>
<td style="text-align: right;">0.01</td>
<td style="text-align: right;">15.61</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">0.09</td>
<td style="text-align: right;">0.11</td>
<td style="text-align: right;">25045</td>
</tr>
<tr class="even">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">1</td>
<td style="text-align: left;">lm2</td>
<td style="text-align: left;">a</td>
<td style="text-align: left;">y1 ~ x1 + 1</td>
<td style="text-align: left;">x1</td>
<td style="text-align: right;">0.10</td>
<td style="text-align: right;">0.01</td>
<td style="text-align: right;">15.10</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">0.08</td>
<td style="text-align: right;">0.11</td>
<td style="text-align: right;">24898</td>
</tr>
<tr class="odd">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">1</td>
<td style="text-align: left;">glm2</td>
<td style="text-align: left;">d</td>
<td style="text-align: left;">y1 ~ x1 + 1</td>
<td style="text-align: left;">x1</td>
<td style="text-align: right;">0.09</td>
<td style="text-align: right;">0.01</td>
<td style="text-align: right;">14.78</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">0.08</td>
<td style="text-align: right;">0.11</td>
<td style="text-align: right;">24800</td>
</tr>
<tr class="even">
<td style="text-align: left;">x1</td>
<td style="text-align: left;">y1</td>
<td style="text-align: left;">1</td>
<td style="text-align: left;">glm2</td>
<td style="text-align: left;">b</td>
<td style="text-align: left;">y1 ~ x1 + 1</td>
<td style="text-align: left;">x1</td>
<td style="text-align: right;">0.11</td>
<td style="text-align: right;">0.01</td>
<td style="text-align: right;">16.98</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">0.09</td>
<td style="text-align: right;">0.12</td>
<td style="text-align: right;">25257</td>
</tr>
</tbody>
</table>
</div>
</div>
</figure>
</div>
</div>
<p>If you noticed above, we already saw an improvement in the run-time of this pipeline over <code>run_specs()</code>, but note that my implementation does not estimate models for the complete data (<code>subsets</code> = <code>all</code> in specr), so it is not a fair comparison.</p>
<p>Nevertheless, now that we have the basic building blocks of the tidy multiverse pipeline collected, let’s focus on what matters; <em>speed</em>.</p>
</section>
</section>
</section>
<section id="parallelizing-the-tidymultiverse" class="level1">
<h1>Parallelizing the tidymultiverse</h1>
<div class="callout callout-style-default callout-note no-icon callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>Parallelization is hard and rarely works out of the box. Multidplyr works best when the individual computations are slow, because there is always some overhead in sending stuff back and forth between the nodes of the cluster. So the benefits will be even greater with larger data or slower models. The furrr package seems to offer a slightly simpler solution, but your mileage may vary. Your feedback is more than welcome (comments are open at the end of this post)!</p>
</div>
</div>
<section id="multidplyr" class="level2">
<h2 class="anchored" data-anchor-id="multidplyr">multidplyr</h2>
<p>To start, we load multidplyr, create a new cluster, and send the required libraries and variables to it.</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb18-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(multidplyr)</span>
<span id="cb18-2"></span>
<span id="cb18-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Create a new cluster with eight nodes</span></span>
<span id="cb18-4">cluster <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">new_cluster</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>)</span>
<span id="cb18-5"></span>
<span id="cb18-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Load libraries in and send variables to nodes in the cluster</span></span>
<span id="cb18-7"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">cluster_library</span>(cluster, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"purrr"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"broom"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"tidyr"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dplyr"</span>))</span>
<span id="cb18-8"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">cluster_copy</span>(cluster, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dat"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"lm2"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"glm2"</span>))</span></code></pre></div></div>
</details>
</div>
<p>Multidplyr integrates seamlessly into <code>%&gt;%</code>lines by sending groups in the passed data to nodes in the cluster. It is therefore important to think a bit about how to group your data. For us, we want to equally divide the <code>lm()</code> and <code>glm()</code> calls across nodes, because <code>glm()</code> is considerably slower. If one node got all the <code>glm()</code> calls, we would have to wait for that one node even after the others had completed.</p>
<p>Here, it makes sense for us to group the data by <code>formula</code> and <code>group</code>. After grouping the data, we <code>partition()</code> it across the nodes in the cluster, run our computations, and then <code>collect()</code> the results back to our main R process. Notice that the <code>pmap()</code> call is identical to above.</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb19-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tic</span>()</span>
<span id="cb19-2">results_multidplyr <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> specs <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb19-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(formula, group) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb19-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">partition</span>(cluster) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb19-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(</span>
<span id="cb19-6">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">out =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pmap</span>(</span>
<span id="cb19-7">      <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">list</span>(model, formula, group),</span>
<span id="cb19-8">      <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">do.call</span>(</span>
<span id="cb19-9">        ..<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,</span>
<span id="cb19-10">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">list</span>(</span>
<span id="cb19-11">          <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">formula =</span> ..<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>,</span>
<span id="cb19-12">          <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(dat, group <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> ..<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)</span>
<span id="cb19-13">        )</span>
<span id="cb19-14">      )</span>
<span id="cb19-15">    )</span>
<span id="cb19-16">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb19-17">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">collect</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb19-18">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ungroup</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb19-19">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">unnest</span>(out)</span>
<span id="cb19-20"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">toc</span>()</span></code></pre></div></div>
</details>
<div class="cell-output cell-output-stdout">
<pre><code>3.163 sec elapsed</code></pre>
</div>
</div>
<p>This particular parallelization scheme (8 cores working on subsets defined by <code>formula</code> and <code>group</code> in <code>dat</code>) sped up our computations about 8 times compared to the original implementation, and about 4 times compared to the non-parallelized equivalent. Good stuff.</p>
</section>
<section id="furrr" class="level2">
<h2 class="anchored" data-anchor-id="furrr">furrr</h2>
<p>I like multidplyr a lot because I can manually specify how the data and computations are assigned across the cluster. I also like that you need to explicitly tell what packages and objects to send to the cluster. As a consequence the syntax grows a bit verbose, however.</p>
<p>As an alternative, the <a href="https://github.com/DavisVaughan/furrr/">furrr</a> package promises drop-in replacements to purrr’s <code>map()</code> functions that parallelize the computations <span class="citation" data-cites="furrr">(Vaughan and Dancho 2022)</span>. To use furrr’s functions, we first need to specify the parallelization scheme with <code>plan()</code>. We can then replace <code>pmap()</code> above with <code>future_pmap()</code>. Also, we need to pass objects from the global environment and packages using <code>furrr_options()</code> as shown below. Otherwise we can keep our <code>%&gt;%</code>line exactly the same.</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb21-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(furrr)</span>
<span id="cb21-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">plan</span>(multisession, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">workers =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>)</span>
<span id="cb21-3"></span>
<span id="cb21-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Pass these global objects to `future_pmap()`</span></span>
<span id="cb21-5">opts <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">furrr_options</span>(</span>
<span id="cb21-6">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">globals =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">list</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dat =</span> dat, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">lm2 =</span> lm2, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">glm2 =</span> glm2),</span>
<span id="cb21-7">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">packages =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dplyr"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"broom"</span>)</span>
<span id="cb21-8">)</span>
<span id="cb21-9"></span>
<span id="cb21-10"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tic</span>()</span>
<span id="cb21-11"></span>
<span id="cb21-12">results_furrr <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> specs <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb21-13">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(</span>
<span id="cb21-14">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">out =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">future_pmap</span>(</span>
<span id="cb21-15">      <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">list</span>(model, formula, group),</span>
<span id="cb21-16">      <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">do.call</span>(</span>
<span id="cb21-17">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">what =</span> ..<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,</span>
<span id="cb21-18">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">args =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">list</span>(</span>
<span id="cb21-19">          <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">formula =</span> ..<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>,</span>
<span id="cb21-20">          <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(dat, group <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> ..<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)</span>
<span id="cb21-21">        )</span>
<span id="cb21-22">      ),</span>
<span id="cb21-23">      <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.options =</span> opts</span>
<span id="cb21-24">    )</span>
<span id="cb21-25">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb21-26">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">unnest</span>(out)</span>
<span id="cb21-27"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">toc</span>()</span></code></pre></div></div>
</details>
<div class="cell-output cell-output-stdout">
<pre><code>5.623 sec elapsed</code></pre>
</div>
</div>
<p>This worked great. While we don’t have to partition our data, and collect the computations afterwards, furrr does require passing stuff using the <code>.options</code> argument. But this is still a bit less verbose than multidplyr, and perhaps therefore preferred. I like it!</p>
</section>
<section id="checking-results" class="level2">
<h2 class="anchored" data-anchor-id="checking-results">Checking results</h2>
<p>I also spot check that the results are consistent across the methods. I am a bit paranoid with what comes to parallel computation. Table&nbsp;9 shows that everything is as it should be.</p>
<div class="cell">
<div id="tbl-results-check" class="cell quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-tbl figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-tbl" id="tbl-results-check-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Table&nbsp;9: Example results from the four estimation methods.
</figcaption>
<div aria-describedby="tbl-results-check-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell-output-display">
<table class="lightable-classic-2 lightable-striped do-not-create-environment cell caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;" data-quarto-table-cell-role="th">Method</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">estimate</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">std.error</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">conf.low</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">conf.high</th>
<th style="text-align: left;" data-quarto-table-cell-role="th">group</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">specr</td>
<td style="text-align: right;">0.09</td>
<td style="text-align: right;">0.01</td>
<td style="text-align: right;">0.08</td>
<td style="text-align: right;">0.11</td>
<td style="text-align: left;">a</td>
</tr>
<tr class="even">
<td style="text-align: left;">tidymultiverse</td>
<td style="text-align: right;">0.09</td>
<td style="text-align: right;">0.01</td>
<td style="text-align: right;">0.08</td>
<td style="text-align: right;">0.11</td>
<td style="text-align: left;">a</td>
</tr>
<tr class="odd">
<td style="text-align: left;">tidymultiverse multidplyr</td>
<td style="text-align: right;">0.09</td>
<td style="text-align: right;">0.01</td>
<td style="text-align: right;">0.08</td>
<td style="text-align: right;">0.11</td>
<td style="text-align: left;">a</td>
</tr>
<tr class="even">
<td style="text-align: left;">tidymultiverse furrr</td>
<td style="text-align: right;">0.09</td>
<td style="text-align: right;">0.01</td>
<td style="text-align: right;">0.08</td>
<td style="text-align: right;">0.11</td>
<td style="text-align: left;">a</td>
</tr>
</tbody>
</table>
</div>
</div>
</figure>
</div>
</div>
</section>
</section>
<section id="a-visualization" class="level1">
<h1>A visualization</h1>
<p>Finally, like any analysis, multiverse analyses need to be visualized for understanding and communicating. Here, we use some ggplot2 magic to create a standard specification curve analysis figure (Figure&nbsp;3).</p>
<div class="cell">
<details open="" class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb23" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb23-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(patchwork)</span>
<span id="cb23-2">results <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">arrange</span>(results_furrr, estimate) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">spec =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">n</span>())</span>
<span id="cb23-3">p_dash <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> results <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb23-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(spec, p.value, x<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>group) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb23-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_longer</span>(<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(spec, p.value), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_transform =</span> as.character) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb23-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(spec, value, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">col =</span> p.value <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.05</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb23-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_color_brewer</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">palette =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Set1"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb23-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_x_continuous</span>(</span>
<span id="cb23-9">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Specification"</span></span>
<span id="cb23-10">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb23-11">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_point</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb23-12">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">facet_grid</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">rows =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">vars</span>(name), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">scales =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"free_y"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">space =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"free_y"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb23-13">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">axis.title.y =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">element_blank</span>())</span>
<span id="cb23-14">p_curve <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> results <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb23-15">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(spec, estimate, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">col =</span> p.value <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.05</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb23-16">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_color_brewer</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">palette =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Set1"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb23-17">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_pointrange</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">ymin =</span> conf.low, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">ymax =</span> conf.high), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb23-18">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">axis.title.x =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">element_blank</span>())</span>
<span id="cb23-19">(p_curve <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> p_dash) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span></span>
<span id="cb23-20">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">legend.position =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"none"</span>)</span></code></pre></div></div>
</details>
<div class="cell-output-display">
<div id="fig-results-sca" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-results-sca-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/parallel-multiverse/index_files/figure-html/fig-results-sca-1.png" class="img-fluid figure-img" width="672">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-results-sca-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;3: Specification curve figure example with ggplot().
</figcaption>
</figure>
</div>
</div>
</div>
</section>
<section id="what-else" class="level1">
<h1>What else?</h1>
<p>Using this method, we can pass whatever modelling functions (e.g.&nbsp;<code>lmer()</code>, <code>brm()</code>) and arguments to them (e.g.&nbsp;append the formula with <code>(1 | participant)</code> for <code>lmer()</code> hierarchical models) and parallelize the iterations quite easily. We can also imagine more complex data subsetting scenarios. For example, we could expand the specs table to include various conditions for filtering data (e.g.&nbsp;outliers). We could then pre-compute those (or do it in <code>do.call()</code>) to dynamically subset data differently in each row of specs.</p>
<p>I hope you found this helpful. If you’ve any feedback, comments are open below and I’d appreciate your thoughts!</p>



</section>


<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-bibliography"><h2 class="anchored quarto-appendix-heading">References</h2><div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="0">
<div id="ref-specr" class="csl-entry">
Masur, Philipp K., and Michael Scharkow. 2020. <span>“Specr: Conducting and Visualizing Specification Curve Analyses (Version 0.2.2).”</span> <a href="https://CRAN.R-project.org/package=specr">https://CRAN.R-project.org/package=specr</a>.
</div>
<div id="ref-mverse" class="csl-entry">
Moon, Michael Jongho, Haoda Li, Mingwei Xu, Nathan Taback, and Fanny Chevalier. 2022. <em>Mverse: Tidy Multiverse Analysis Made Simple</em>. <a href="https://CRAN.R-project.org/package=mverse">https://CRAN.R-project.org/package=mverse</a>.
</div>
<div id="ref-orbenAssociationAdolescentWellbeing2019" class="csl-entry">
Orben, Amy, and Andrew K. Przybylski. 2019. <span>“The Association Between Adolescent Well-Being and Digital Technology Use.”</span> <em>Nature Human Behaviour</em> 3 (2, 2): 173–82. <a href="https://doi.org/10.1038/s41562-018-0506-1">https://doi.org/10.1038/s41562-018-0506-1</a>.
</div>
<div id="ref-multiverse-r" class="csl-entry">
Sarma, Abhraneel, Alex Kale, Michael Moon, Nathan Taback, Fanny Chevalier, Jessica Hullman, and Matthew Kay. 2021. <span>“Multiverse: Multiplexing Alternative Data Analyses in r Notebooks (Version 0.6.1).”</span> <em>OSF Preprints</em>. <a href="https://github.com/MUCollective/multiverse">https://github.com/MUCollective/multiverse</a>.
</div>
<div id="ref-simonsohnSpecificationCurveAnalysis2020" class="csl-entry">
Simonsohn, Uri, Joseph P. Simmons, and Leif D. Nelson. 2020. <span>“Specification Curve Analysis.”</span> <em>Nature Human Behaviour</em>, July, 1–7. <a href="https://doi.org/10.1038/s41562-020-0912-z">https://doi.org/10.1038/s41562-020-0912-z</a>.
</div>
<div id="ref-steegenIncreasingTransparencyMultiverse2016" class="csl-entry">
Steegen, Sara, Francis Tuerlinckx, Andrew Gelman, and Wolf Vanpaemel. 2016. <span>“Increasing <span>Transparency Through</span> a <span>Multiverse Analysis</span>.”</span> <em>Perspectives on Psychological Science</em>, September. <a href="https://doi.org/10.1177/1745691616658637">https://doi.org/10.1177/1745691616658637</a>.
</div>
<div id="ref-furrr" class="csl-entry">
Vaughan, Davis, and Matt Dancho. 2022. <em>Furrr: Apply Mapping Functions in Parallel Using Futures</em>. <a href="https://CRAN.R-project.org/package=furrr">https://CRAN.R-project.org/package=furrr</a>.
</div>
<div id="ref-tidyverse" class="csl-entry">
Wickham, Hadley, Mara Averick, Jennifer Bryan, Winston Chang, Lucy D’Agostino McGowan, Romain François, Garrett Grolemund, et al. 2019. <span>“Welcome to the <span class="nocase">tidyverse</span>.”</span> <em>Journal of Open Source Software</em> 4 (43): 1686. <a href="https://doi.org/10.21105/joss.01686">https://doi.org/10.21105/joss.01686</a>.
</div>
<div id="ref-dplyr" class="csl-entry">
Wickham, Hadley, Romain François, Lionel Henry, and Kirill Müller. 2022. <em>Dplyr: A Grammar of Data Manipulation</em>. <a href="https://CRAN.R-project.org/package=dplyr">https://CRAN.R-project.org/package=dplyr</a>.
</div>
</div></section><section id="footnotes" class="footnotes footnotes-end-of-document"><h2 class="anchored quarto-appendix-heading">Footnotes</h2>

<ol>
<li id="fn1"><p>It first creates a data frame with the specs, then the requested subsets, and then either applies <code>run_spec()</code> to all the datasets and specs using <code>map()</code>, or if no subsets were requested, runs the <code>run_spec()</code> on the specs only. So it wasn’t straightforward to parallelize over both data subsets and specs. Parallelizing over specs <a href="https://github.com/masurp/specr/pull/31/commits/142bdf879b96966b3f4bd1fdf04e886711d827f1">was simple</a>.↩︎</p></li>
</ol>
</section><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{vuorre2022,
  author = {Vuorre, Matti},
  title = {Tidymultiverse},
  date = {2022-12-07},
  url = {https://vuorre.com/posts/parallel-multiverse/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-vuorre2022" class="csl-entry quarto-appendix-citeas">
Vuorre, Matti. 2022. <span>“Tidymultiverse.”</span> December 7, 2022. <a href="https://vuorre.com/posts/parallel-multiverse/">https://vuorre.com/posts/parallel-multiverse/</a>.
</div></div></section></div> ]]></description>
  <category>r</category>
  <category>statistics</category>
  <guid>https://vuorre.com/posts/parallel-multiverse/</guid>
  <pubDate>Tue, 06 Dec 2022 23:00:00 GMT</pubDate>
  <media:content url="https://vuorre.com/posts/parallel-multiverse/images/undraw-lost-online.png" medium="image" type="image/png" height="117" width="144"/>
</item>
<item>
  <title>Some alternatives to raincloud plots</title>
  <dc:creator>Matti Vuorre</dc:creator>
  <link>https://vuorre.com/posts/raincloud-plot-alt/</link>
  <description><![CDATA[ 





<section id="ggrain" class="level1">
<h1>ggrain</h1>
<p><a href="https://github.com/njudd/ggrain">ggrain</a> <span class="citation" data-cites="ggrain">(Judd, van Langen, and Kievit 2022)</span> is an R package that brings extra geoms to ggplot2 to make it easy to create informative plots of your data like Figure&nbsp;1.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(ggrain)</span>
<span id="cb1-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme_set</span>(</span>
<span id="cb1-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme_classic</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">base_family =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Comic Sans MS"</span>)</span>
<span id="cb1-4">)</span>
<span id="cb1-5"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(iris, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> Species, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> Sepal.Length, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">fill =</span> Species)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb1-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_rain</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">rain.side =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'l'</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<div id="fig-ggrain" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-ggrain-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/raincloud-plot-alt/index_files/figure-html/fig-ggrain-1.png" class="img-fluid figure-img" width="672">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-ggrain-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;1: A raincloud plot using the ggrain package.
</figcaption>
</figure>
</div>
</div>
</div>
<p>The hallmark feature of a raincloud plot is that it includes the raw data (points), a summary (boxplot), and a density (shaded curve/area) of your data.</p>
<p>I love raincloud plots. But. I am concerned that they might unnecessarily duplicate features of the data, which might lead to visually overwhelming presentations, and therefore degrade the signal to noise ratio of the plots.</p>
<p>It just might be possible to show these three features—raw data, summary, and densities—in a visually simpler and perhaps more compelling way. In this blog entry, I’ll try two variations on this theme that I hope simplify the presentation without taking information away.</p>
</section>
<section id="raincloud-plots-the-hard-way" class="level1">
<h1>Raincloud plots the hard way</h1>
<p>But first, I’ll try to recreate this raincloud plot without the ggrain package. Most of the geoms and stats we need are in the <a href="https://mjskay.github.io/ggdist/index.html">ggdist</a> package <span class="citation" data-cites="ggdist">(Kay 2022)</span>. The end result (Figure&nbsp;2) looks very similar to the ggrain version, above.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb2-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(tidyverse)</span>
<span id="cb2-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(ggdist)</span>
<span id="cb2-3">iris <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb2-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(Species, Sepal.Length, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">fill =</span> Species)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb2-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_point</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">position =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">position_jitter</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">width =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">033</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb2-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_boxplot</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">position =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">position_nudge</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.085</span>), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">width =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">05</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb2-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">stat_halfeye</span>(</span>
<span id="cb2-8">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">side =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"left"</span>,</span>
<span id="cb2-9">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">normalize =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"none"</span>,</span>
<span id="cb2-10">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">width =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>,</span>
<span id="cb2-11">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">position =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">position_nudge</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.15</span>),</span>
<span id="cb2-12">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">point_interval =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NULL</span></span>
<span id="cb2-13">  )</span></code></pre></div></div>
<div class="cell-output-display">
<div id="fig-ggdistrain-1" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-ggdistrain-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/raincloud-plot-alt/index_files/figure-html/fig-ggdistrain-1-1.png" class="img-fluid figure-img" width="672">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-ggdistrain-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;2: A raincloud plot made using ‘base’ ggplot2 and ggdist.
</figcaption>
</figure>
</div>
</div>
</div>
<p>OK, so now we have a handle on how to create raincloud plots “manually”.</p>
</section>
<section id="removing-summaries-and-densities" class="level1">
<h1>Removing summaries and densities</h1>
<p>What I would like to do next is to make the summaries less prominent. I can use <code>stat_halfeye()</code>. Above, I used <code>stat_halfeye(..., point_inteval = NULL)</code> to remove them completely. Here, I will specify some quantiles to show with the <code>width</code> argument. I am not sure if Figure&nbsp;3 is an improvement.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb3-1">iris <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb3-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(Species, Sepal.Length, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">fill =</span> Species)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb3-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_point</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">position =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">position_jitter</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">width =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">033</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb3-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">stat_halfeye</span>(</span>
<span id="cb3-5">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">side =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"left"</span>,</span>
<span id="cb3-6">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">normalize =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"none"</span>,</span>
<span id="cb3-7">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">width =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>,</span>
<span id="cb3-8">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">position =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">position_nudge</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1</span>),</span>
<span id="cb3-9">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.width =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(.<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">99</span>)</span>
<span id="cb3-10">  )</span></code></pre></div></div>
<div class="cell-output-display">
<div id="fig-ggdistrain-2" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-ggdistrain-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/raincloud-plot-alt/index_files/figure-html/fig-ggdistrain-2-1.png" class="img-fluid figure-img" width="672">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-ggdistrain-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;3: A raincloud plot made using ‘base’ ggplot2 and ggdist, with different summary geoms (a point interval).
</figcaption>
</figure>
</div>
</div>
</div>
<p>Maybe all this information can be gleaned from the points alone. To do this, we can jitter the points according to a method specified in the <a href="https://cran.r-project.org/web/packages/vipor/index.html">vipor</a> package <span class="citation" data-cites="vipor">(Sherrill-Mix and Clarke 2017)</span>.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb4-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(ggbeeswarm)</span>
<span id="cb4-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">set.seed</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb4-3">iris <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb4-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(Species, Sepal.Length, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">fill =</span> Species, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">col =</span> Species)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb4-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_point</span>(</span>
<span id="cb4-6">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">position =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">position_quasirandom</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">width =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb4-7">  )</span></code></pre></div></div>
<div class="cell-output-display">
<div id="fig-rain-bee" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-rain-bee-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/raincloud-plot-alt/index_files/figure-html/fig-rain-bee-1.png" class="img-fluid figure-img" width="672">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-rain-bee-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;4: A scatterplot where the points are jittered on the x-axis according to a normal density kernel.
</figcaption>
</figure>
</div>
</div>
</div>
<p>Figure&nbsp;4 arranges the points using one of the offsetting algorithms in vipor, brought to ggplot via the <a href="https://cran.r-project.org/web/packages/ggbeeswarm/index.html">ggbeeswarm</a> package <span class="citation" data-cites="ggbeeswarm">(Clarke and Sherrill-Mix 2017)</span>. By default, this is the “quasirandom” method, where “points are distributed within a kernel density estimate of the distribution with offset determined by quasirandom Van der Corput noise”. I can only guess that “the distribution” refers to a gaussian distribution.</p>
<p>It would be really nice if we could choose the x-axis side to which jitter the points. Then we could display two groups side by side. Unfortunately that is not possible.</p>
</section>
<section id="a-more-complicated-example" class="level1">
<h1>A more complicated example</h1>
<div id="fig-new-ggrain" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-new-ggrain-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://cdn.fosstodon.org/cache/media_attachments/files/109/460/641/893/080/595/small/0f1dcd129a6b60a5.png" class="img-fluid figure-img">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-new-ggrain-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;5: A more complicated raincloud plot courtesy of Rogier Kievit
</figcaption>
</figure>
</div>
<p>Let’s try a more complicated example similar to Rogier Kievit’s figure (Figure&nbsp;5). I first simulate some data with two groups and four timepoints. There’s also some covariate that I’d like to display.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb5-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Data generation</span></span>
<span id="cb5-2">generate_data <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">seed =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NA</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">200</span>) {</span>
<span id="cb5-3">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(seed)) {</span>
<span id="cb5-4">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">set.seed</span>(seed)</span>
<span id="cb5-5">  }</span>
<span id="cb5-6">  dat <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tibble</span>(</span>
<span id="cb5-7">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">id =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>n,</span>
<span id="cb5-8">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sample</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, n, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">replace =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>),</span>
<span id="cb5-9">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">c =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rnorm</span>(n),</span>
<span id="cb5-10">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">1</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rnorm</span>(n, x <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> c <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.1</span>),</span>
<span id="cb5-11">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">2</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rnorm</span>(n, x <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> c <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.2</span>),</span>
<span id="cb5-12">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">3</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rnorm</span>(n, x <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> c <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.3</span>),</span>
<span id="cb5-13">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">4</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rnorm</span>(n, x <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> c <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.4</span>)</span>
<span id="cb5-14">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb5-15">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">factor</span>(x, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">labels =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Old"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Young"</span>))) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb5-16">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_longer</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">1</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">4</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb5-17">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as.integer</span>(name))</span>
<span id="cb5-18">}</span>
<span id="cb5-19">dat <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">generate_data</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>)</span></code></pre></div></div>
</div>
<p>I’ll try to show this plot with much fewer visual symbols, and hopefully retain most of the information.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb6-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(ggnewscale)</span>
<span id="cb6-2">dat <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb6-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rename</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Time =</span> name, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Value =</span> value) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb6-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(Time, Value)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb6-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_color_viridis_c</span>(</span>
<span id="cb6-6">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Covariate"</span></span>
<span id="cb6-7">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb6-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_point</span>(</span>
<span id="cb6-9">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">col =</span> c, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">group =</span> x),</span>
<span id="cb6-10">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,</span>
<span id="cb6-11">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">alpha =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">75</span>,</span>
<span id="cb6-12">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">position =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">position_quasirandom</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">width =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">05</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dodge.width =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">35</span>)</span>
<span id="cb6-13">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb6-14">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">new_scale_color</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb6-15">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_color_brewer</span>(</span>
<span id="cb6-16">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Group"</span>,</span>
<span id="cb6-17">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">palette =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Set1"</span></span>
<span id="cb6-18">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb6-19">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">stat_pointinterval</span>(</span>
<span id="cb6-20">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">color =</span> x),</span>
<span id="cb6-21">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">interval_size_range =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(.<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>),</span>
<span id="cb6-22">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">position =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">position_dodge</span>(.<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">075</span>)</span>
<span id="cb6-23">  )</span></code></pre></div></div>
<div class="cell-output-display">
<div id="fig-ggdistrain-new" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-ggdistrain-new-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/raincloud-plot-alt/index_files/figure-html/fig-ggdistrain-new-1.png" class="img-fluid figure-img" width="672">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-ggdistrain-new-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;6: An attempt at a more complicated “raincloud” plot using ggnewscale and ggdist.
</figcaption>
</figure>
</div>
</div>
</div>
<p>Hmm. Figure&nbsp;6 doesn’t quite work visually as I’d like it to. I think it would be really nice if the jittered points were jittered only on their respective sides.</p>
<p>I might come back to this later to see if I can improve on this design.</p>
<p>The takeaway, though, is that the ggrain package provides really nice figures out of the box. If we want to do more complex figures kind of like these, the ggdist and ggbeeswarm plots can create compelling alternatives.</p>



</section>

<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-bibliography"><h2 class="anchored quarto-appendix-heading">References</h2><div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="0">
<div id="ref-ggbeeswarm" class="csl-entry">
Clarke, Erik, and Scott Sherrill-Mix. 2017. <em>Ggbeeswarm: Categorical Scatter (Violin Point) Plots</em>. <a href="https://CRAN.R-project.org/package=ggbeeswarm">https://CRAN.R-project.org/package=ggbeeswarm</a>.
</div>
<div id="ref-ggrain" class="csl-entry">
Judd, Nicholas, Jordy van Langen, and Rogier Kievit. 2022. <em>Ggrain: A Rainclouds Geom for Ggplot2</em>. <a href="https://github.com/njudd/ggrain">https://github.com/njudd/ggrain</a>.
</div>
<div id="ref-ggdist" class="csl-entry">
Kay, Matthew. 2022. <em><span class="nocase">ggdist</span>: Visualizations of Distributions and Uncertainty</em>. <a href="https://doi.org/10.5281/zenodo.3879620">https://doi.org/10.5281/zenodo.3879620</a>.
</div>
<div id="ref-vipor" class="csl-entry">
Sherrill-Mix, Scott, and Erik Clarke. 2017. <em>Vipor: Plot Categorical Data Using Quasirandom Noise and Density Estimates</em>. <a href="https://CRAN.R-project.org/package=vipor">https://CRAN.R-project.org/package=vipor</a>.
</div>
</div></section><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{vuorre2022,
  author = {Vuorre, Matti},
  title = {Some Alternatives to Raincloud Plots},
  date = {2022-12-06},
  url = {https://vuorre.com/posts/raincloud-plot-alt/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-vuorre2022" class="csl-entry quarto-appendix-citeas">
Vuorre, Matti. 2022. <span>“Some Alternatives to Raincloud
Plots.”</span> December 6, 2022. <a href="https://vuorre.com/posts/raincloud-plot-alt/">https://vuorre.com/posts/raincloud-plot-alt/</a>.
</div></div></section></div> ]]></description>
  <category>r</category>
  <category>visualization</category>
  <guid>https://vuorre.com/posts/raincloud-plot-alt/</guid>
  <pubDate>Mon, 05 Dec 2022 23:00:00 GMT</pubDate>
</item>
<item>
  <title>How to run R remotely</title>
  <dc:creator>Matti Vuorre</dc:creator>
  <link>https://vuorre.com/posts/remote-r/</link>
  <description><![CDATA[ 





<p>I recently saw an <a href="https://fosstodon.org/@michaelflynn/109445977522188850">interesting question</a> on Mastodon: <strong>How can I run R remotely?</strong></p>
<p>It’s often the case that we write code and manuscripts on computers that are not powerful enough to run complicated data analyses. Or maybe it is not possible for us to leave the computer running alone for a long time. Sometimes we’re lucky enough to have a powerful desktop computer somewhere that could run those tasks with much greater speed, but we either don’t like using them (maybe they have windows installed!) or we don’t have physical access to them. In those cases, we’d like to run R on the fast computer but also access it remotely from other computers. In this entry, I show how to create remote R sessions with ease using RStudio Server, Docker (optionally), and Tailscale.</p>
<p>In order to best solve this problem, we need to recognize two main scenarios:</p>
<ol type="1">
<li>The laptop (or “slow” computer) and desktop (or “fast” computer) are on the same local network, or</li>
<li>The laptop and desktop are not on the same local network.</li>
</ol>
<p>We discuss these options in turn. The answers turn out to be very similar, but when the computers are not on the same network, the solution is just a wee bit more complicated.</p>
<section id="what-you-need" class="level1">
<h1>What you need</h1>
<p>These solutions work on Linux, MacOS, and even Windows operating systems. The slow and fast computers can have any combination of these.</p>
<p>You also need to use RStudio for the solutions discussed here. It turns out that doing this in VS Code can be even easier because of its superb remote session support. I’ll add the VS Code writeup later, once my transition from RStudio to VS Code is complete <span class="emoji" data-emoji="wink">😉</span>.</p>
<p>The first thing you need to set up is an RStudio Server instance on the fast computer. If your fast computer is running Linux, <a href="https://posit.co/download/rstudio-server/">this is trivial</a>.</p>
<p>If your fast computer has either MacOS or Windows, you will need to set up the RStudio Server instance using Docker. This is really easy, and we begin here.</p>
</section>
<section id="rstudio-server" class="level1">
<h1>RStudio Server</h1>
<p>We are first going to install RStudio Server on the fast computer. You cannot run RStudio Server on MacOS or Windows, but we can easily fire one up using <a href="https://www.docker.com/">Docker</a>. First, using your fast computer, head over to the Docker website and download the Docker desktop app. Then start it and make sure it is running (you will have a menu bar or taskbar Docker button to indicate that it’s running).</p>
<p>Then start a terminal session, and use it to start a <a href="https://rocker-project.org/">rocker/rstudio</a> container:</p>
<div class="aside callout callout-style-default callout-note no-icon callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>The rocker images don’t yet work on M1 Macs. If you, like me, are using an M1 Mac, you can replace <code>rocker/rstudio</code> with <code>amoselb/rstudio-m1</code>.</p>
</div>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">docker</span> run <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--rm</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-ti</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-v</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">pwd</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">)</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>/work:/home/rstudio <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-e</span> PASSWORD=yourpassword <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-p</span> 8787:8787 rocker/rstudio</span></code></pre></div></div>
<p>This creates a directory in your current working directory called <code>work</code>, and lets the Docker container access files therein (inside the container, the path is <code>/home/rstudio</code> where RStudio Server sessions typically start). This way whatever files you save inside Docker will remain in your disk, and you can use / edit those outside the container as well. (Thanks Kristoffer for pointing this critical point to me!)</p>
<p>Now your fast computer is running an RStudio Server session. You can verify this by opening a browser tab on the fast computer, and typing <code>localhost:8787</code> in the address bar. You should see the RStudio Server login window pop up (Figure&nbsp;1).</p>
<div id="fig-login" class="quarto-float quarto-figure quarto-figure-center anchored" alt="RStudio Server login window.">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-login-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/remote-r/images/login.png" class="img-fluid figure-img" alt="RStudio Server login window.">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-login-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;1: RStudio Server login window.
</figcaption>
</figure>
</div>
<p>Then use <code>rstudio</code> as the Username, and <code>yourpassword</code> as the password. You’ll then have a fully functioning RStudio session in your browser (Figure&nbsp;2).</p>
<div id="fig-rstudio-server" class="quarto-float quarto-figure quarto-figure-center anchored" alt="RStudio Server.">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-rstudio-server-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/remote-r/images/rstudio-server.png" class="img-fluid figure-img" alt="RStudio Server.">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-rstudio-server-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;2: RStudio Server–RStudio in the browser!.
</figcaption>
</figure>
</div>
<p>Notice how it runs on Ubuntu, although my computer is an M1 Mac. Pretty cool, huh.</p>
<p>Ok, so how do we connect to this from other computers. We might now either want to connect from another computer on the same network, or on another network. Let’s start with the first.</p>
</section>
<section id="computers-on-the-same-local-network" class="level1">
<h1>Computers on the same local network</h1>
<p>This is pretty easy! First, find your fast computer’s local IP address. There’s many ways to find this and you could for example query it in the terminal:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb2-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">ipconfig</span> getifaddr en0</span></code></pre></div></div>
<p>Your local IP address will be something like <code>192.168.0.123</code>. My fast computer currently runs on <code>192.168.0.155</code>, and I’ll use it below.</p>
<p>Fire up a browser in your slow computer, and navigate to <code>192.168.0.155:8787</code>. I’m using my phone as the slow computer here, and after logging in with the same credentials as above, I see Figure&nbsp;3.</p>
<div id="fig-rstudio-remote-1" class="quarto-float quarto-figure quarto-figure-center anchored" alt="RStudio remote session on my phone.">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-rstudio-remote-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/remote-r/images/phone-1.jpg" class="img-fluid figure-img" alt="RStudio remote session on my phone.">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-rstudio-remote-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;3: RStudio remote session on my phone.
</figcaption>
</figure>
</div>
<p>It really isn’t more difficult than that.</p>
</section>
<section id="computers-on-different-networks" class="level1">
<h1>Computers on different networks</h1>
<p>OK, so you still have RStudio Server running on your fast computer, but maybe it’s at work and you are now at home with your slow computer and a cold beer. How to connect? There’s many ways to do this, but here we will use <a href="https://tailscale.com/">Tailscale</a>.</p>
<p>First, create a Tailscale account, and then install it on both computers. (OK so I guess you still need to be physically near both machines at this point <span class="emoji" data-emoji="smile">😄</span>. [Unless you already have e.g.&nbsp;SSH access to the fast computer, in which case you can install Tailscale in the terminal.]) Make sure Tailscale is running on both and that they are signed in to the same Tailscale account. You can follow the <a href="https://tailscale.com/kb/1017/install/">official instructions</a>. It really is quite easy and that’s why I use Tailscale and not some other SSH or VPN based solution.</p>
<p>Then, you can head to <a href="https://login.tailscale.com/admin/machines" class="uri">https://login.tailscale.com/admin/machines</a> (on either computer). It will show you all the machines that you’ve connected to Tailscale (Figure&nbsp;4), whether they are active or not.</p>
<div id="fig-tailscale" class="quarto-float quarto-figure quarto-figure-center anchored" alt="Tailscale admin panel.">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-tailscale-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/remote-r/images/tailscale-1.png" class="img-fluid figure-img" alt="Tailscale admin panel.">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-tailscale-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;4: Tailscale admin panel.
</figcaption>
</figure>
</div>
<p>Now you can connect between your computers wherever the machines might be, provided that they are connected to the internet and Tailscale. My fast computer’s Tailscale IP, redacted in Figure&nbsp;4, is <code>xxx.xxx.x.xx</code>. So now I go home with my slow computer, and then use the browser to connect to <code>xxx.xxx.x.xx:8787</code>, and I see Figure&nbsp;3 again.</p>
<p>I can then use RStudio (server) running on my fast computer on any of my other computers (as clients), by using the Tailscale IP address.</p>
</section>
<section id="conclusion" class="level1">
<h1>Conclusion</h1>
<p>If it is possible for you to have a powerful computer always connected to the internet, you can make a persistent RStudio computing platform out of it with RStudio Server. You can then use Tailscale to connect to it very easily from anywhere in the world.</p>
<p>I hope that was as helpful to you as it has been for me <span class="emoji" data-emoji="smile">😄</span>. If something didn’t work for you, comments are open below.</p>


</section>

<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{vuorre2022,
  author = {Vuorre, Matti},
  title = {How to Run {R} Remotely},
  date = {2022-12-03},
  url = {https://vuorre.com/posts/remote-r/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-vuorre2022" class="csl-entry quarto-appendix-citeas">
Vuorre, Matti. 2022. <span>“How to Run R Remotely.”</span> December 3,
2022. <a href="https://vuorre.com/posts/remote-r/">https://vuorre.com/posts/remote-r/</a>.
</div></div></section></div> ]]></description>
  <category>r</category>
  <category>workflow</category>
  <guid>https://vuorre.com/posts/remote-r/</guid>
  <pubDate>Fri, 02 Dec 2022 23:00:00 GMT</pubDate>
  <media:content url="https://vuorre.com/posts/remote-r/images/christina-wocintechchat-com-glRqyWJgUeY-unsplash.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Website favicons with hexSticker</title>
  <dc:creator>Matti Vuorre</dc:creator>
  <link>https://vuorre.com/posts/hexsticker-favicon/</link>
  <description><![CDATA[ 





<p>My website needed a new <a href="https://en.wikipedia.org/wiki/Favicon">favicon</a>, and I decided to create one with R. I quite like the look of those hexagonal R package logos, and it turns out there’s an R package that helps you make those: <a href="https://github.com/GuangchuangYu/hexSticker">hexSticker</a>.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(hexSticker)</span>
<span id="cb1-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(viridis)</span>
<span id="cb1-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(here)</span>
<span id="cb1-4"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(tidyverse)</span></code></pre></div></div>
</div>
<p>First, the design. I really like the simple symmetry of a (normal) density curve. So I based my design on that. To make it a bit more interesting, I decided to stack a small number of them on top of another, each with its own color. Here’s how I went about doing that.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb2-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># A consistent color palette for the image</span></span>
<span id="cb2-2">palette <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">viridis</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>)</span>
<span id="cb2-3"></span>
<span id="cb2-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Create data for the density curves</span></span>
<span id="cb2-5">d <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">expand_grid</span>(</span>
<span id="cb2-6">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">m =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>,</span>
<span id="cb2-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">nesting</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">s =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.5</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.5</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.5</span>), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n1 =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">factor</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)),</span>
<span id="cb2-8">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">seq</span>(<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">by =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">01</span>)</span>
<span id="cb2-9">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb2-10">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dnorm</span>(x, m, s))</span>
<span id="cb2-11"></span>
<span id="cb2-12"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Plot said data</span></span>
<span id="cb2-13">p <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> d <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb2-14">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">col =</span> n1, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">group =</span> n1)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb2-15">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># What's a better / more overused color scale? Nothing.</span></span>
<span id="cb2-16">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_color_viridis_d</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">begin =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">end =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">direction =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb2-17">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Adjust the empty areas between plot geoms and axis limits</span></span>
<span id="cb2-18">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_y_continuous</span>(</span>
<span id="cb2-19">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">expand =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">expansion</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(.<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">35</span>, .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span>))</span>
<span id="cb2-20">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb2-21">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># These curves go up</span></span>
<span id="cb2-22">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_line</span>(</span>
<span id="cb2-23">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> x, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> y),</span>
<span id="cb2-24">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">linewidth =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>,</span>
<span id="cb2-25">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">position =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">position_stack</span>()</span>
<span id="cb2-26">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb2-27">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Make the plot otherwise completely empty</span></span>
<span id="cb2-28">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme_void</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb2-29">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme_transparent</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb2-30">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme</span>(</span>
<span id="cb2-31">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">legend.position =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"none"</span></span>
<span id="cb2-32">  )</span></code></pre></div></div>
</div>
<p>Can you imagine from above what it’ll look like 😉? You’ll see in a bit. Next I needed to pass the plot object throught <code>hexSticker::sticker()</code> to create the hexagonal sticker plot. There are quite a few arguments to that function and it took me a few minutes to figure out what they do. I basically wanted to fill the hexagonal area with the plot, and add a URL to the corner.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb3-1">outfile <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tempfile</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">fileext =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">".png"</span>)</span>
<span id="cb3-2">s <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sticker</span>(</span>
<span id="cb3-3">  p,</span>
<span id="cb3-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">s_x =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,</span>
<span id="cb3-5">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">s_y =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,</span>
<span id="cb3-6">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">s_width =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.9</span>,</span>
<span id="cb3-7">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">s_height =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.7</span>,</span>
<span id="cb3-8">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">h_fill =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"black"</span>,</span>
<span id="cb3-9">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">h_color =</span> palette[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>],</span>
<span id="cb3-10">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">package =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span>,</span>
<span id="cb3-11">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">url =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sometimes I R"</span>,</span>
<span id="cb3-12">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">u_color =</span> palette[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>],</span>
<span id="cb3-13">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">u_size =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">24</span>,</span>
<span id="cb3-14">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpi =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">800</span>,</span>
<span id="cb3-15">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">filename =</span> outfile</span>
<span id="cb3-16">)</span></code></pre></div></div>
<div class="cell-output cell-output-stderr">
<pre><code>Warning: `aes_()` was deprecated in ggplot2 3.0.0.
ℹ Please use tidy evaluation idioms with `aes()`
ℹ The deprecated feature was likely used in the hexSticker package.
  Please report the issue at
  &lt;https://github.com/GuangchuangYu/hexSticker/issues&gt;.</code></pre>
</div>
<div class="cell-output cell-output-stderr">
<pre><code>Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use `linewidth` instead.
ℹ The deprecated feature was likely used in the hexSticker package.
  Please report the issue at
  &lt;https://github.com/GuangchuangYu/hexSticker/issues&gt;.</code></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb6-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">plot</span>(s)</span></code></pre></div></div>
<div class="cell-output-display">
<div id="fig-favicon" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-favicon-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/hexsticker-favicon/index_files/figure-html/fig-favicon-1.png" class="img-fluid figure-img" width="672">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-favicon-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;1: Sticker made with ggplot2 and hexSticker.
</figcaption>
</figure>
</div>
</div>
</div>
<p>The more I kept tweaking this, the more it started to look like a tropical fish swimming towards me. Only the eyes are missing! When printed in RStudio or here in the html output of a rmarkdown/quarto document, the margins are oddly large. But the output file looks just as it should, and is now both the logo (top-left corner) and favicon (browser tab) of this website.</p>



<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{vuorre2022,
  author = {Vuorre, Matti},
  title = {Website Favicons with {hexSticker}},
  date = {2022-06-29},
  url = {https://vuorre.com/posts/hexsticker-favicon/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-vuorre2022" class="csl-entry quarto-appendix-citeas">
Vuorre, Matti. 2022. <span>“Website Favicons with hexSticker.”</span>
June 29, 2022. <a href="https://vuorre.com/posts/hexsticker-favicon/">https://vuorre.com/posts/hexsticker-favicon/</a>.
</div></div></section></div> ]]></description>
  <category>r</category>
  <guid>https://vuorre.com/posts/hexsticker-favicon/</guid>
  <pubDate>Tue, 28 Jun 2022 22:00:00 GMT</pubDate>
  <media:content url="https://vuorre.com/posts/hexsticker-favicon/index_files/figure-html/fig-favicon-1.png" medium="image" type="image/png" height="103" width="144"/>
</item>
<item>
  <title>Easy notifications from R</title>
  <dc:creator>Matti Vuorre</dc:creator>
  <link>https://vuorre.com/posts/easy-notifications-from-r/</link>
  <description><![CDATA[ 





<p>R can be a pretty slow tool. So it would be good to know when an expensive computation has ended. One way to do that is to have R send a notification to your phone when it is done. Here, I’ll show how to do that easily with <a href="https://ntfy.sh">ntfy</a>.</p>
<section id="download-ntfy.sh" class="level2">
<h2 class="anchored" data-anchor-id="download-ntfy.sh">Download ntfy.sh</h2>
<p>Go to your app store (iOS/Android) and download the ntfy app.</p>
</section>
<section id="subscribe-to-a-topic" class="level2">
<h2 class="anchored" data-anchor-id="subscribe-to-a-topic">Subscribe to a topic</h2>
<p>Open the app on your phone and <a href="https://ntfy.sh/docs/subscribe/phone/">subscribe to a topic</a>. Just type in a name that’s both memorable and not likely to already be used by someone else. I use <code>vuorre-r-notifications</code>.</p>
<p><img src="https://vuorre.com/posts/easy-notifications-from-r/images/subscribe.jpeg" class="img-fluid" alt="Subscribing to vuorre-r-notifications on ntfy.sh"></p>
</section>
<section id="send-notifications" class="level2">
<h2 class="anchored" data-anchor-id="send-notifications">Send notifications</h2>
<p>You can now include variations of <code>system("curl -d 'Notification text' ntfy.sh/vuorre-r-notifications")</code> in your R code. For example, to send a notification after a long running code</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Long running code here</span></span>
<span id="cb1-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Sys.sleep</span>(.<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Sleep for .1 second</span></span>
<span id="cb1-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Send notification</span></span>
<span id="cb1-4"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">system</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"curl -d 'Woke up after .1 second nap!' ntfy.sh/vuorre-r-notifications"</span>)</span></code></pre></div></div>
</div>
<p>You’ll get this notification on your phone:</p>
<p><img src="https://vuorre.com/posts/easy-notifications-from-r/images/notification.jpeg" class="img-fluid" alt="Notification received on phone"></p>
<p>This is really useful when you have simulations (mcmc or otherwise 😉) that take a long time, and you’d like to act as soon as they are done. Have fun!</p>


</section>

<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{vuorre2022,
  author = {Vuorre, Matti},
  title = {Easy Notifications from {R}},
  date = {2022-06-15},
  url = {https://vuorre.com/posts/easy-notifications-from-r/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-vuorre2022" class="csl-entry quarto-appendix-citeas">
Vuorre, Matti. 2022. <span>“Easy Notifications from R.”</span> June 15,
2022. <a href="https://vuorre.com/posts/easy-notifications-from-r/">https://vuorre.com/posts/easy-notifications-from-r/</a>.
</div></div></section></div> ]]></description>
  <category>r</category>
  <category>workflow</category>
  <guid>https://vuorre.com/posts/easy-notifications-from-r/</guid>
  <pubDate>Tue, 14 Jun 2022 22:00:00 GMT</pubDate>
</item>
<item>
  <title>How to calculate contrasts from a fitted brms model</title>
  <dc:creator>Matti Vuorre</dc:creator>
  <link>https://vuorre.com/posts/how-to-calculate-contrasts-from-a-fitted-brms-model/</link>
  <description><![CDATA[ 





<p><a href="https://cran.rstudio.com/web/packages/brms/">brms</a> (Bayesian Regression Models using Stan) is an <a href="https://cran.rstudio.com/">R</a> package that allows fitting complex (multilevel, multivariate, mixture, …) statistical models with straightforward R modeling syntax, while using <a href="https://mc-stan.org/">Stan</a> for bayesian inference under the hood. You will find many uses of that package on this blog. I am particularly fond of brms’ helper functions for post-processing (visualizing, summarizing, etc) the fitted models. In this post, I will show how to calculate and visualize arbitrary contrasts (aka “(general linear) hypothesis tests”) with brms, with full uncertainty estimates.</p>
<section id="models-and-contrasts" class="level2">
<h2 class="anchored" data-anchor-id="models-and-contrasts">Models and contrasts</h2>
<p>Here, we will discuss linear models, which regress an outcome variable on a weighted combination of predictors, while allowing the weights to vary across individuals (hierarchical linear regression). After fitting the model, you will have estimates of the weights (“beta weights”, or simply regression parameters) that typically consist of an intercept (estimated level of outcome variable when all predictors are zero) and slopes, which indicate how the outcome variable changes as function of one-unit changes of the predictors, when other predictors are at 0.</p>
<p>However, we are often interested in further questions (contrasts, “general linear hypothesis tests”). For example, your model output may report one group’s change over time, and the difference of that slope between groups, but you are particularly interested in the other group’s slope. To find that slope, you’d need to calculate an additional contrast from your model. This is also commonly called “probing interactions” or sometimes “post hoc testing”.</p>
<section id="example-data" class="level3">
<h3 class="anchored" data-anchor-id="example-data">Example data</h3>
<p>To make this concrete, let’s consider a hypothetical example data set from <a href="http://intensivelongitudinal.com/ch4/ch4index.html">Bolger and Laurenceau (2013)</a>: Two groups’ (<code>treatment</code>: 0/1) self-reported <code>intimacy</code> was tracked over 16 days (<code>time</code>). The dataset contains data from a total of 50 (simulated) individuals.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(tidyverse)</span>
<span id="cb1-2"></span>
<span id="cb1-3">tmpfile <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tempfile</span>()</span>
<span id="cb1-4"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">download.file</span>(</span>
<span id="cb1-5">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"http://www.intensivelongitudinal.com/ch4/ch4R.zip"</span>,</span>
<span id="cb1-6">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">destfile =</span> tmpfile</span>
<span id="cb1-7">)</span>
<span id="cb1-8">dat <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">read_csv</span>(tmpfile) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb1-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">id =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as.factor</span>(id), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">treatment =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as.factor</span>(treatment))</span></code></pre></div></div>
</div>
</section>
<section id="model" class="level3">
<h3 class="anchored" data-anchor-id="model">Model</h3>
<p>We might be interested in how the two groups’ feelings of intimacy developed over time, and how their temporal trajectories of intimacy differed. To be more specific, we have three questions:</p>
<p>Q1: How did intimacy develop over time for group 0? Q2: How did intimacy develop over time for group 1? Q3: How different were these two time-courses?</p>
<p>To answer, we model intimacy as a function of time, treatment, and their interactions. The hierarchical model includes varying intercepts and effects of time across participants.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb2-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(brms)</span>
<span id="cb2-2">fit <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">brm</span>(</span>
<span id="cb2-3">  intimacy <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> time <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> treatment <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> (time <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> id),</span>
<span id="cb2-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">family =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">gaussian</span>(),</span>
<span id="cb2-5">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> dat,</span>
<span id="cb2-6">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">file =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"intimacymodel"</span></span>
<span id="cb2-7">)</span></code></pre></div></div>
</div>
</section>
<section id="interpreting-the-models-parameters" class="level3">
<h3 class="anchored" data-anchor-id="interpreting-the-models-parameters">Interpreting the model’s parameters</h3>
<p>Let’s then answer our questions by looking at the model’s summary, and interpreting the estimated population-level parameters (the posterior means and standard deviations).</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb3-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(kableExtra)</span>
<span id="cb3-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">posterior_summary</span>(fit, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">pars =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"b_"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb3-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_tibble</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">rownames =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Parameter"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb3-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">caption =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Summary of the Intimacy model's parameters"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb3-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable_styling</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">full_width =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stderr">
<pre><code>Warning: Argument 'pars' is deprecated. Please use 'variable' instead.</code></pre>
</div>
<div class="cell-output-display">
<table class="table caption-top table-sm table-striped small">
<caption>Summary of the Intimacy model's parameters</caption>
<thead>
<tr class="header">
<th style="text-align: left;" data-quarto-table-cell-role="th">Parameter</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">Estimate</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">Est.Error</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">Q2.5</th>
<th style="text-align: right;" data-quarto-table-cell-role="th">Q97.5</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">b_Intercept</td>
<td style="text-align: right;">2.89</td>
<td style="text-align: right;">0.21</td>
<td style="text-align: right;">2.49</td>
<td style="text-align: right;">3.31</td>
</tr>
<tr class="even">
<td style="text-align: left;">b_time</td>
<td style="text-align: right;">0.05</td>
<td style="text-align: right;">0.02</td>
<td style="text-align: right;">0.00</td>
<td style="text-align: right;">0.10</td>
</tr>
<tr class="odd">
<td style="text-align: left;">b_treatment1</td>
<td style="text-align: right;">-0.06</td>
<td style="text-align: right;">0.30</td>
<td style="text-align: right;">-0.65</td>
<td style="text-align: right;">0.51</td>
</tr>
<tr class="even">
<td style="text-align: left;">b_time:treatment1</td>
<td style="text-align: right;">0.06</td>
<td style="text-align: right;">0.03</td>
<td style="text-align: right;">0.00</td>
<td style="text-align: right;">0.13</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>The first lesson is that most models are simply too complex to interpret by just looking at the numerical parameter estimates. Therefore, we always draw figures to help us interpret what the model thinks is going on. The figure below shows example participants’ data (left) and the model’s estimated effects on the right.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb5-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(patchwork)</span>
<span id="cb5-2">pa <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> dat <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb5-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(id <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%in%</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">25</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">28</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb5-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(time, intimacy, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">group =</span> id, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">col =</span> treatment)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb5-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_y_continuous</span>(</span>
<span id="cb5-6">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Intimacy"</span>,</span>
<span id="cb5-7">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">limits =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>),</span>
<span id="cb5-8">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">breaks =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pretty_breaks</span>()</span>
<span id="cb5-9">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb5-10">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">labs</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Time"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb5-11">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_line</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">25</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb5-12">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_point</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">shape =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">21</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">fill =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"white"</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stderr">
<pre><code>Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use `linewidth` instead.</code></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb7-1">pb <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">conditional_effects</span>(</span>
<span id="cb7-2">  fit,</span>
<span id="cb7-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">effects =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"time:treatment"</span></span>
<span id="cb7-4">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb7-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">plot</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">plot =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb7-6">  .[[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]] <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb7-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_y_continuous</span>(</span>
<span id="cb7-8">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Intimacy"</span>,</span>
<span id="cb7-9">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">limits =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>),</span>
<span id="cb7-10">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">breaks =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pretty_breaks</span>()</span>
<span id="cb7-11">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb7-12">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">labs</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Time"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb7-13">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">axis.title.y =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">element_blank</span>(), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">legend.position =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"none"</span>)</span>
<span id="cb7-14">(pa <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> pb) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span></span>
<span id="cb7-15">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme</span>(</span>
<span id="cb7-16">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">legend.position =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"bottom"</span>,</span>
<span id="cb7-17">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">aspect.ratio =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span>
<span id="cb7-18">  )</span></code></pre></div></div>
<div class="cell-output cell-output-stderr">
<pre><code>Warning: Removed 1 row containing missing values or values outside the scale range
(`geom_point()`).</code></pre>
</div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://vuorre.com/posts/how-to-calculate-contrasts-from-a-fitted-brms-model/index_files/figure-html/figure-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>Then, we can begin interpreting the parameters. First, the intercept indicates estimated intimacy when time and treatment were at their respective baseline levels (0). It is always easiest to interpret the parameters by eyeballing the right panel of the figure above and trying to connect the numbers to the figure. This estimate is the left-most point of the red line.</p>
<p>The estimated <code>time</code> parameter describes the slope of the red line (Q1); <code>treatment1</code> is the difference between the two lines at time zero (Q3). However, we cannot immediately answer Q2 from the parameters, although we can see that the slope of the blue line is about 0.05 + 0.06. To get the answer to Q2, or more generally, any contrast or “general linear hypothesis test” from a brms model, we can use the <code>hypothesis()</code> method.</p>
</section>
</section>
<section id="hypothesis" class="level2">
<h2 class="anchored" data-anchor-id="hypothesis">hypothesis()</h2>
<p><code>hypothesis()</code> truly is an underappreciated method of the brms package. It can be very useful in probing complex models. It allows us to calculate, visualize, and summarize, with full uncertainty estimates, any transformation of the model’s parameters. These transformations are often called “contrasts” or “general linear hypothesis tests”. But really, they are just transformations of the joint posterior distribution of the model’s parameters.</p>
<p>To answer Q2, then, we encode our question into a combination of the models parameters:</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb9-1">q2 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">q2 =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"time + time:treatment1 = 0"</span>)</span></code></pre></div></div>
</div>
<p>The slope of group 1 is calculated from the model’s parameters by adding the slope of group 0 (<code>time</code>) and the interaction term <code>time:treatment1</code>. <code>= 0</code> indicates that we are interested in contrasting the resulting estimate the zero (“testing against zero” or even “testing the null hypothesis”). Then, we pass this named string to <code>hypothesis()</code>, and observe the results.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb10-1">q2_answer <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">hypothesis</span>(fit, q2)</span>
<span id="cb10-2">q2_answer</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Hypothesis Tests for class b:
  Hypothesis Estimate Est.Error CI.Lower CI.Upper Evid.Ratio Post.Prob Star
1         q2     0.11      0.02     0.06     0.16         NA        NA    *
---
'CI': 90%-CI for one-sided and 95%-CI for two-sided hypotheses.
'*': For one-sided hypotheses, the posterior probability exceeds 95%;
for two-sided hypotheses, the value tested against lies outside the 95%-CI.
Posterior probabilities of point hypotheses assume equal prior probabilities.</code></pre>
</div>
</div>
<p>The output indicates that the estimated answer to Question 2 is 0.11 with a standard error of 0.02. I will return to <code>Evid.Ratio</code> and <code>Post.Prob</code> shortly.</p>
<p>The results can also be visualized.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb12-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">plot</span>(q2_answer)</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://vuorre.com/posts/how-to-calculate-contrasts-from-a-fitted-brms-model/index_files/figure-html/unnamed-chunk-5-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>That figure shows the (samples from the) posterior distribution of the answer to Question 2.</p>
</section>
<section id="more-contrasts" class="level2">
<h2 class="anchored" data-anchor-id="more-contrasts">More contrasts</h2>
<p>With <code>hypothesis()</code> you can answer many additional questions about your model, beyond the parameter estimates. To illustrate, say we are interested in the groups’ difference in intimacy at the end of the study (day 15; Question 4). (The difference at time 0 is reported by the group parameter.)</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb13-1">q4 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">q4 =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"treatment1 + time:treatment1 * 15 = 0"</span>)</span>
<span id="cb13-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">hypothesis</span>(fit, q4)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Hypothesis Tests for class b:
  Hypothesis Estimate Est.Error CI.Lower CI.Upper Evid.Ratio Post.Prob Star
1         q4     0.87       0.4      0.1     1.66         NA        NA    *
---
'CI': 90%-CI for one-sided and 95%-CI for two-sided hypotheses.
'*': For one-sided hypotheses, the posterior probability exceeds 95%;
for two-sided hypotheses, the value tested against lies outside the 95%-CI.
Posterior probabilities of point hypotheses assume equal prior probabilities.</code></pre>
</div>
</div>
<section id="directional-hypotheses-and-posterior-probabilities" class="level3">
<h3 class="anchored" data-anchor-id="directional-hypotheses-and-posterior-probabilities">Directional hypotheses and posterior probabilities</h3>
<p>We can also ask for directional questions. For example, what is the probability that group 0’s slope is greater than 0 (Q5)?</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb15-1">q5 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">q5 =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"time &gt; 0"</span>)</span>
<span id="cb15-2">q5_answer <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">hypothesis</span>(fit, q5)</span>
<span id="cb15-3">q5_answer</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Hypothesis Tests for class b:
  Hypothesis Estimate Est.Error CI.Lower CI.Upper Evid.Ratio Post.Prob Star
1         q5     0.05      0.02     0.01     0.09      57.82      0.98    *
---
'CI': 90%-CI for one-sided and 95%-CI for two-sided hypotheses.
'*': For one-sided hypotheses, the posterior probability exceeds 95%;
for two-sided hypotheses, the value tested against lies outside the 95%-CI.
Posterior probabilities of point hypotheses assume equal prior probabilities.</code></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb17-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">plot</span>(q5_answer)</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://vuorre.com/posts/how-to-calculate-contrasts-from-a-fitted-brms-model/index_files/figure-html/unnamed-chunk-7-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>We can now return to <code>Evid.Ratio</code> and <code>Post.Prob</code>: The latter indicates the posterior probability that the parameter of interest is greater than zero (<code>&gt; 0</code>). (More accurately, the proportion of samples from the posterior that are greater than zero.) That should correspond to what you see in the figure above. The former is the ratio of the hypothesis and its complement (the ratio of <code>time &gt; 0</code> and <code>time &lt; 0</code>). I find posterior probabilities more intuitive than evidence ratios, but they both return essentially the same information. Perhaps of interest, with uniform priors, posterior probabilities will exactly correspond (numerically, not conceptually) to frequentist one-sided p-values (<a href="https://www.ejwagenmakers.com/2017/MarsmanWagenmakers2017ThreeInsights.pdf">Marsman &amp; Wagenmakers, 2017</a>).</p>
</section>
<section id="multiple-hypotheses" class="level3">
<h3 class="anchored" data-anchor-id="multiple-hypotheses">Multiple hypotheses</h3>
<p>You can evaluate multiple hypotheses in one function call:</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb18-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">hypothesis</span>(fit, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(q2, q4, q5))</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Hypothesis Tests for class b:
  Hypothesis Estimate Est.Error CI.Lower CI.Upper Evid.Ratio Post.Prob Star
1         q2     0.11      0.02     0.06     0.16         NA        NA    *
2         q4     0.87      0.40     0.10     1.66         NA        NA    *
3         q5     0.05      0.02     0.01     0.09      57.82      0.98    *
---
'CI': 90%-CI for one-sided and 95%-CI for two-sided hypotheses.
'*': For one-sided hypotheses, the posterior probability exceeds 95%;
for two-sided hypotheses, the value tested against lies outside the 95%-CI.
Posterior probabilities of point hypotheses assume equal prior probabilities.</code></pre>
</div>
</div>
</section>
<section id="hierarchical-hypotheses" class="level3">
<h3 class="anchored" data-anchor-id="hierarchical-hypotheses">Hierarchical hypotheses</h3>
<p>Up to this point, we have “tested” the model’s population level effects. (Parameters for the average person. “Fixed effects.”) Because we fit a hierarchical model with varying intercepts and slopes of time, we can also test the individual specific parameters. For example, we can look at every individual’s estimated intercept (intimacy at time 0):</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb20-1">x <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">hypothesis</span>(fit, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Intercept = 0"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">group =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"id"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">scope =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"coef"</span>)</span></code></pre></div></div>
</div>
<p>In the above, we asked for the results of the hypothesis test, split by group <code>id</code> (which is the grouping factor in our hierarchical model), and indicated <code>coef</code> as the scope. The latter means that the estimates are the subject-specific deviations with the fixed effect added, as opposed to <code>ranef</code>, which are zero-centered.</p>
<p>The results of this question would be a bit too much information to print on screen, so instead we will draw a figure:</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb21-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Results of hypothesis() in a data.frame</span></span>
<span id="cb21-2">x<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>hypothesis <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb21-3">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Obtain group indicators from original data</span></span>
<span id="cb21-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">left_join</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">distinct</span>(dat, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Group =</span> id, treatment)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb21-5">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Rename Group to id and reverse order for figure</span></span>
<span id="cb21-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">id =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">factor</span>(Group, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">levels =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rev</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">50</span>))) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb21-7">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Draw a forest plot with ggplot2</span></span>
<span id="cb21-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(Estimate, id, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">col =</span> treatment)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb21-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_errorbarh</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">xmin =</span> CI.Lower, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">xmax =</span> CI.Upper)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb21-10">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_point</span>()</span></code></pre></div></div>
<div class="cell-output cell-output-stderr">
<pre><code>Warning: `geom_errobarh()` was deprecated in ggplot2 4.0.0.
ℹ Please use the `orientation` argument of `geom_errorbar()` instead.</code></pre>
</div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://vuorre.com/posts/how-to-calculate-contrasts-from-a-fitted-brms-model/index_files/figure-html/unnamed-chunk-10-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
</section>
</section>
<section id="conclusion" class="level2">
<h2 class="anchored" data-anchor-id="conclusion">Conclusion</h2>
<p>When you find that you have a brms model whose parameters don’t quite answer your questions, <code>hypothesis()</code> will probably give you the answer. For more advanced post-processing of your models, I recommend taking a look at the <a href="http://mjskay.github.io/tidybayes/">tidybayes</a> package.</p>


</section>

<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{vuorre2020,
  author = {Vuorre, Matti},
  title = {How to Calculate Contrasts from a Fitted Brms Model},
  date = {2020-02-06},
  url = {https://vuorre.com/posts/how-to-calculate-contrasts-from-a-fitted-brms-model/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-vuorre2020" class="csl-entry quarto-appendix-citeas">
Vuorre, Matti. 2020. <span>“How to Calculate Contrasts from a Fitted
Brms Model.”</span> February 6, 2020. <a href="https://vuorre.com/posts/how-to-calculate-contrasts-from-a-fitted-brms-model/">https://vuorre.com/posts/how-to-calculate-contrasts-from-a-fitted-brms-model/</a>.
</div></div></section></div> ]]></description>
  <category>r</category>
  <category>statistics</category>
  <guid>https://vuorre.com/posts/how-to-calculate-contrasts-from-a-fitted-brms-model/</guid>
  <pubDate>Wed, 05 Feb 2020 23:00:00 GMT</pubDate>
  <media:content url="https://vuorre.com/posts/how-to-calculate-contrasts-from-a-fitted-brms-model/index_files/figure-html/figure-1.png" medium="image" type="image/png" height="103" width="144"/>
</item>
<item>
  <title>How to analyze visual analog (slider) scale data?</title>
  <dc:creator>Matti Vuorre</dc:creator>
  <link>https://vuorre.com/posts/analyze-analog-scale-ratings-with-zero-one-inflated-beta-models/</link>
  <description><![CDATA[ 





<section id="introduction" class="level1">
<h1>Introduction</h1>
<p>In psychological experiments, subjective responses are often collected using two types of response scales: ordinal and visual analog scales. These scales are unlikely to provide normally distributed data. However, researchers often analyze responses from these scales with models that assume normality of the data.<sup>1</sup></p>
<p>Ordinal scales, of which binary ratings are a special case, provide ordinal data and are thus better analyzed using ordinal models <span class="citation" data-cites="BurknerOrdinalRegressionModels2019 LiddellAnalyzingOrdinalData2018">(Bürkner and Vuorre 2019; Liddell and Kruschke 2018)</span>.</p>
<p>Analog scales, also known as slider scales, are also unlikely to provide normally distributed responses because the scale is bounded at the low and high ends. These responses also tend to be skewed. It is common for slider responses to bunch at either end of the slider scale, potentially making the deviation from normality more severe.</p>
<p>For example, Figure&nbsp;1 shows a slider scale in action. (I found this random example with a simple internet search at <a href="https://blog.surveyhero.com/2018/09/03/new-question-type-slider/" class="uri">https://blog.surveyhero.com/2018/09/03/new-question-type-slider/</a>). In experiments using slider scales, subjects are typically instructed to use their mouse to drag a response indicator along a horizontal line, and/or click with a mouse on a point of the scale that matches their subjective impression. Sometimes these responses are provided on paper, where subjects are asked to bisect a line at a point that matches their subjective feeling (e.g.&nbsp;halfway between “Leisure” and “Money” if they are subjectively equally important.)</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">include_graphics</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"vas.gif"</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<div id="fig-vas" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-vas-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/analyze-analog-scale-ratings-with-zero-one-inflated-beta-models/vas.gif" class="img-fluid figure-img">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-vas-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;1: Example slider scale from https://blog.surveyhero.com/2018/09/03/new-question-type-slider/
</figcaption>
</figure>
</div>
</div>
</div>
<p>These analog ratings are sometimes thought to be ‘better’ than discrete ordinal ratings (Likert item responses) because of the greater resolution of the slider scale. The scale’s resolution is limited only by the resolution of the monitor: For example, if the rating scale is 100 pixels wide, there are 100 possible values for the ratings. It is not unthinkable that such ratings can be considered continuous between the low and high endpoints. However, they are often not well described by the normal distribution.</p>
<section id="normal-model-of-slider-ratings" class="level2">
<h2 class="anchored" data-anchor-id="normal-model-of-slider-ratings">Normal model of slider ratings</h2>
<p>Consider Figure&nbsp;2. This figure shows 200 simulated ratings on a [0, 1] slider scale (meaning that any value between 0 and 1, inclusive of the endpoints, is possible). I have also superimposed a blue curve of the best-fitting normal density on the histogram. The two most notable non-normal features of these data are that they are bounded at 0 and 1 where the data appears to “bunch”, and (possibly) skewed. Of course, these data were simulated; experience with slider scales tells me, however, that this histogram is not unrepresentative of such ratings.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb2-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">set.seed</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">99</span>)</span>
<span id="cb2-2">rzoib <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1e4</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">alpha =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">gamma =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">45</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mu =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">phi =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>) {</span>
<span id="cb2-3">  a <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> mu <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> phi</span>
<span id="cb2-4">  b <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> mu) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> phi</span>
<span id="cb2-5">  y <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">vector</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"numeric"</span>, n)</span>
<span id="cb2-6">  y <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ifelse</span>(</span>
<span id="cb2-7">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rbinom</span>(n, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, alpha),</span>
<span id="cb2-8">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rbinom</span>(n, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, gamma),</span>
<span id="cb2-9">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rbeta</span>(n, a, b)</span>
<span id="cb2-10">  )</span>
<span id="cb2-11">  y</span>
<span id="cb2-12">}</span>
<span id="cb2-13">dat <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tibble</span>(</span>
<span id="cb2-14">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">200</span>,</span>
<span id="cb2-15">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,</span>
<span id="cb2-16">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">alpha =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,</span>
<span id="cb2-17">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">gamma =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</span>,</span>
<span id="cb2-18">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mu =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>,</span>
<span id="cb2-19">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">phi =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span></span>
<span id="cb2-20">)</span>
<span id="cb2-21">dat <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> dat <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb2-22">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rowwise</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb2-23">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Rating =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rzoib</span>(n, alpha, gamma, mu, phi)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb2-24">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ungroup</span>()</span>
<span id="cb2-25">p1 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> dat <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb2-26">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(Rating)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb2-27">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_histogram</span>(</span>
<span id="cb2-28">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">stat</span>(ncount)),</span>
<span id="cb2-29">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">col =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"white"</span>,</span>
<span id="cb2-30">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">fill =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"black"</span>,</span>
<span id="cb2-31">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">bins =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>,</span>
<span id="cb2-32">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb2-33">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_y_continuous</span>(</span>
<span id="cb2-34">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">expand =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">expansion</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mult =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">05</span>))</span>
<span id="cb2-35">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb2-36">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_x_continuous</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">breaks =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pretty_breaks</span>()) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb2-37">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme</span>(</span>
<span id="cb2-38">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">axis.title.y =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">element_blank</span>(),</span>
<span id="cb2-39">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">axis.text.y =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">element_blank</span>(),</span>
<span id="cb2-40">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">axis.ticks.y =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">element_blank</span>()</span>
<span id="cb2-41">  )</span>
<span id="cb2-42"></span>
<span id="cb2-43">sims <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tibble</span>(</span>
<span id="cb2-44">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">seq</span>(<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.8</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">by =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">01</span>),</span>
<span id="cb2-45">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dnorm</span>(x, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mean</span>(dat<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>Rating), <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sd</span>(dat<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>Rating))</span>
<span id="cb2-46">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb2-47">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> y <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">max</span>(y))</span>
<span id="cb2-48"></span>
<span id="cb2-49">p2 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> p1 <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb2-50">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_line</span>(</span>
<span id="cb2-51">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> sims,</span>
<span id="cb2-52">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> x, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> y),</span>
<span id="cb2-53">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">col =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dodgerblue"</span>,</span>
<span id="cb2-54">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span>
<span id="cb2-55">  )</span></code></pre></div></div>
<div class="cell-output cell-output-stderr">
<pre><code>Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use `linewidth` instead.</code></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb4-1">p2</span></code></pre></div></div>
<div class="cell-output cell-output-stderr">
<pre><code>Warning: `stat(ncount)` was deprecated in ggplot2 3.4.0.
ℹ Please use `after_stat(ncount)` instead.</code></pre>
</div>
<div class="cell-output-display">
<div id="fig-simulate-example" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-simulate-example-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/analyze-analog-scale-ratings-with-zero-one-inflated-beta-models/index_files/figure-html/fig-simulate-example-1.png" class="img-fluid figure-img" width="480">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-simulate-example-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;2: Histogram of 200 simulated slider scale ratings, with a superimposed best-fitting density curve from a normal distribution.
</figcaption>
</figure>
</div>
</div>
</div>
<p>While the height of the blue curve is not comparable to the heights of the bars (one represents a density, the other counts of observations in rating bins), it should be apparent that features of the rating scale data make the blue normal curve a poor representation of the data.</p>
<p>First, the skew apparent in the data is not captured by the normal density curve. Second, and perhaps more important, the blue curve does not respect the 0 and 1 boundaries of the slider scale data.</p>
<p>Focus on this latter point: We can see that the blue curve assigns density to areas outside the possible values: The model predicts impossible values with alarming frequency. Second, the boundary values 0.0 and 1.0 do not receive any special treatment under the normal model, but we can see that the data are bunched at the boundaries. The great frequency of responses at 0.0 and 1.0 leads to large prediction errors from the normal model of these data.</p>
<p>In other words, (simulated) subjects tend to give many extreme ratings. This is especially apparent in the low end of the rating scale, where the continuous spread of scores tapers off, but then there is a large spike of ratings at zero. The normal model misses these features of the data, and may therefore lead to unrepresentative estimates of the data generating process, and even erroneous conclusions.</p>
</section>
<section id="toward-a-better-model" class="level2">
<h2 class="anchored" data-anchor-id="toward-a-better-model">Toward a better model</h2>
<p>More generally, if your goal is to predict cognition and behavior <span class="citation" data-cites="YarkoniChoosingPredictionExplanation2017">(Yarkoni and Westfall 2017)</span>, a model that is obviously a poor representation of your data—in terms of having such a poor predictive utility—should not be your first choice for data analysis.</p>
<p>Admittedly, the data in Figure&nbsp;2 were simulated, and it remains an empirical question as to how common these features are in real data, and how severe these issues are to normal models (t-test, ANOVA, correlation, etc.).</p>
<p>Nevertheless, it would be desirable to have an accessible data-analytic model for slider scale data, whose assumption better match observed features of the data. Here, I introduce one such model—the zero-one-inflated beta (ZOIB) model—and show how it can be applied to real data using the R package brms <span class="citation" data-cites="BurknerBrmsPackageBayesian2017">(Bürkner 2017)</span>. I also compare this model to standard analyses of slider scale data and conclude that the ZOIB can provide more detailed and accurate inferences from data than its conventional counterparts.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb6-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># https://imgflip.com/i/2u6fgk</span></span>
<span id="cb6-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">include_graphics</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"zoidberg.jpg"</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://vuorre.com/posts/analyze-analog-scale-ratings-with-zero-one-inflated-beta-models/zoidberg.jpg" class="img-fluid figure-img" width="240"></p>
<figcaption>Dr.&nbsp;John A. Zoidberg thinks you should try a ZOIB model on your slider scale data.</figcaption>
</figure>
</div>
</div>
</div>
</section>
</section>
<section id="the-zero-one-inflated-beta-model" class="level1">
<h1>The zero-one-inflated beta model</h1>
<p>Above, we established—rather informally—that normal models may be less than optimal for slider scale data. Of course, no model is the <em>correct</em> model of such data, but it would be desirable to use a model that best represents the data under study.</p>
<p>The model for analysis of slider scale data discussed here has been called the “zero-one-inflated beta” model, or ZOIB <span class="citation" data-cites="LiuZoibPackageBayesian2015">(Liu and Kong 2015)</span>. It is a model of data in the closed [0, 1] interval, and has two components: A beta distribution for responses in the closed (0, 1) interval, and a bernoulli distribution for the binary {0, 1} responses. Under this model, predictors can affect either or both the continuous and binary responses, the proportion of binary responses, or the spread of the continuous ratings.</p>
<p>To understand ZOIB, let’s start with a closer look at the theoretical beta density.</p>
<section id="the-beta-distribution" class="level2">
<h2 class="anchored" data-anchor-id="the-beta-distribution">The beta distribution</h2>
<p>The beta distribution used in beta regression <span class="citation" data-cites="FerrariBetaRegressionModelling2004">(Ferrari and Cribari-Neto 2004)</span> is a model of data in the open (0, 1) interval. (i.e.&nbsp;all values from 0 to 1, but not 0 and 1 themselves, are permitted.)</p>
<p>The beta distribution typically has two parameters, which in R are called <code>shape1</code> and <code>shape2</code>. Together, they determine the location, spread, and skew of the distribution. Four example beta densities are shown in Figure&nbsp;3. Using R’s <code>dbeta()</code>, I drew four curves corresponding to beta densities with different <code>shape1</code> and <code>2</code> parameters.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb7-1">tmp <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tibble</span>(</span>
<span id="cb7-2">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">seq</span>(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.001</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.999</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">by =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">001</span>),</span>
<span id="cb7-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbeta</span>(x, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">shape1 =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">shape2 =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>),</span>
<span id="cb7-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbeta</span>(x, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">shape1 =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">shape2 =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>),</span>
<span id="cb7-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbeta</span>(x, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">shape1 =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">shape2 =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>),</span>
<span id="cb7-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbeta</span>(x, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">shape1 =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">35</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">shape2 =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">35</span>)</span>
<span id="cb7-7">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb7-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">gather</span>(Distribution, Density, <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>x) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb7-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Function =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fct_inorder</span>(Distribution))</span>
<span id="cb7-10"></span>
<span id="cb7-11">tmp <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb7-12">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(x, Density)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb7-13">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_line</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.4</span>, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">col =</span> Function)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb7-14">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_x_continuous</span>(</span>
<span id="cb7-15">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">breaks =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pretty_breaks</span>(),</span>
<span id="cb7-16">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">expand =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">expansion</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mult =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.005</span>)</span>
<span id="cb7-17">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb7-18">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_y_continuous</span>(</span>
<span id="cb7-19">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">breaks =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pretty_breaks</span>(),</span>
<span id="cb7-20">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">expand =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">expansion</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mult =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.005</span>, .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">01</span>))</span>
<span id="cb7-21">  )</span></code></pre></div></div>
<div class="cell-output-display">
<div id="fig-beta-distributions" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-beta-distributions-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/analyze-analog-scale-ratings-with-zero-one-inflated-beta-models/index_files/figure-html/fig-beta-distributions-1.png" class="img-fluid figure-img" width="672">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-beta-distributions-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;3: Four examples of the beta density, corresponding to different shape parameters.
</figcaption>
</figure>
</div>
</div>
</div>
<p>This default parameterization is useful, for example, as a prior distribution for proportions: The <code>shape1</code> and <code>shape2</code> parameters can define the prior number of zeros and ones, respectively. For example, in the above figure, <code>dbeta(x, shape1 = 1, shape2 = 1)</code> results in a uniform prior over proportions, because the prior zeros and ones are 1 each.</p>
<p>However, for our purposes, it is more useful to parameterize the beta distribution with a mean and a precision. To convert the former parameterization to mean (which we’ll call <img src="https://latex.codecogs.com/png.latex?%5Cmu"> (mu)) and precision (<img src="https://latex.codecogs.com/png.latex?%5Cphi"> (phi)), the following formulas can be used</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cbegin%7Balign*%7D%0A%5Cmbox%7Bshape1%7D%20&amp;=%20%5Cmu%20%5Cphi%20%5C%5C%0A%5Cmbox%7Bshape2%7D%20&amp;=%20(1%20-%20%5Cmu)%5Cphi%0A%5Cend%7Balign*%7D"></p>
<p>(This parameterization is provided in R in the PropBeta functions from the extraDist package, which calls the precision parameter, or <img src="https://latex.codecogs.com/png.latex?%5Cphi">, <code>size</code>.) Redrawing the figure from above with this parameterization using the <code>dprop()</code> function, we get the figure below.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb8-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(extraDistr)</span>
<span id="cb8-2">tmp <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tibble</span>(</span>
<span id="cb8-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">seq</span>(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.001</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.999</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">by =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">001</span>),</span>
<span id="cb8-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dprop</span>(x, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mean =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>),</span>
<span id="cb8-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dprop</span>(x, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mean =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>),</span>
<span id="cb8-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dprop</span>(x, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mean =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>),</span>
<span id="cb8-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dprop</span>(x, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">70</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mean =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>)</span>
<span id="cb8-8">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb8-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">gather</span>(Distribution, Density, <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>x) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb8-10">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Function =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fct_inorder</span>(Distribution))</span>
<span id="cb8-11"></span>
<span id="cb8-12">tmp <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb8-13">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(x, Density)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb8-14">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_line</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.4</span>, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">col =</span> Function)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb8-15">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_x_continuous</span>(</span>
<span id="cb8-16">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">breaks =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pretty_breaks</span>(),</span>
<span id="cb8-17">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">expand =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">expansion</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mult =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.005</span>)</span>
<span id="cb8-18">    ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb8-19">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_y_continuous</span>(</span>
<span id="cb8-20">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">breaks =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pretty_breaks</span>(),</span>
<span id="cb8-21">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">expand =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">expansion</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mult =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.005</span>, .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">01</span>))</span>
<span id="cb8-22">    )</span></code></pre></div></div>
<div class="cell-output-display">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://vuorre.com/posts/analyze-analog-scale-ratings-with-zero-one-inflated-beta-models/index_files/figure-html/beta-reparameterized-distributions-1.png" class="img-fluid figure-img" width="672"></p>
<figcaption>Four examples of the reparameterized beta density (<code>dprop()</code>).</figcaption>
</figure>
</div>
</div>
</div>
<p>Shown above are four density functions of the beta family, whose precision and mean are varied. The first (red line) is a beta distribution with precision = 1, and mean = 0.5. It results in a uniform distribution. If a subject gave random slider scale responses, they might look much like this distribution (any rating is equally probably as any other rating).</p>
<p>The second beta distribution (green line) has precision 10, and mean 0.2. It is heavily skewed to the right. The third distribution (teal line) has precision 10, and a mean of 0.9. The fourth one, most similar to a normal distribution, has precision 70 and mean 0.50 (purple line).</p>
<p>In beta regression, this family of distributions is used to model observations, and covariates can have effects on both the mean and precision parameters.</p>
<p>However, beta regression only allows outcomes in the open (0, 1) interval. We know that slider scales often result in a bunching of values at the boundaries, and these boundary values might be informative of the participants’ cognition and behavior. To handle these extreme values, we can add a zero-one inflation process to the beta distribution.</p>
</section>
<section id="zero-one-inflation" class="level2">
<h2 class="anchored" data-anchor-id="zero-one-inflation">Zero-one inflation</h2>
<p>The zero-one-inflated beta (ZOIB) adds a separate discrete process for the {0, 1} values, using two additional parameters. Following convention, we shall call them <img src="https://latex.codecogs.com/png.latex?%5Calpha"> (alpha) and <img src="https://latex.codecogs.com/png.latex?%5Cgamma"> (gamma). These parameters describe the probability of an observation being a 0 or 1 (<img src="https://latex.codecogs.com/png.latex?%5Calpha">), and conditional on that, whether the observation was 1 (<img src="https://latex.codecogs.com/png.latex?%5Cgamma">).</p>
<p>In other words, the model of outcomes under ZOIB is described by four parameters. The first is <img src="https://latex.codecogs.com/png.latex?%5Calpha">, the probability that an observation is either 0 or 1. (Thus, <img src="https://latex.codecogs.com/png.latex?1-%5Calpha"> is the probability of a non-boundary observation.) If an observation is not 0 or 1, the datum is described by the beta distribution with some mean <img src="https://latex.codecogs.com/png.latex?%5Cmu"> and precision <img src="https://latex.codecogs.com/png.latex?%5Cphi">. If an observation is 0 or 1, the probability of it being 1 is given by <img src="https://latex.codecogs.com/png.latex?%5Cgamma"> (just like your usual model of binary outcomes, e.g.&nbsp;logistic regression). So you can think of the model as a kind of mixture of beta and logistic regressions, where the <img src="https://latex.codecogs.com/png.latex?%5Calpha"> parameter describes the mixing proportions. The mathematical representation of this model is given in <a href="https://cran.rstudio.com/web/packages/brms/vignettes/brms_families.html#zero-inflated-and-hurdle-models">this vignette</a> <span class="citation" data-cites="BurknerBrmsPackageBayesian2017">(Bürkner 2017)</span>.</p>
<p>To illustrate, I wrote a little function <code>rzoib()</code> that takes these parameters as arguments, and generates <code>n</code> random draws. Here is a histogram of 1k samples from four ZOIB distributions with various combinations of the parameters:</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb9-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">set.seed</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">101</span>)</span>
<span id="cb9-2">tmp <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tibble</span>(</span>
<span id="cb9-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rzoib</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">a =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">g =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">m =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">p =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>),</span>
<span id="cb9-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rzoib</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">a =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">g =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">m =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">p =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>),</span>
<span id="cb9-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rzoib</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">a =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">g =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">m =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">p =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>),</span>
<span id="cb9-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rzoib</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">a =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">g =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">m =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">p =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span>)</span>
<span id="cb9-7">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb9-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">gather</span>(distribution, x) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb9-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">distribution =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fct_inorder</span>(distribution))</span>
<span id="cb9-10"></span>
<span id="cb9-11">tmp <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb9-12">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> x, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">stat</span>(count), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">fill =</span> distribution)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb9-13">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_histogram</span>(</span>
<span id="cb9-14">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">bins =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">50</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">col =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"white"</span></span>
<span id="cb9-15">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb9-16">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_x_continuous</span>(</span>
<span id="cb9-17">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Rating"</span>,</span>
<span id="cb9-18">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">breaks =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pretty_breaks</span>()</span>
<span id="cb9-19">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb9-20">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_y_continuous</span>(</span>
<span id="cb9-21">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Count"</span>,</span>
<span id="cb9-22">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">breaks =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pretty_breaks</span>(),</span>
<span id="cb9-23">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">expand =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">expansion</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mult =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0</span>, .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">02</span>))</span>
<span id="cb9-24">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb9-25">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">facet_wrap</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"distribution"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">scales =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"free_y"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb9-26">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">legend.position =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"none"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">strip.text =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">element_text</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>))</span></code></pre></div></div>
<div class="cell-output-display">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://vuorre.com/posts/analyze-analog-scale-ratings-with-zero-one-inflated-beta-models/index_files/figure-html/zoib-distributions-1.png" class="img-fluid figure-img" width="672"></p>
<figcaption>Four different ZOIB distributions resulting from various combinations of the parameters. (Parameter names are abbreviated; a = alpha, g = gamma, etc.)</figcaption>
</figure>
</div>
</div>
</div>
<p>Take the first (red) one. <img src="https://latex.codecogs.com/png.latex?%5Calpha"> was set to zero, and therefore there are no observations exactly at zero or 1. Because <img src="https://latex.codecogs.com/png.latex?%5Calpha%20=%200">, it doesn’t matter that <img src="https://latex.codecogs.com/png.latex?%5Cgamma"> was set to 0.5. <img src="https://latex.codecogs.com/png.latex?%5Cgamma"> is the conditional one probability, given that the observation was 0 or 1. Therefore, the first histogram only contains draws from a beta distribution with mean = 0.2, and precision = 6.</p>
<p>Next, take a look at the second (green) histogram. Here, <img src="https://latex.codecogs.com/png.latex?%5Calpha%20=%200.1">, so 10% of the observations will be either 0 or 1. Of these 10%, 30% are ones (<img src="https://latex.codecogs.com/png.latex?%5Cgamma%20=%200.3">). The bulk of the distribution, 90%, are draws from a beta distribution with a mean = 0.5, and precision = 3.</p>
<p>The bottom two histograms are two more combinations of the four parameters. Try to understand how their shapes are explained by the specific parameter combinations.</p>
<p>In summary, ZOIB is a reasonable model of slider scale data that can capture their major features, has support for the entire [0, 1] range of data, and does not assign density to impossible values (unlike the normal model). It also has an intuitive way of dealing with the boundary values as a separate process, thus providing more nuanced information about the outcome variable under study.</p>
<p>Next, we discuss a regression model with ZOIB as the data model: We are most interested in how other variables affect or relate to the outcome variables under study (slider scale ratings). By modeling the four parameters of the ZOIB model on predictors, ZOIB regression allows us to do just that.</p>
</section>
</section>
<section id="zoib-regression" class="level1">
<h1>ZOIB regression</h1>
<p>In this example, we examine the ZOIB model in the context of one binary predictor variable (Group A vs B, a “between subjects” manipulation).</p>
<section id="example-data" class="level2">
<h2 class="anchored" data-anchor-id="example-data">Example data</h2>
<p>To illustrate the ZOIB model in action, I simulated a data set of 100 ratings from two groups, A and B. These data are shown in Figure&nbsp;4.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb10-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">set.seed</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">666</span>)</span>
<span id="cb10-2">dat <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tibble</span>(</span>
<span id="cb10-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rbinom</span>(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1e2</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>),</span>
<span id="cb10-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,</span>
<span id="cb10-5">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">alpha =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">25</span>,</span>
<span id="cb10-6">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">gamma =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>,</span>
<span id="cb10-7">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mu =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span>,</span>
<span id="cb10-8">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">phi =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span></span>
<span id="cb10-9">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb10-10">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rowwise</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb10-11">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Rating =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rzoib</span>(n, alpha, gamma, mu, phi)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb10-12">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ungroup</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb10-13">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">group =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">factor</span>(x, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">levels =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">labels =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"B"</span>)))</span>
<span id="cb10-14">dat <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(dat, group, Rating)</span>
<span id="cb10-15">dat <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb10-16">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(group, Rating)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb10-17">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_beeswarm</span>(</span>
<span id="cb10-18">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">shape =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">21</span>,</span>
<span id="cb10-19">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">fill =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"white"</span>,</span>
<span id="cb10-20">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>,</span>
<span id="cb10-21">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">stroke =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>,</span>
<span id="cb10-22">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">alpha =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>,</span>
<span id="cb10-23">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">cex =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span></span>
<span id="cb10-24">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb10-25">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">stat_summary</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">fun.data =</span> mean_cl_boot, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">col =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dodgerblue2"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb10-26">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_y_continuous</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">breaks =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pretty_breaks</span>())</span></code></pre></div></div>
<div class="cell-output-display">
<div id="fig-zoib-example" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-zoib-example-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/analyze-analog-scale-ratings-with-zero-one-inflated-beta-models/index_files/figure-html/fig-zoib-example-1.png" class="img-fluid figure-img" width="288">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-zoib-example-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;4: Simulated data set of two group’s slider scale ratings, with means and bootstrapped 95% CIs in blue. The ratings are jittered horizontally to reveal overlapping data points.
</figcaption>
</figure>
</div>
</div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb11-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(</span>
<span id="cb11-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head</span>(dat),</span>
<span id="cb11-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>,</span>
<span id="cb11-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">caption =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"First six rows of example data of two groups' slider scale ratings."</span></span>
<span id="cb11-5">)</span></code></pre></div></div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb12-1">t.ex <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">t.test</span>(Rating <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> group, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> dat <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">group =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fct_rev</span>(group)))</span>
<span id="cb12-2">t.ex.out <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tidy</span>(t.ex) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb12-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate_if</span>(is.numeric, round, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb12-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">glue_data</span>(</span>
<span id="cb12-5">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"B - A = {estimate}, 95%CI = [{conf.low}, {conf.high}], {pvalue(p.value, add_p=T)}"</span></span>
<span id="cb12-6">  )</span>
<span id="cb12-7">w.p <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tidy</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">wilcox.test</span>(Rating <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> group, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> dat))<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>p.value <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb12-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pvalue</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">add_p =</span> T)</span>
<span id="cb12-9">k.p <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tidy</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kruskal.test</span>(Rating <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> group, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> dat))<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>p.value <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb12-10">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pvalue</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">add_p =</span> T)</span></code></pre></div></div>
</div>
<p>We are interested in the extent to which Group A’s ratings differ from Group B’s ratings. It is common practice to address this question with a t-test, treating the ratings as normally distributed within each group. I compared the two groups’ means with a t-test: The difference was not statistically significant (B - A = 0.06, 95%CI = [-0.07, 0.2], p=0.340). I’ve also heard that you can do something called a Mann-Whitney U test, or a Kruskal-Wallis test when you have a categorical predictor and don’t want to assume a parametric form for your outcomes. I tried those as well. Neither of these nonparametric tests were significant (p=0.226; p=0.225). I therefore concluded that I was unable to reject the null hypothesis that Group A and Group B’s population means are not different.</p>
<p>But as can be seen from Figure&nbsp;2, the normal model makes unreasonable assumptions about these ratings. We see in Figure&nbsp;4 that there are many non-normal features in this example data set; e.g.&nbsp;many values are bunched at 0.0 and 1.0. Let’s fit the ZOIB model on these data, and see if our conclusions differ. Spoiler alert: they do.</p>
</section>
<section id="the-model" class="level2">
<h2 class="anchored" data-anchor-id="the-model">The model</h2>
<p>We will model the data as ZOIB, and use <code>group</code> as a predictor of the mean and precision of the beta distribution, the zero-one inflation probability <img src="https://latex.codecogs.com/png.latex?%5Calpha">, and the conditional one-inflation probability <img src="https://latex.codecogs.com/png.latex?%5Cgamma">. In other words, in this model <code>group</code> may affect the mean and/or precision of the assumed beta distribution of the continuous ratings (0, 1), and/or the probability with which a binary rating is given, and/or the probability that a binary rating is 1. How do we estimate this model?</p>
<p>It might not come as a surprise that we estimate the model with bayesian methods, using the R package brms <span class="citation" data-cites="BurknerBrmsPackageBayesian2017">(Bürkner 2017)</span>. Previously, I have discussed how to estimate signal detection theoretic models, “robust models”, and other multilevel models using this package. I’m a big fan of brms because of its modeling flexibility and post-processing functions: With concise syntax, you can fit a wide variety of possibly nonlinear, multivariate, and multilevel models, and analyze and visualize the models’ results.</p>
<p>Let’s load the package, and start building our model.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb13-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(brms)</span></code></pre></div></div>
</div>
<p>The R formula syntax allows a concise representation of regression models in the form of <code>response ~ predictors</code>. For a simple normal (i.e.&nbsp;gaussian) model of the mean of <code>Ratings</code> as a function of <code>group</code>, you could write <code>Ratings ~ group, family = gaussian</code>. However, we want to predict the four parameters of the ZOIB model, and so will need to expand this notation.</p>
<p>The brms package allows modeling more than one parameter of an outcome distribution. Specifically, we want to predict so-called “distributional parameters”, and <code>bf()</code> allows predicting them in their own formulas. Implicitly, <code>Ratings ~ group</code> means that you want to model the <em>mean</em> of <code>Ratings</code> on <code>group</code>. Therefore, to model <img src="https://latex.codecogs.com/png.latex?%5Cphi">, <img src="https://latex.codecogs.com/png.latex?%5Calpha">, and <img src="https://latex.codecogs.com/png.latex?%5Cgamma">, we will give them their own regression formulas within a call to <code>bf()</code>:</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb14-1">zoib_model <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bf</span>(</span>
<span id="cb14-2">  Rating <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> group,</span>
<span id="cb14-3">  phi <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> group,</span>
<span id="cb14-4">  zoi <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> group,</span>
<span id="cb14-5">  coi <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> group,</span>
<span id="cb14-6">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">family =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">zero_one_inflated_beta</span>()</span>
<span id="cb14-7">)</span></code></pre></div></div>
</div>
<p>The four sub-models of our model are, in order of appearance: 1. the model of the beta distribution’s mean (read, “predict <code>Rating</code>’s mean from <code>group</code>”). Then, 2. the model of <code>phi</code>; the beta distribution’s precision. 3. <code>zoi</code> is the zero-one inflation (<img src="https://latex.codecogs.com/png.latex?%5Calpha">); that is, we model the probability of a binary rating as a function of <code>group</code>. 4. <code>coi</code> is the conditional one-inflation: Given that a response was {0, 1}, the probability of it being 1 is modelled on <code>group</code>.</p>
<p>As is usual in R’s formula syntax, the intercepts of each of these formulas are implicitly included. (To make intercepts explicit, use e.g.&nbsp;<code>Rating ~ 1 + group</code>.) Therefore, this model will have 8 parameters; the intercepts are Group A’s mean, <code>phi</code>, <code>zoi</code>, and <code>coi</code>. Then, there will be a Group B parameter for each of them, indicating the extent to which the parameters differ for Group B versus Group A.</p>
<p>If <code>group</code> has a positive effect on (the mean of) <code>Rating</code>, we may conclude that the continuous rating’s mean differs as function of Group. On the other hand, if <code>coi</code> is affected by <code>group</code>, Group has an effect on the binary {0, 1} ratings. If group has no effects on any of the parameters, we throw up our hands and design a new study.</p>
<p>Finally, we specified <code>family = zero_one_inflated_beta()</code>. Just like logistic regression, ZOIB regression is a type of generalized linear model. Therefore, each distributional parameter is modeled through a link function. The mean, zoi, and coi parameters are modeled through a logit link function. Phi is modeled through a log link function. These link functions can be changed by giving named arguments to <code>zero_one_inflated_beta()</code>. It is important to keep in mind the specific link functions, we will need them when interpreting the model’s parameters.</p>
<p>To estimate this model, we pass the resulting <code>zoib_model</code> to <code>brm()</code>, with a data frame from the current R environment, 4 CPU cores for speed, and a file argument to save the resulting model to disk. The last two arguments are optional.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb15-1">fit <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">brm</span>(</span>
<span id="cb15-2">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">formula =</span> zoib_model,</span>
<span id="cb15-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> dat,</span>
<span id="cb15-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">cores =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>,</span>
<span id="cb15-5">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">file =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"brm-zoib"</span></span>
<span id="cb15-6">)</span></code></pre></div></div>
</div>
<p>brms estimates the regression model using bayesian methods: It will return random draws from the parameters’ posterior distribution. It takes less than a minute to draw samples from this model. Let’s then interpret the estimated parameters (i.e.&nbsp;the numerical summaries of the posterior distribution):</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb16-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summary</span>(fit)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code> Family: zero_one_inflated_beta 
  Links: mu = logit; phi = log; zoi = logit; coi = logit 
Formula: Rating ~ group 
         phi ~ group
         zoi ~ group
         coi ~ group
   Data: dat (Number of observations: 100) 
  Draws: 4 chains, each with iter = 2000; warmup = 1000; thin = 1;
         total post-warmup draws = 4000

Regression Coefficients:
              Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
Intercept         0.33      0.16     0.01     0.63 1.00     6253     3166
phi_Intercept     1.49      0.24     1.01     1.94 1.00     5683     3040
zoi_Intercept    -0.79      0.32    -1.44    -0.18 1.00     6968     2958
coi_Intercept     0.62      0.57    -0.46     1.79 1.00     6660     2940
groupB            0.91      0.21     0.52     1.33 1.00     5658     2983
phi_groupB        0.49      0.33    -0.16     1.14 1.00     5273     3223
zoi_groupB        0.08      0.43    -0.76     0.91 1.00     6631     2955
coi_groupB       -0.86      0.75    -2.36     0.58 1.00     7174     2930

Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).</code></pre>
</div>
</div>
<p>First, the summary of this model prints a paragraph of information about the model, such as the outcome family (ZOIB), link functions, etc. The regression coefficients are found under the “Population-Level Effects:” header. The columns of this section are “Estimate”, the posterior mean or point estimate of the parameter. “Est.Error”, the posterior standard deviation, or so called standard error of the parameter. Then, the lower and upper limit of the 95% Credible Interval. The two last columns are diagnostics of the model fitting procedure.</p>
<p>The first four rows of this describe the parameters for the baseline group (Group A). <code>Intercept</code> is the logit-transformed mean of the beta distribution for Group A’s ratings (the subset of ratings that were (0, 1)). Next, <code>phi_Intercept</code> describes the precision of the beta distribution fitted to Group A’s slider responses, on the scale of the (log) link function. <code>zoi_Intercept</code> is the zero or one inflation of Group A’s data, on the logit scale. <code>coi_Intercept</code> is the conditional one inflation; out of the 0 or 1 ratings in Group A’s data, describing the proportion of ones (out of the 0/1 responses)?</p>
<p>These parameters are described on the link scale, so for each of them, we can use the inverse link function to transform them to the response scale. Precision (<code>phi_Intercept</code>) was modeled on the log scale. Therefore, we can convert it back to the original scale by exponentiating. For the other parameters, which were modeled on the logit scale, we can use the inverse, which is <code>plogis()</code>.</p>
<p>However, before converting the parameters, it is important to note that the estimates displayed above are summaries (means, quantiles) of the posterior draws of the parameters on the link function scale. Therefore, we cannot simply convert the summaries. Instead, we must transform each of the posterior samples, and then re-calculate the summaries. The following code accomplishes this “transform-then-summarize” procedure for each of the four parameters:</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb18-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">posterior_samples</span>(fit, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">pars =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"b_"</span>)[, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>] <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb18-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate_at</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"b_phi_Intercept"</span>), exp) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb18-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate_at</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">vars</span>(<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"b_phi_Intercept"</span>), plogis) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb18-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">posterior_summary</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb18-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as.data.frame</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb18-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rownames_to_column</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Parameter"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb18-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stderr">
<pre><code>Warning: Method 'posterior_samples' is deprecated. Please see ?as_draws for recommended alternatives.</code></pre>
</div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">Parameter</th>
<th style="text-align: right;">Estimate</th>
<th style="text-align: right;">Est.Error</th>
<th style="text-align: right;">Q2.5</th>
<th style="text-align: right;">Q97.5</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">b_Intercept</td>
<td style="text-align: right;">0.58</td>
<td style="text-align: right;">0.04</td>
<td style="text-align: right;">0.50</td>
<td style="text-align: right;">0.65</td>
</tr>
<tr class="even">
<td style="text-align: left;">b_phi_Intercept</td>
<td style="text-align: right;">4.57</td>
<td style="text-align: right;">1.07</td>
<td style="text-align: right;">2.74</td>
<td style="text-align: right;">6.99</td>
</tr>
<tr class="odd">
<td style="text-align: left;">b_zoi_Intercept</td>
<td style="text-align: right;">0.32</td>
<td style="text-align: right;">0.07</td>
<td style="text-align: right;">0.19</td>
<td style="text-align: right;">0.45</td>
</tr>
<tr class="even">
<td style="text-align: left;">b_coi_Intercept</td>
<td style="text-align: right;">0.64</td>
<td style="text-align: right;">0.12</td>
<td style="text-align: right;">0.39</td>
<td style="text-align: right;">0.86</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>We can then interpret these summaries, beginning with <code>b_Intercept</code>. This is the estimated mean of the beta distribution fitted to Group A’s (0, 1) rating scale responses (with its standard error, lower- and upper limits of the 95% CI). Then, <code>b_Phi_Intercept</code> is the precision of the beta distribution. <code>zoi</code> is the zero-one inflation, and <code>coi</code> the conditional one inflation.</p>
<p>To make <code>b_zoi_Intercept</code> concrete, we should be able to compare its posterior mean to the observed proportion of 0/1 values in the data:</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb20-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mean</span>(dat<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>Rating[dat<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>group <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A"</span>] <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%in%</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] 0.311</code></pre>
</div>
</div>
<p>Above we calculated the proportion of zeros and ones in the data set, and found that it matches the estimated value. Similarly, for <code>coi</code>, we can find the corresponding value from the data:</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb22" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb22-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mean</span>(dat<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>Rating[dat<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>group <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> dat<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>Rating <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%in%</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>] <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb22-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] 0.643</code></pre>
</div>
</div>
<p>Let’s get back to the model summary output. The following four parameters are the effects of being in group B on these parameters. Most importantly, <code>groupB</code> is the effect of group B (versus group A) on the mean of the ratings’ assumed beta distribution, in the logit scale. Immediately, we can see that the parameter’s 95% Credible Interval does not include zero. Traditionally, this parameter would be called “significant”; group B’s (0, 1) ratings are on average greater than group A’s.</p>
<p>To transform this effect back to the data scale, we can again use <code>plogis()</code>. However, it is important to keep in mind that the effect’s size on the original scale depends on the intercept, getting smaller as the intercept increases (just like in any other generalized linear model.) The following bit of code transforms this effect and its uncertainty back to the original scale.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb24" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb24-1">h <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"B - A"</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"plogis(Intercept + groupB) = plogis(Intercept)"</span>)</span>
<span id="cb24-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">hypothesis</span>(fit, h)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Hypothesis Tests for class b:
  Hypothesis Estimate Est.Error CI.Lower CI.Upper Evid.Ratio Post.Prob Star
1      B - A     0.19      0.04     0.11     0.29         NA        NA    *
---
'CI': 90%-CI for one-sided and 95%-CI for two-sided hypotheses.
'*': For one-sided hypotheses, the posterior probability exceeds 95%;
for two-sided hypotheses, the value tested against lies outside the 95%-CI.
Posterior probabilities of point hypotheses assume equal prior probabilities.</code></pre>
</div>
</div>
<p>The data were simulated with the <code>rzoib()</code> function, and I set <img src="https://latex.codecogs.com/png.latex?%5Calpha%20=%200.25,%20%5Cgamma%20=%200.5,%20%5Cmu%20=%200.6%20+%200.15%5Cmbox%7BgroupB%7D,%20%5Cphi%20=%205">. Therefore, the results of the t-tests and nonparametric tests were misses; a true effect was missed. On the other hand, the ZOIB regression model detected the true effect of group on the beta distribution’s mean.</p>
<p>Finally, let’s visualize this key finding using the <code>conditional_effects()</code> function from brms.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb26" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb26-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">plot</span>(</span>
<span id="cb26-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">conditional_effects</span>(fit, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpar =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mu"</span>),</span>
<span id="cb26-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">points =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>,</span>
<span id="cb26-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">point_args =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">list</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">width =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">05</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">shape =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb26-5">)</span></code></pre></div></div>
<div class="cell-output-display">
<div id="fig-ex-me" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-ex-me-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/analyze-analog-scale-ratings-with-zero-one-inflated-beta-models/index_files/figure-html/fig-ex-me-1.png" class="img-fluid figure-img" width="672">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-ex-me-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;5: Estimated mu parameters from the example ZOIB fit, as filled points and error bars (95% CIs), with the original data (empty circles).
</figcaption>
</figure>
</div>
</div>
</div>
<p>Comparing Figure&nbsp;5 to Figure&nbsp;4 reveals the fundamental difference of the normal t-test model, and the ZOIB model: The ZOIB regression (Figure&nbsp;5) has found a large difference between the continuous part of the slider ratings’ means because it has treated the data with an appropriate model. By conflating the continuous and binary data, the t-test did not detect this difference.</p>
<p>In conclusion, this example showed that ZOIB results in more informative, and potentially more accurate, inferences from analog scale (“slider”) data. Of course, in this simulation we had the benefit of knowing the true state of matters: The data were simulated from a ZOIB model. Nevertheless, we have reasoned that by respecting the major features of slider scale data, the ZOIB is a more accurate representation of it, and was therefore able to detect a difference where the t-test did not. Next, I put this conjecture to a test by conducting a small simulation study.</p>
</section>
</section>
<section id="simulation-compare-zoib-and-t-test-performances" class="level1">
<h1>Simulation: Compare ZOIB and t-test performances</h1>
<p>To compare the performance of the t-test and ZOIB in a little bit more detail, I conducted a small simulation study. I simulated 100 data sets of 200 ratings from two independent groups, from the ZOIB model (100 ratings per group). I set <img src="https://latex.codecogs.com/png.latex?%5Calpha%20=%200.2,%20%5Cgamma%20=%200.7,%20%5Cmu%20=%200.6%20+%200.1%5Cmbox%7BgroupB%7D,%20%5Cphi%20=%205">; that is, there was a small effect of group on the mean of the beta distribution, and all other parameters were constant across groups. A sample of the resulting data sets is shown in Figure&nbsp;6.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb27" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb27-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Simulate datasets</span></span>
<span id="cb27-2">K <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span></span>
<span id="cb27-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">set.seed</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb27-4">rdata <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">nsubs =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2e2</span>) {</span>
<span id="cb27-5">  dat <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tibble</span>(</span>
<span id="cb27-6">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rbinom</span>(nsubs, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>),</span>
<span id="cb27-7">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,</span>
<span id="cb27-8">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">alpha =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>,</span>
<span id="cb27-9">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">gamma =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>,</span>
<span id="cb27-10">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mu =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,</span>
<span id="cb27-11">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">phi =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span></span>
<span id="cb27-12">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb27-13">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rowwise</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb27-14">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Rating =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rzoib</span>(n, alpha, gamma, mu, phi)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb27-15">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ungroup</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb27-16">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">group =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">factor</span>(x, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">levels =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">labels =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"B"</span>)))</span>
<span id="cb27-17">  dat</span>
<span id="cb27-18">}</span>
<span id="cb27-19">out <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tibble</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">set =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>K, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">nsubs =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1e2</span>)</span>
<span id="cb27-20">dat <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> out <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb27-21">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">map</span>(nsubs, rdata))</span>
<span id="cb27-22"></span>
<span id="cb27-23"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Get ttests</span></span>
<span id="cb27-24">dat <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> dat <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb27-25">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(</span>
<span id="cb27-26">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">ttest =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">map</span>(</span>
<span id="cb27-27">      data,</span>
<span id="cb27-28">      <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">t.test</span>(Rating <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> group, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(., <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">group =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fct_rev</span>(group)))</span>
<span id="cb27-29">    )</span>
<span id="cb27-30">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb27-31">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">ttest.out =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">map</span>(ttest, <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> broom<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tidy</span>(.)))</span></code></pre></div></div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb28" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb28-1">dat <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb28-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sample_n</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb28-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">unnest</span>(data) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb28-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rename</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Group =</span> group) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb28-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(Group, Rating)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb28-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_beeswarm</span>(</span>
<span id="cb28-7">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">shape =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">21</span>,</span>
<span id="cb28-8">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">fill =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"white"</span>,</span>
<span id="cb28-9">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>,</span>
<span id="cb28-10">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">stroke =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>,</span>
<span id="cb28-11">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">cex =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>,</span>
<span id="cb28-12">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">alpha =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span></span>
<span id="cb28-13">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb28-14">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">stat_summary</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">fun.data =</span> mean_cl_boot, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">col =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dodgerblue2"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb28-15">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_y_continuous</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">breaks =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pretty_breaks</span>()) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb28-16">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">facet_wrap</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"set"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">labeller =</span> label_both)</span></code></pre></div></div>
<div class="cell-output-display">
<div id="fig-sim-examplesets" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-sim-examplesets-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/analyze-analog-scale-ratings-with-zero-one-inflated-beta-models/index_files/figure-html/fig-sim-examplesets-1.png" class="img-fluid figure-img" width="672">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-sim-examplesets-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;6: Six randomly selected simulated data sets. Points are individual ratings (jittered to show overlapping points), while blue symbols indicate the means and bootstrapped 95% CIs.
</figcaption>
</figure>
</div>
</div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb29" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb29-1">sig.ttests <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> dat <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb29-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">unnest</span>(ttest.out) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb29-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">sigs =</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sum</span>(p.value <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.05</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> K) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb29-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pull</span>(sigs)</span></code></pre></div></div>
</div>
<p>I first conducted an independent samples, unequal variances t-test on each of the 100 simulated data sets, comparing the two groups’ mean ratings. 35% of these t-tests were significantly positive at the .05 level. That is, the power of the t-test in this simulation was about 35%. (Uncertainty in this value is moderate, because I only did 100 simulation runs.)</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb30" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb30-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Get ZOIB fits</span></span>
<span id="cb30-2"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">file.exists</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"zoib-sims.rds"</span>)) {</span>
<span id="cb30-3">  dat<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>brm <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">vector</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"list"</span>, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">nrow</span>(dat))</span>
<span id="cb30-4">  dat<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>brm[[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]] <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">brm</span>(</span>
<span id="cb30-5">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bf</span>(</span>
<span id="cb30-6">      Rating <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> group,</span>
<span id="cb30-7">      phi <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> group,</span>
<span id="cb30-8">      zoi <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> group,</span>
<span id="cb30-9">      coi <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> group</span>
<span id="cb30-10">    ),</span>
<span id="cb30-11">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">family =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">zero_one_inflated_beta</span>(),</span>
<span id="cb30-12">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> dat<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>data[[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]],</span>
<span id="cb30-13">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">iter =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">800</span>,</span>
<span id="cb30-14">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">cores =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>,</span>
<span id="cb30-15">  )</span>
<span id="cb30-16">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> (i <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">nrow</span>(dat)) {</span>
<span id="cb30-17">    dat<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>brm[[i]] <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">update</span>(</span>
<span id="cb30-18">      dat<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>brm[[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]],</span>
<span id="cb30-19">      <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">newdata =</span> dat<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>data[[i]],</span>
<span id="cb30-20">      <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">cores =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>,</span>
<span id="cb30-21">      <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">iter =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">800</span></span>
<span id="cb30-22">    )</span>
<span id="cb30-23">  }</span>
<span id="cb30-24">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">write_rds</span>(dat, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"zoib-sims.rds"</span>)</span>
<span id="cb30-25">} <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> {</span>
<span id="cb30-26">  dat <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">read_rds</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"zoib-sims.rds"</span>)</span>
<span id="cb30-27">}</span>
<span id="cb30-28"></span>
<span id="cb30-29">brmout <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(x) {</span>
<span id="cb30-30">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">hypothesis</span>(x, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"plogis(Intercept + groupB) = plogis(Intercept)"</span>)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>hypothesis</span>
<span id="cb30-31">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># hypothesis(x, "groupB = 0")$hypothesis</span></span>
<span id="cb30-32">}</span>
<span id="cb30-33">dat <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> dat <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb30-34">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">brm.out =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">map</span>(brm, <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">brmout</span>(.)))</span></code></pre></div></div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb31" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb31-1">sig.brms <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> dat <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb31-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">unnest</span>(brm.out) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb31-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">sigs =</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sum</span>(Star <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"*"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> K) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb31-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pull</span>(sigs)</span></code></pre></div></div>
</div>
<p>I then estimated the ZOIB model for each of the 100 simulated data sets. Statistical significance does not play a role in Bayesian statistics, but to most easily compare the results of these two models, I calculated the proportion of simulations for which the estimated Group on <img src="https://latex.codecogs.com/png.latex?%5Cmu"> effect’s 95% Credible Interval was entirely above zero. If a 95% CI does not include zero, disrespecting the philosophical differences of bayesian and frequentist statistics, I may say that the estimate is “significant”.</p>
<p>This parameter was significantly greater than zero in 65% of the ZOIB models estimated on the same 100 simulated data sets. That is, the power of this model to detect an effect was much greater than the power of the t-test. These results are illustrated in Figure&nbsp;7.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb32" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb32-1">sims_t <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> dat <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb32-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">unnest</span>(ttest.out) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb32-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">reorder</span>(set, estimate), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> estimate, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">col =</span> conf.low <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb32-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_color_brewer</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">palette =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Set1"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb32-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_x_discrete</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Simulated data set"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb32-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_y_continuous</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Difference in means"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb32-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_hline</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">yintercept =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">col =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"green"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb32-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_hline</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">yintercept =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">lty =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb32-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_pointrange</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">ymin =</span> conf.low, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">ymax =</span> conf.high), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">fatten =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb32-10">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme</span>(</span>
<span id="cb32-11">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">legend.position =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"none"</span>,</span>
<span id="cb32-12">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">axis.text.x =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">element_blank</span>()</span>
<span id="cb32-13">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb32-14">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">labs</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">title =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"t-test"</span>)</span>
<span id="cb32-15"></span>
<span id="cb32-16">sims_z <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> dat <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb32-17">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">unnest</span>(brm.out) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb32-18">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">reorder</span>(set, Estimate), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> Estimate, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">col =</span> CI.Lower <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb32-19">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_color_brewer</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">palette =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Set1"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb32-20">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_x_discrete</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Simulated data set"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb32-21">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_y_continuous</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Difference in mu parameters"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb32-22">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_hline</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">yintercept =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">col =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"green"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb32-23">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_hline</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">yintercept =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">lty =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb32-24">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_pointrange</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">ymin =</span> CI.Lower, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">ymax =</span> CI.Upper), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">fatten =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb32-25">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme</span>(</span>
<span id="cb32-26">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">legend.position =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"none"</span>,</span>
<span id="cb32-27">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">axis.text.x =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">element_blank</span>()</span>
<span id="cb32-28">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb32-29">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">labs</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">title =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ZOIB"</span>)</span>
<span id="cb32-30"></span>
<span id="cb32-31">(sims_t <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> sims_z) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span></span>
<span id="cb32-32">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">coord_cartesian</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">ylim =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>.<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span>, .<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>))</span></code></pre></div></div>
<div class="cell-output cell-output-stderr">
<pre><code>Warning: The `fatten` argument of `geom_pointrange()` is deprecated as of ggplot2 4.0.0.
ℹ Please use the `size` aesthetic instead.</code></pre>
</div>
<div class="cell-output-display">
<div id="fig-sims-compare" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-sims-compare-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://vuorre.com/posts/analyze-analog-scale-ratings-with-zero-one-inflated-beta-models/index_files/figure-html/fig-sims-compare-1.png" class="img-fluid figure-img" width="672">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-sims-compare-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;7: Results of the simulation study. Top: the estimated mean difference and 95% CI of the two groups’ ratings, as estimated by a t-test. Red = not statistically significant; blue = statistically significant. The data sets are ordered on the x axis on the estimated mean difference. Bottom: simulation results of the ZOIB model. Same as the top panel, but the estimated parameter is the difference between the two group’s mu parameters of the beta distribution. (I back-transformed the mu parameter from the logit scale to the data scale to make the results numerically more comparable across the t-test and ZOIB models.) In both panels, the horizontal green line indicates the true effect used in the simulations.
</figcaption>
</figure>
</div>
</div>
</div>
<p>As can be seen in this figure, in this particular setup, the t-tests severely underperformed in detecting a true effect when compared to the ZOIB model. Of course, this is to be expected, because the data were generated from the ZOIB model.</p>
<p>Out there in the wild, which of these models is closer to the true data generating process for slider scale ratings? Normal models, or ZOIB? (Or, most likely, some other class of models?) As we have seen, normal models may be poor representations of bounded and skewed slider scale data. It is therefore possible that the routine use of normal models in analyzing slider scale data can result in missing true effects at a rate higher than indicated by conventional power analyses.</p>
</section>
<section id="discussion" class="level1">
<h1>Discussion</h1>
<p>I have not extensively reviewed the performance of the ZOIB model in this blog post. Neither did I analyze real slider scale data. Therefore, I can not and would not recommend exclusively favoring the ZOIB model over normal models for the analysis of slider scale data. However, I can recommend at least trying ZOIB for your own slider scale data, and thinking about what models might best fit your data if they appear non normal.</p>
<section id="limitations" class="level2">
<h2 class="anchored" data-anchor-id="limitations">Limitations</h2>
<p>There are many limitations to the current discussion, and the simulation studies should be considerably expanded to more realistic and variable situations.</p>
<p>One limitation of the ZOIB model might be what I here discussed as its main benefit. ZOIB separates the binary and continuous processes, such that a predictor’s effect on one or both of them are independent in the model. However, it is likely that these two processes are somehow correlated. Thus, ZOIB does not give only one “effect” of a predictor on the ratings, but two, one for the continuous part, and one for the binary. By not getting a single effect, if nothing else, the model is more complex and probably more difficult to analyze and/or explain.</p>
</section>
<section id="further-reading" class="level2">
<h2 class="anchored" data-anchor-id="further-reading">Further reading</h2>
<p>The beta regression model has previously been discussed as a reasonable model of data in the open (0, 1) interval <span class="citation" data-cites="FerrariBetaRegressionModelling2004">(Ferrari and Cribari-Neto 2004)</span>. It’s application in psychological studies has also been discussed by <span class="citation" data-cites="SmithsonBetterLemonSqueezer2006 VerkuilenMixedMixtureRegression2012">(Smithson and Verkuilen 2006; see also Verkuilen and Smithson 2012)</span>. These earlier papers recommended that values at the 0 and 1 boundaries be somehow transformed to make the data suitable for the model, but transforming the data such that a model can be fitted seems like a bad idea.</p>
<p>Mixtures of beta and discrete models were discussed by <span class="citation" data-cites="OspinaInflatedBetaDistributions2008">Ospina and Ferrari (2008)</span>, and an R package for estimation of the ZOIB model was introduced by <span class="citation" data-cites="LiuZoibPackageBayesian2015">Liu and Kong (2015)</span>. <span class="citation" data-cites="LiuReviewComparisonBayesian2018">Liu and Eugenio (2018)</span> found that ZOIB models are better estimated with Bayesian methods than with maximum likelihood methods.</p>
<p>More information about the brms package can be found in <span class="citation" data-cites="BurknerBrmsPackageBayesian2017">Bürkner (2017)</span>, and in the excellent vignettes at <a href="https://cran.rstudio.com/web/packages/brms/" class="uri">https://cran.rstudio.com/web/packages/brms/</a>.</p>



</section>
</section>


<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-bibliography"><h2 class="anchored quarto-appendix-heading">References</h2><div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="0">
<div id="ref-BurknerBrmsPackageBayesian2017" class="csl-entry">
Bürkner, Paul-Christian. 2017. <span>“Brms: <span>An</span> <span>R</span> <span>Package</span> for <span>Bayesian</span> <span>Multilevel</span> <span>Models</span> <span>Using</span> <span>Stan</span>.”</span> <em>Journal of Statistical Software</em> 80 (1): 1–28. <a href="https://doi.org/10.18637/jss.v080.i01">https://doi.org/10.18637/jss.v080.i01</a>.
</div>
<div id="ref-BurknerOrdinalRegressionModels2019" class="csl-entry">
Bürkner, Paul-Christian, and Matti Vuorre. 2019. <span>“Ordinal <span>Regression</span> <span>Models</span> in <span>Psychology</span>: <span>A</span> <span>Tutorial</span>.”</span> <em>Advances in Methods and Practices in Psychological Science</em> 2 (1): 77–101. <a href="https://doi.org/10.1177/2515245918823199">https://doi.org/10.1177/2515245918823199</a>.
</div>
<div id="ref-FerrariBetaRegressionModelling2004" class="csl-entry">
Ferrari, Silvia, and Francisco Cribari-Neto. 2004. <span>“Beta <span>Regression</span> for <span>Modelling</span> <span>Rates</span> and <span>Proportions</span>.”</span> <em>Journal of Applied Statistics</em> 31 (7): 799–815. <a href="https://doi.org/10.1080/0266476042000214501">https://doi.org/10.1080/0266476042000214501</a>.
</div>
<div id="ref-LiddellAnalyzingOrdinalData2018" class="csl-entry">
Liddell, Torrin M., and John K. Kruschke. 2018. <span>“Analyzing Ordinal Data with Metric Models: <span>What</span> Could Possibly Go Wrong?”</span> <em>Journal of Experimental Social Psychology</em> 79 (November): 328–48. <a href="https://doi.org/10.1016/j.jesp.2018.08.009">https://doi.org/10.1016/j.jesp.2018.08.009</a>.
</div>
<div id="ref-LiuReviewComparisonBayesian2018" class="csl-entry">
Liu, Fang, and Evercita C Eugenio. 2018. <span>“A Review and Comparison of <span>Bayesian</span> and Likelihood-Based Inferences in Beta Regression and Zero-or-One-Inflated Beta Regression.”</span> <em>Statistical Methods in Medical Research</em> 27 (4): 1024–44. <a href="https://doi.org/10.1177/0962280216650699">https://doi.org/10.1177/0962280216650699</a>.
</div>
<div id="ref-LiuZoibPackageBayesian2015" class="csl-entry">
Liu, Fang, and Yunchuan Kong. 2015. <span>“Zoib: <span>An</span> <span>R</span> <span>Package</span> for <span>Bayesian</span> <span>Inference</span> for <span>Beta</span> <span>Regression</span> and <span>Zero</span>/<span>One</span> <span>Inflated</span> <span>Beta</span> <span>Regression</span>.”</span> <em>The R Journal</em> 7 (2): 34–51. <a href="https://journal.r-project.org/archive/2015/RJ-2015-019/index.html">https://journal.r-project.org/archive/2015/RJ-2015-019/index.html</a>.
</div>
<div id="ref-OspinaInflatedBetaDistributions2008" class="csl-entry">
Ospina, Raydonal, and Silvia L. P. Ferrari. 2008. <span>“Inflated Beta Distributions.”</span> <em>Statistical Papers</em> 51 (1): 111. <a href="https://doi.org/10.1007/s00362-008-0125-4">https://doi.org/10.1007/s00362-008-0125-4</a>.
</div>
<div id="ref-SmithsonBetterLemonSqueezer2006" class="csl-entry">
Smithson, Michael, and Jay Verkuilen. 2006. <span>“A Better Lemon Squeezer? <span>Maximum</span>-Likelihood Regression with Beta-Distributed Dependent Variables.”</span> <em>Psychological Methods</em> 11 (1): 54–71. <a href="https://doi.org/10.1037/1082-989X.11.1.54">https://doi.org/10.1037/1082-989X.11.1.54</a>.
</div>
<div id="ref-VerkuilenMixedMixtureRegression2012" class="csl-entry">
Verkuilen, Jay, and Michael Smithson. 2012. <span>“Mixed and <span>Mixture</span> <span>Regression</span> <span>Models</span> for <span>Continuous</span> <span>Bounded</span> <span>Responses</span> <span>Using</span> the <span>Beta</span> <span>Distribution</span>.”</span> <em>Journal of Educational and Behavioral Statistics</em> 37 (1): 82–113. <a href="https://doi.org/10.3102/1076998610396895">https://doi.org/10.3102/1076998610396895</a>.
</div>
<div id="ref-YarkoniChoosingPredictionExplanation2017" class="csl-entry">
Yarkoni, Tal, and Jacob Westfall. 2017. <span>“Choosing <span>Prediction</span> <span>Over</span> <span>Explanation</span> in <span>Psychology</span>: <span>Lessons</span> <span>From</span> <span>Machine</span> <span>Learning</span>.”</span> <em>Perspectives on Psychological Science</em> 12 (6): 1100–1122. <a href="https://doi.org/10.1177/1745691617693393">https://doi.org/10.1177/1745691617693393</a>.
</div>
</div></section><section id="footnotes" class="footnotes footnotes-end-of-document"><h2 class="anchored quarto-appendix-heading">Footnotes</h2>

<ol>
<li id="fn1"><p>Technically, normal models assume that the residuals are normally distributed. I will keep referring to data being normally distributed or not, for clarity.↩︎</p></li>
</ol>
</section><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{vuorre2019,
  author = {Vuorre, Matti},
  title = {How to Analyze Visual Analog (Slider) Scale Data?},
  date = {2019-02-18},
  url = {https://vuorre.com/posts/analyze-analog-scale-ratings-with-zero-one-inflated-beta-models/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-vuorre2019" class="csl-entry quarto-appendix-citeas">
Vuorre, Matti. 2019. <span>“How to Analyze Visual Analog (Slider) Scale
Data?”</span> February 18, 2019. <a href="https://vuorre.com/posts/analyze-analog-scale-ratings-with-zero-one-inflated-beta-models/">https://vuorre.com/posts/analyze-analog-scale-ratings-with-zero-one-inflated-beta-models/</a>.
</div></div></section></div> ]]></description>
  <category>r</category>
  <category>statistics</category>
  <guid>https://vuorre.com/posts/analyze-analog-scale-ratings-with-zero-one-inflated-beta-models/</guid>
  <pubDate>Sun, 17 Feb 2019 23:00:00 GMT</pubDate>
  <media:content url="https://vuorre.com/posts/analyze-analog-scale-ratings-with-zero-one-inflated-beta-models/index_files/figure-html/fig-beta-distributions-1.png" medium="image" type="image/png" height="70" width="144"/>
</item>
<item>
  <title>Combine ggplots with patchwork</title>
  <dc:creator>Matti Vuorre</dc:creator>
  <link>https://vuorre.com/posts/rpihkal-combine-ggplots-with-patchwork/</link>
  <description><![CDATA[ 





<p><a href="https://ggplot2.tidyverse.org/">ggplot2</a> is the best R package for data visualization, and has powerful features for “facetting” plots into small multiples based on categorical variables.</p>
<section id="facetting-figures-into-small-multiples" class="level2">
<h2 class="anchored" data-anchor-id="facetting-figures-into-small-multiples">Facetting figures into small multiples</h2>
<p>This “facetting” is useful for showing the same figure, e.g.&nbsp;a bivariate relationship, at multiple levels of some other variable</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(tidyverse)</span>
<span id="cb1-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(mtcars, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(mpg, disp)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb1-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_point</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb1-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">facet_wrap</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"cyl"</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://vuorre.com/posts/rpihkal-combine-ggplots-with-patchwork/index_files/figure-html/unnamed-chunk-1-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>But if you would like to get a figure that consists of multiple panels of unrelated plots—with different variables on the X and Y axes, potentially from different data sources—things become more complicated.</p>
</section>
<section id="combining-arbitrary-ggplots" class="level2">
<h2 class="anchored" data-anchor-id="combining-arbitrary-ggplots">Combining arbitrary ggplots</h2>
<p>Say you have these three figures</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb2-1">p <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(mtcars)</span>
<span id="cb2-2"></span>
<span id="cb2-3">a <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> p <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb2-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(mpg, disp, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">col =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as.factor</span>(vs)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb2-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_smooth</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">se =</span> F) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb2-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_point</span>()</span>
<span id="cb2-7"></span>
<span id="cb2-8">b <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> p <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb2-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(disp, gear, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">group =</span> gear) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb2-10">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_boxplot</span>()</span>
<span id="cb2-11"></span>
<span id="cb2-12">c <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> p <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb2-13">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(hp) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb2-14">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">stat_density</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">geom =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"area"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb2-15">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">coord_cartesian</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">expand =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
</div>
<p>How would you go about combining them? There are a few options, such as <code>grid.arrange()</code> in the <a href="https://cran.r-project.org/web/packages/gridExtra/index.html">gridExtra</a> package, and <code>plot_grid()</code> in the <a href="https://cran.r-project.org/web/packages/cowplot/vignettes/plot_grid.html">cowplot</a> package. Today, I’ll point out a newer package that introduces a whole new syntax for combining together, <a href="https://github.com/thomasp85/patchwork">patchwork</a>.</p>
</section>
<section id="patchwork" class="level2">
<h2 class="anchored" data-anchor-id="patchwork">Patchwork</h2>
<p>patchwork is not yet on CRAN, so install it from GitHub:</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb3-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># install.packages("devtools")</span></span>
<span id="cb3-2">devtools<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">install_github</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"thomasp85/patchwork"</span>)</span></code></pre></div></div>
</div>
<p>Once you load the package, you can add ggplots together by adding them with <code>+</code>:</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb4-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(patchwork)</span>
<span id="cb4-2">a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> b <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> c</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://vuorre.com/posts/rpihkal-combine-ggplots-with-patchwork/index_files/figure-html/unnamed-chunk-4-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>Basically, you can add ggplots together as if they were geoms inside a single ggplot. However, there’s more. <code>|</code> specifies side-by-side addition</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb5-1">a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> c</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://vuorre.com/posts/rpihkal-combine-ggplots-with-patchwork/index_files/figure-html/unnamed-chunk-5-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>And <code>/</code> is for adding plots under the previous plot</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb6-1">b <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> c</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://vuorre.com/posts/rpihkal-combine-ggplots-with-patchwork/index_files/figure-html/unnamed-chunk-6-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>These operators can be used to flexibly compose figures from multiple components, using parentheses to group plots and <code>+</code>, <code>|</code>, and <code>/</code> to add the groups together</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb7-1">(a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> b) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> c</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://vuorre.com/posts/rpihkal-combine-ggplots-with-patchwork/index_files/figure-html/unnamed-chunk-7-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>Use <code>plot_annotation()</code> to add tags, and <code>&amp;</code> to pass theme elements to all plot elements in a composition</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb8-1">(a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> b) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span></span>
<span id="cb8-2">  c <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb8-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">plot_annotation</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">tag_levels =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span></span>
<span id="cb8-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">legend.position =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"none"</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://vuorre.com/posts/rpihkal-combine-ggplots-with-patchwork/index_files/figure-html/mainfig-1.png" class="img-fluid figure-img" width="672"></p>
<figcaption>Tweak this a little bit and throw it in a manuscript.</figcaption>
</figure>
</div>
</div>
</div>
<p>There are many more examples on <a href="https://github.com/thomasp85/patchwork">patchwork’s GitHub page</a>. I’ve found this package more useful in composing figures out of multiple plots than its alternatives, mainly because of the concise but powerful syntax.</p>


</section>

<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{vuorre2018,
  author = {Vuorre, Matti},
  title = {Combine Ggplots with Patchwork},
  date = {2018-12-13},
  url = {https://vuorre.com/posts/rpihkal-combine-ggplots-with-patchwork/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-vuorre2018" class="csl-entry quarto-appendix-citeas">
Vuorre, Matti. 2018. <span>“Combine Ggplots with Patchwork.”</span>
December 13, 2018. <a href="https://vuorre.com/posts/rpihkal-combine-ggplots-with-patchwork/">https://vuorre.com/posts/rpihkal-combine-ggplots-with-patchwork/</a>.
</div></div></section></div> ]]></description>
  <category>r</category>
  <category>visualization</category>
  <guid>https://vuorre.com/posts/rpihkal-combine-ggplots-with-patchwork/</guid>
  <pubDate>Wed, 12 Dec 2018 23:00:00 GMT</pubDate>
  <media:content url="https://vuorre.com/posts/rpihkal-combine-ggplots-with-patchwork/index_files/figure-html/mainfig-1.png" medium="image" type="image/png" height="82" width="144"/>
</item>
</channel>
</rss>
