<?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>Credibly Curious</title>
<link>https://www.njtierney.com/</link>
<atom:link href="https://www.njtierney.com/index.xml" rel="self" type="application/rss+xml"/>
<description>Nick Tierney&#39;s (mostly) rstats blog</description>
<generator>quarto-1.9.38</generator>
<lastBuildDate>Thu, 09 Jul 2026 00:00:00 GMT</lastBuildDate>
<item>
  <title>How to Put your Course Book Online</title>
  <link>https://www.njtierney.com/posts/2026-07-09-put-course-online/</link>
  <description><![CDATA[ 
<header class="site-header">
  <h1 class="site-title">
    <a href="../../">
      <img class="hvr-grow site-logo" src="https://www.njtierney.com/assets/njt-logo-small.png" alt="Nick logo">
    </a>
    <span class="hvr-bob site-title-credibly">Credibly</span>
    <span class="hvr-hang site-title-curious">Curious</span>
  </h1>
  <p class="site-subtitle">
    Nick Tierney's (mostly) rstats blog
  </p>
  
</header>




<p>I recently gave a talk, <a href="https://njtierney.github.io/talk-teacher-over-content/#/title-slide">The value in teaching is not the <strong>content</strong> it’s the <strong>teacher</strong></a></p>
<p>My main point in this is:</p>
<blockquote class="blockquote">
<p>Your course materials should be out there in public for free online.</p>
</blockquote>
<p>To help support this, this blog post goes through the technical details I note in one of my slides: How to Put your Course Book Online.</p>
<section id="summary" class="level1">
<h1>Summary</h1>
<ul>
<li>Make a quarto book</li>
<li>Add an appropriate license <a href="https://creativecommons.org/licenses/by-nc/4.0/">CC BY-NC-4.0</a>
<ul>
<li>Can share/adapt, must attribute</li>
<li>Cannot use materials commercially</li>
</ul></li>
<li>Add a README</li>
<li>Put it on github</li>
<li>Have it render as an online book when you make changes</li>
</ul>
</section>
<section id="follow-along-with-github-repo-course-book-template" class="level1">
<h1>Follow along with github repo: “course-book-template”</h1>
<p>I have made a repo on github <a href="https://github.com/njtierney/course-book-template">“course-book-template”</a> that details each of these steps.</p>
</section>
<section id="make-a-quarto-book" class="level1">
<h1>Make a quarto book</h1>
<p>The quarto docs on starting a book are <em>excellent</em> so I would recommend starting there: <a href="https://quarto.org/docs/books/#quick-start" class="uri">https://quarto.org/docs/books/#quick-start</a>.</p>
<p>But essentially, you run:</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;">quarto</span> create project book .</span></code></pre></div></div>
<p>It will then guide you through creating a title, etc</p>
<p><a href="https://github.com/njtierney/course-book-template/commit/e2b1a6f3b0e8668ca4c068365124124c14630230">commit of adding the book</a></p>
</section>
<section id="add-an-appropriate-license" class="level1">
<h1>Add an appropriate license</h1>
<p>It is important to pick a license early. This helps protect your work, and also makes it clear to others how to reference and use your work. Personally, I like <a href="https://creativecommons.org/licenses/by-nc/4.0/">CC BY-NC-4.0</a>, this gives you these conditions:</p>
<ul>
<li>Can share/adapt, must attribute</li>
<li>Cannot use materials commercially</li>
</ul>
<p>Note that this is different to the very common <a href="https://creativecommons.org/licenses/by/4.0/">CC-BY</a>, which does allow commercial usage.</p>
<p>If you aren’t sure about licenses for your purpose, it would be worthwhile checking out the chooser here <a href="https://creativecommons.org/chooser/" class="uri">https://creativecommons.org/chooser/</a></p>
<p>In using this, I discovered another useful license, <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC-BY-NC-SA 4.0</a> Which builds off of CC-BY-NC, but with one additional clause:</p>
<blockquote class="blockquote">
<p>ShareAlike - If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.</p>
</blockquote>
<p>This is sometimes known as “copyleft”. This is sometimes seen as too restrictive. Consult with your community about what the standards are. Another useful place to read up on licenses is the <a href="https://r-pkgs.org/license.html">“licensing” chapter in the R packages book by Hadley Wickham and Jenny Bryan</a></p>
<p>I add a LICENSE file, and also a license.qmd chapter, as well as add the license to the README.</p>
<p><a href="https://github.com/njtierney/course-book-template/commit/1825258f3bda4116ef09886c4fda7dedd722c2f2">commit of adding the license</a></p>
</section>
<section id="using-a-readme" class="level1">
<h1>Using a README</h1>
<p>I think it is worthwhile adding a few key sections to your README file:</p>
<ul>
<li>Details: like the abstract - the hook!</li>
<li>Prerequisites: What do you expect learners to know?</li>
<li>Learning outcomes: What will they walk away knowing?</li>
<li>Schedule: An outline of each hour of learning, optionally with a timetable</li>
</ul>
<p><a href="https://github.com/njtierney/course-book-template/commit/5ca6202b80b047f1da48486db57df96d2bbdbf02">commit of adding the README</a></p>
</section>
<section id="put-it-on-online---github" class="level1">
<h1>Put it on online - github</h1>
<p>Your course should live somewhere public! You can see for example our course materials here: <a href="https://github.com/njtierney/course-book-template" class="uri">https://github.com/njtierney/course-book-template</a></p>
</section>
<section id="have-it-render-when-you-make-changes" class="level1">
<h1>Have it render when you make changes</h1>
<p>You can use github actions to render your book. This is really neat, and means your book will be rendered anytime you push changes. It means you don’t need to push HTML, just the quarto files.</p>
<p>Rhere are a few different ways you can manage this, I happen to like using github pages.</p>
<p>There are some really nice instructions on the quarto website on how to set up github pages - <a href="https://quarto.org/docs/publishing/github-pages.html#github-action" class="uri">https://quarto.org/docs/publishing/github-pages.html#github-action</a></p>
<p>However, I have found a slightly different setup, which I will share here.</p>
<p>This involves using a DESCRIPTION file to track the R packages that you use. The reason we need to do this is to make sure when we render our book, that all the R packages we need are installed. There are probably other ways around this, and I’d love to hear them, but this is what I have found works.</p>
<p>Here is the first step where I add a dependency, in this case, tidyverse.</p>
<p><a href="https://github.com/njtierney/course-book-template/commit/7777757f9ab2d98985576ef7e65ebc801e2ae17e">commit of adding this tidyverse code</a></p>
<p>Then add the DESCRIPTION file with:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb2-1">usethis<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;">use_description</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">check_name =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span>)</span></code></pre></div></div>
<p>I then edited mine to look like this:</p>
<pre class="dcf"><code>Package: course-book-template
Title: A book about some things
Version: 0.0.0.9000
Authors@R: 
  c(
  person(
    given = "Nicholas",
    family = "Tierney",
    email = "nicholas.tierney@gmail.com",
    role = c("aut", "cre"),
    comment = c(ORCID = "https://orcid.org/0000-0003-1460-8722")
    )
  )
Description: Course materials for your topic. This should have two sentences.
License: CC-BY-NC 4.0 + file LICENSE
Encoding: UTF-8
Language: en-GB
Roxygen: list(markdown = TRUE)
RoxygenNote: 8.0.0</code></pre>
<p><a href="https://github.com/njtierney/course-book-template/commit/22ec04320474b5c60d6ab1e51772e2a30cfc899d">commit</a></p>
<p>You can then add your package dependency into Imports or Depends. Which one you use is normally very important for R package development, but the reason we are using a DESCRIPTION file here is to track our dependencies.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf">usethis</span><span class="nf">::</span><span class="nf"><a href="https://usethis.r-lib.org/reference/use_package.html">use_package</a></span><span class="o">(</span><span class="s">"tidyverse"</span>, type <span class="o">=</span> <span class="s">"Depends"</span><span class="o">)</span></span></code></pre>
</div>
<p><a href="https://github.com/njtierney/course-book-template/commit/ec736d9eb84849cc10ab798f57772694d33766d0">commit</a></p>
<p>I then add the github actions - you can actually just refer to a file, so this will work:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" 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;">use_github_action</span>(<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;">"https://github.com/njtierney/gentlegit/blob/main/.github/workflows/quarto-publish.yml"</span>)</span></code></pre></div></div>
<p>This will give you a message like the following:</p>
<pre><code>✔ Creating .github/.
✔ Adding "^\\.github$" to .Rbuildignore.
✔ Adding "*.html" to .github/.gitignore.
✔ Creating .github/workflows/.
✔ Saving
  "njtierney/gentlegit/.github/workflows/quarto-publish.yml@main"
  to .github/workflows/quarto-publish.yml.</code></pre>
<p><a href="https://github.com/njtierney/course-book-template/commit/0d18aaa8546698cb2c5ec8de38f5b5ee60be3dbf">commit</a></p>
<p>Also, probably a good time to add a .gitignore file. This is a good idea to make sure you don’t commit HTML files (they can be really large,a nd we don’t need them), or other file types that might be really large, or have sensitive information in them.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf">usethis</span><span class="nf">::</span><span class="nf"><a href="https://usethis.r-lib.org/reference/use_git_ignore.html">use_git_ignore</a></span><span class="o">(</span><span class="s">"*.pdf"</span><span class="o">)</span></span></code></pre>
</div>
<p>Will create the file, and tell git to never commit a PDF.</p>
<p>I edit my .gitignore file to look like the following:</p>
<pre><code>/.quarto/
**/*.quarto_ipynb
.Rproj.user
.Rhistory
.RData
.Ruserdata
dev
docs
/.quarto/
*.aux
*.log
*.pdf
*.tex
*.toc
*.rds
*_files
*_cache
*.html
.DS_Store</code></pre>
<p><a href="https://github.com/njtierney/course-book-template/commit/9c165f3c88194b7a2526fe13cfbaaa5ea6c89d9a">commit</a></p>
<p>Once all this is said and done, you will still need to run some commands in your terminal:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb7-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">quarto</span> publish gh-pages</span></code></pre></div></div>
<p>This should then produce a question like:</p>
<pre><code>nick course-book-template[main] &gt; quarto publish gh-pages
? Publish site to https://njtierney.github.io/course-book-template/ using gh-pages? (Y/n) › </code></pre>
<p>reply “Y”</p>
<p>You will then get some code that looks like:</p>
<pre><code>Switched to a new branch 'gh-pages'
[gh-pages (root-commit) 8ccc5e0] Initializing gh-pages branch
remote: 
remote: Create a pull request for 'gh-pages' on GitHub by visiting:        
remote:      https://github.com/njtierney/course-book-template/pull/new/gh-pages        
remote: 
To https://github.com/njtierney/course-book-template.git
 * [new branch]      HEAD -&gt; gh-pages
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
From https://github.com/njtierney/course-book-template
 * branch            gh-pages   -&gt; FETCH_HEAD</code></pre>
<p>And then some rendering code that will look like:</p>
<pre><code>Rendering for publish:

[1/4] index.qmd
[2/4] intro.qmd


processing file: intro.qmd
1/3                  
2/3 [unnamed-chunk-1]
3/3                  
output file: intro.knit.md

...

(|) Deploying gh-pages branch to website (this may take a few minutes)</code></pre>
<p>Wait a few minutes, as it asks you.</p>
<p>Then you should see something like:</p>
<pre><code>[✓] Deploying gh-pages branch to website (this may take a few minutes)
[✓] Published to https://njtierney.github.io/course-book-template/

NOTE: GitHub Pages deployments normally take a few minutes (your site updates
will be visible once the deploy completes)</code></pre>
<p>Your website probably won’t be visible just yet, which feels a touch annoying, but you can keep an eye on it on the “actions” tab, e.g., <a href="https://github.com/njtierney/course-book-template/actions" class="uri">https://github.com/njtierney/course-book-template/actions</a></p>
<p>Once this has lit green (hopefully it has!)</p>
<p>You should go to your “about” section, and click on the setting cog:</p>
<div class="highlight">
<p><img src="https://www.njtierney.com/posts/2026-07-09-put-course-online/imgs/about-cog.png" alt="" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>Then tick the box that says “Use your GitHub Pages website”</p>
<div class="highlight">
<p><img src="https://www.njtierney.com/posts/2026-07-09-put-course-online/imgs/about-website.png" alt="" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>This adds your GitHub Pages website onto the repo, and it looks pretty neat.</p>
<p>There are more things you can do, like configuring your own custom website instead of using github.</p>
<p>So, instead of <a href="https://njtierney.github.io/course-book-template/" class="uri">https://njtierney.github.io/course-book-template/</a>, you could have: “course-book-template.com”.</p>
<p>And that’s it!</p>


</section>

 ]]></description>
  <category>bookdown</category>
  <category>quarto</category>
  <category>teaching</category>
  <guid>https://www.njtierney.com/posts/2026-07-09-put-course-online/</guid>
  <pubDate>Thu, 09 Jul 2026 00:00:00 GMT</pubDate>
</item>
<item>
  <title>R Version 4.5.0 is Out!</title>
  <link>https://www.njtierney.com/posts/2025-04-14-r-version-4-5-0-is-out/</link>
  <description><![CDATA[ 
<header class="site-header">
  <h1 class="site-title">
    <a href="../../">
      <img class="hvr-grow site-logo" src="https://www.njtierney.com/assets/njt-logo-small.png" alt="Nick logo">
    </a>
    <span class="hvr-bob site-title-credibly">Credibly</span>
    <span class="hvr-hang site-title-curious">Curious</span>
  </h1>
  <p class="site-subtitle">
    Nick Tierney's (mostly) rstats blog
  </p>
  
</header>




<div class="highlight">
<p><img src="https://www.njtierney.com/posts/2025-04-14-r-version-4-5-0-is-out/figs/windows-olympus-xa-portra-800.jpg" width="700px" style="display: block; margin: auto;"></p>
</div>
<p><em>Some windows. Olympus XA, Portra 800. Photo by Nicholas Tierney</em></p>
<p>The new R version 4.5.0 is out, and you should get it!</p>
<p>I’ve read through <a href="https://cran.r-project.org/doc/manuals/r-release/NEWS.html">the NEWS file</a>, which details every change - there are many! I would recommend having a skim.</p>
<p>If you’d like to have a skim of the news file, you even use the <a href="https://rdrr.io/r/utils/news.html"><code>news()</code></a> R function, which will open the NEWS file to your help file pane in RStudio. This can also tell us how many news bullets were added:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">news_4_5_0</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/utils/news.html">news</a></span><span class="o">(</span><span class="nv">Version</span> <span class="o">==</span> <span class="s">"4.5.0"</span><span class="o">)</span></span>
<span><span class="c"># just show the first 5</span></span>
<span><span class="nf"><a href="https://rdrr.io/r/utils/head.html">head</a></span><span class="o">(</span><span class="nv">news_4_5_0</span><span class="o">)</span></span>
<span><span class="c">#&gt;                         Changes in version 4.5.0                        </span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt; NEW FEATURES</span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt;     o   as.integer(rl) and hence as.raw(rl) now work for a list of</span></span>
<span><span class="c">#&gt;   raw(1) elements, as proposed by Michael Chirico's PR#18696.</span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt;     o   graphics' grid() gains optional argument nintLog.</span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt;     o   New functions check_package_urls() and check_package_dois() in</span></span>
<span><span class="c">#&gt;   package tools for checking URLs and DOIs in package sources.</span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt;     o   New head() and tail() methods for class "ts" time series,</span></span>
<span><span class="c">#&gt;   proposed by Spencer Graves on R-devel.</span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt;     o   New qr.influence() function, a "bare bones" interface to the</span></span>
<span><span class="c">#&gt;   lm.influence() leave-one-out diagnostics computations; wished</span></span>
<span><span class="c">#&gt;   for in PR#18739.</span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt;     o   Package citation() results auto-generated from the package</span></span>
<span><span class="c">#&gt;   metadata now also provide package DOIs for CRAN and</span></span>
<span><span class="c">#&gt;   Bioconductor packages.</span></span>
<span></span></code></pre>
</div>
<p>The work of this release involved many people, and there are 150 changes. I think it’s worthwhile reading over these changes, and I am incredibly grateful to all the amazing volunteers who put their time and energy into continuing to make R stable, and awesome.</p>
<p>I thought I’d share just a couple of the changes that jumped out at me as I was reading.</p>
<section id="installation-is-now-faster" class="level1">
<h1>Installation is now faster</h1>
<blockquote class="blockquote">
<p><a href="https://rdrr.io/r/utils/install.packages.html"><code>install.packages()</code></a> and <a href="https://rdrr.io/r/utils/download.packages.html"><code>download.packages()</code></a> download packages simultaneously using <code>libcurl</code>, significantly reducing download times when installing or downloading multiple packages.</p>
</blockquote>
<p>This is cool! Installing packages is now much faster! I love this. Generally, I use <a href="https://github.com/r-lib/pak"><code>pak</code></a>, which I believe already does this. But it’s a nice win for vanilla R to know I can download things faster.</p>
</section>
<section id="data" class="level1">
<h1>Data</h1>
<p>There are two new datasets added to R! The last time (that I could find) a new dataset was added to R was in <a href="https://cran.r-project.org/doc/manuals/r-devel/NEWS.3.html">R version 3.0.2</a>, which, <a href="https://cran.r-project.org/bin/windows/base/old/">going to the release dates</a>, was in September 2013. So, nearly 12 years ago! That NEWS item read:</p>
<blockquote class="blockquote">
<p>Dataset <code>npk</code> has been copied from MASS to allow more tests to be run without recommended packages being installed.</p>
</blockquote>
<p>You might be familiar with one of these new datasets, the penguins data (!) from the <a href="https://github.com/allisonhorst/palmerpenguins/"><code>palmerpenguins</code></a> R package.</p>
<div class="highlight">
<p><img src="https://www.njtierney.com/posts/2025-04-14-r-version-4-5-0-is-out/figs/lter_penguins.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p><em>artwork by <a href="https://allisonhorst.com/">Allison Horst</a></em></p>
<p>The NEWS item reads:</p>
<blockquote class="blockquote">
<p>New datasets penguins and penguins_raw thanks to <a href="https://ellakaye.co.uk/">Ella Kaye</a>, <a href="https://www.heatherturner.net/">Heather Turner</a>, and <a href="https://gormankb.github.io/">Kristen Gorman</a>.</p>
</blockquote>
<p>This is huge! Well, I think it is. Now we don’t need to write <a href="https://allisonhorst.github.io/palmerpenguins/"><code>library(palmerpenguins)</code></a> if you want to use the <code>penguins</code> or <code>penguins_raw</code> data. Looking at the examples, we can see the following base visualisations:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="c">## bill depth vs. length by species (color) and sex (symbol):</span></span>
<span><span class="c">## positive correlations for all species, males tend to have bigger bills</span></span>
<span><span class="nf"><a href="https://rdrr.io/r/utils/head.html">head</a></span><span class="o">(</span><span class="nv">penguins</span><span class="o">)</span></span>
<span><span class="c">#&gt;   species    island bill_len bill_dep flipper_len body_mass    sex year</span></span>
<span><span class="c">#&gt; 1  Adelie Torgersen     39.1     18.7         181      3750   male 2007</span></span>
<span><span class="c">#&gt; 2  Adelie Torgersen     39.5     17.4         186      3800 female 2007</span></span>
<span><span class="c">#&gt; 3  Adelie Torgersen     40.3     18.0         195      3250 female 2007</span></span>
<span><span class="c">#&gt; 4  Adelie Torgersen       NA       NA          NA        NA   &lt;NA&gt; 2007</span></span>
<span><span class="c">#&gt; 5  Adelie Torgersen     36.7     19.3         193      3450 female 2007</span></span>
<span><span class="c">#&gt; 6  Adelie Torgersen     39.3     20.6         190      3650   male 2007</span></span>
<span></span><span><span class="nf"><a href="https://rdrr.io/r/base/names.html">names</a></span><span class="o">(</span><span class="nv">penguins</span><span class="o">)</span></span>
<span><span class="c">#&gt; [1] "species"     "island"      "bill_len"    "bill_dep"    "flipper_len"</span></span>
<span><span class="c">#&gt; [6] "body_mass"   "sex"         "year"</span></span>
<span></span><span><span class="nv">sym</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span><span class="m">1</span>, <span class="m">16</span><span class="o">)</span></span>
<span><span class="nv">pal</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span></span>
<span>  <span class="s">"darkorange"</span>,</span>
<span>  <span class="s">"purple"</span>,</span>
<span>  <span class="s">"cyan4"</span></span>
<span>  <span class="o">)</span></span>
<span><span class="nf"><a href="https://rdrr.io/r/graphics/plot.default.html">plot</a></span><span class="o">(</span></span>
<span>  <span class="nv">bill_dep</span> <span class="o">~</span> <span class="nv">bill_len</span>, </span>
<span>  data <span class="o">=</span> <span class="nv">penguins</span>, </span>
<span>  pch <span class="o">=</span> <span class="nv">sym</span><span class="o">[</span><span class="nv">sex</span><span class="o">]</span>, </span>
<span>  col <span class="o">=</span> <span class="nv">pal</span><span class="o">[</span><span class="nv">species</span><span class="o">]</span></span>
<span>  <span class="o">)</span></span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2025-04-14-r-version-4-5-0-is-out/figs/penguins-plot-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>It is worth noting that the variable names are slightly different in the new base R version - <code>bill_len</code> (not <code>bill_length</code>) <code>bill_dep</code> (not <code>bill_depth</code>), and <code>flipper_len</code> (not <code>flipper_length</code>), which they note in the helpfile: “The penguins data has some shorter variable names than the palmerpenguins version, for compact code and data display.”</p>
<p>There has been a bit of work done on the penguins data, and I wanted to share the relevant references:</p>
<ul>
<li><p>Gorman, K. B., Williams, T. D. and Fraser, W. R. (2014) Ecological Sexual Dimorphism and Environmental Variability within a Community of Antarctic Penguins (Genus Pygoscelis). PLoS ONE 9, 3, e90081; <a href="https://doi.org/10.1371/journal.pone.0090081">doi:10.1371/journal.pone.0090081</a>.</p></li>
<li><p>Horst, A. M., Hill, A. P. and Gorman, K. B. (2022) Palmer Archipelago Penguins Data in the palmerpenguins R Package - An Alternative to Anderson’s Irises. R Journal 14, 1; <a href="https://doi.org/10.32614/RJ-2022-020">doi:10.32614/RJ-2022-020</a>.</p></li>
<li><p>Kaye, E., Turner, H., Gorman, K. B., Horst, A. M. and Hill, A. P. (2025) Preparing the Palmer Penguins Data for the datasets Package in R. <a href="https://doi.org/10.5281/zenodo.14902740">doi:10.5281/zenodo.14902740</a>.</p></li>
</ul>
<p>And there’s ANOTHER dataset!</p>
<blockquote class="blockquote">
<p>New dataset gait thanks to <a href="">Heather Turner</a> and <a href="">Ella Kaye</a>, used in examples.</p>
</blockquote>
<p>I hadn’t come across this before, the helpfile (<a href="https://rdrr.io/r/datasets/gait.html"><code>?gait</code></a>) reads:</p>
<blockquote class="blockquote">
<p>Hip and knee angle (in degrees) through a 20 point movement cycle for 39 boys.</p>
</blockquote>
<p>Which is stored as a 3D array, as stated in the helpfile:</p>
<blockquote class="blockquote">
<p>A 3-dimensional array with dimensions c(20, 39, 2) giving the “Hip Angle” and “Knee Angle” (in degrees) for 39 repetitions of a 20 point gait cycle (over standardized gait times).</p>
</blockquote>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://rdrr.io/r/utils/head.html">head</a></span><span class="o">(</span><span class="nv">gait</span><span class="o">)</span></span>
<span><span class="c">#&gt; , , Variable = Hip Angle</span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt;        Subject</span></span>
<span><span class="c">#&gt; Time    boy1 boy2 boy3 boy4 boy5 boy6 boy7 boy8 boy9 boy10 boy11 boy12 boy13</span></span>
<span><span class="c">#&gt;   0.025   37   47   46   37   20   57   46   46   46    35    38    35    34</span></span>
<span><span class="c">#&gt;   0.075   36   46   44   36   18   48   38   46   42    34    37    31    31</span></span>
<span><span class="c">#&gt;   0.125   33   42   39   27   11   44   33   43   37    29    33    29    27</span></span>
<span><span class="c">#&gt;   0.175   29   34   34   20    8   35   25   40   34    28    29    26    23</span></span>
<span><span class="c">#&gt;   0.225   23   27   33   15    7   31   18   36   31    19    26    22    19</span></span>
<span><span class="c">#&gt;   0.275   18   21   27   15    5   27   15   30   25    15    20    19    15</span></span>
<span><span class="c">#&gt;        Subject</span></span>
<span><span class="c">#&gt; Time    boy14 boy15 boy16 boy17 boy18 boy19 boy20 boy21 boy22 boy23 boy24 boy25</span></span>
<span><span class="c">#&gt;   0.025    43    43    40    51    52    36    35    46    43    55    39    37</span></span>
<span><span class="c">#&gt;   0.075    41    37    41    49    46    33    37    38    41    51    38    34</span></span>
<span><span class="c">#&gt;   0.125    36    35    36    45    41    28    33    30    37    47    31    30</span></span>
<span><span class="c">#&gt;   0.175    31    28    32    39    35    22    27    23    30    41    27    27</span></span>
<span><span class="c">#&gt;   0.225    26    26    27    31    31    18    22    17    24    35    21    26</span></span>
<span><span class="c">#&gt;   0.275    20    21    20    23    24    13    14    13    16    30    14    19</span></span>
<span><span class="c">#&gt;        Subject</span></span>
<span><span class="c">#&gt; Time    boy26 boy27 boy28 boy29 boy30 boy31 boy32 boy33 boy34 boy35 boy36 boy37</span></span>
<span><span class="c">#&gt;   0.025    36    36    42    38    46    54    52    32    46    46    48    44</span></span>
<span><span class="c">#&gt;   0.075    33    33    40    34    47    48    44    28    41    44    42    41</span></span>
<span><span class="c">#&gt;   0.125    28    30    40    30    44    44    44    26    38    40    42    38</span></span>
<span><span class="c">#&gt;   0.175    22    28    34    23    37    37    33    22    31    35    35    32</span></span>
<span><span class="c">#&gt;   0.225    18    21    23    17    29    30    28    19    25    31    30    24</span></span>
<span><span class="c">#&gt;   0.275    13    15    15    12    23    27    27    13    20    25    23    18</span></span>
<span><span class="c">#&gt;        Subject</span></span>
<span><span class="c">#&gt; Time    boy38 boy39</span></span>
<span><span class="c">#&gt;   0.025    55    48</span></span>
<span><span class="c">#&gt;   0.075    56    50</span></span>
<span><span class="c">#&gt;   0.125    51    47</span></span>
<span><span class="c">#&gt;   0.175    46    42</span></span>
<span><span class="c">#&gt;   0.225    41    37</span></span>
<span><span class="c">#&gt;   0.275    36    29</span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt; , , Variable = Knee Angle</span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt;        Subject</span></span>
<span><span class="c">#&gt; Time    boy1 boy2 boy3 boy4 boy5 boy6 boy7 boy8 boy9 boy10 boy11 boy12 boy13</span></span>
<span><span class="c">#&gt;   0.025   10   16   18    5    2   15   13   14   15     9    13     7     9</span></span>
<span><span class="c">#&gt;   0.075   15   25   27   14    6   17   16   17   20    22    24     8    14</span></span>
<span><span class="c">#&gt;   0.125   18   28   32   16    6   23   22   18   23    25    27    11    16</span></span>
<span><span class="c">#&gt;   0.175   18   25   32   17    6   23   17   19   26    21    23    12    15</span></span>
<span><span class="c">#&gt;   0.225   15   18   28   10    5   20   12   19   25    10    18     8    15</span></span>
<span><span class="c">#&gt;   0.275   14   12   23    8    6   19    9   15   21     9    13     6    12</span></span>
<span><span class="c">#&gt;        Subject</span></span>
<span><span class="c">#&gt; Time    boy14 boy15 boy16 boy17 boy18 boy19 boy20 boy21 boy22 boy23 boy24 boy25</span></span>
<span><span class="c">#&gt;   0.025    15     6    11    24    16    16     7    21    11    12     8    11</span></span>
<span><span class="c">#&gt;   0.075    20    11    19    32    20    20    13    24    14    17    12    20</span></span>
<span><span class="c">#&gt;   0.125    22    20    30    35    21    22    14    25    14    20    14    22</span></span>
<span><span class="c">#&gt;   0.175    22    18    28    33    20    21    17    21    11    20    13    21</span></span>
<span><span class="c">#&gt;   0.225    21    13    25    29    18    20    14    16     8    18    12    21</span></span>
<span><span class="c">#&gt;   0.275    19     9    17    24    14    20     8     9     5    12     9    17</span></span>
<span><span class="c">#&gt;        Subject</span></span>
<span><span class="c">#&gt; Time    boy26 boy27 boy28 boy29 boy30 boy31 boy32 boy33 boy34 boy35 boy36 boy37</span></span>
<span><span class="c">#&gt;   0.025    16    19    13    11    17    20    18     9     8     9    13    19</span></span>
<span><span class="c">#&gt;   0.075    20    26    23    15    25    20    18    12    10    18    18    23</span></span>
<span><span class="c">#&gt;   0.125    22    28    30    19    30    22    25    16    17    19    27    26</span></span>
<span><span class="c">#&gt;   0.175    21    28    28    20    30    16    23    15    16    19    26    25</span></span>
<span><span class="c">#&gt;   0.225    20    24    19    18    27    10    18    14    12    19    25    21</span></span>
<span><span class="c">#&gt;   0.275    20    18    10    17    22    10    19    11    10    15    18    18</span></span>
<span><span class="c">#&gt;        Subject</span></span>
<span><span class="c">#&gt; Time    boy38 boy39</span></span>
<span><span class="c">#&gt;   0.025    16    14</span></span>
<span><span class="c">#&gt;   0.075    23    25</span></span>
<span><span class="c">#&gt;   0.125    28    32</span></span>
<span><span class="c">#&gt;   0.175    28    34</span></span>
<span><span class="c">#&gt;   0.225    25    30</span></span>
<span><span class="c">#&gt;   0.275    21    20</span></span>
<span></span></code></pre>
</div>
<p>With the examples having a nifty data visualisation:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://rdrr.io/r/graphics/plot.default.html">plot</a></span><span class="o">(</span></span>
<span>  <span class="nv">gait</span><span class="o">[</span>, <span class="m">1</span>, <span class="o">]</span>, </span>
<span>  type <span class="o">=</span> <span class="s">"b"</span>,</span>
<span>  xlim <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/range.html">range</a></span><span class="o">(</span><span class="nv">gait</span><span class="o">[</span>,,<span class="m">1</span><span class="o">]</span><span class="o">)</span>, </span>
<span>  ylim <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/range.html">range</a></span><span class="o">(</span><span class="nv">gait</span><span class="o">[</span>,,<span class="m">2</span><span class="o">]</span><span class="o">)</span>, </span>
<span>  xlab <span class="o">=</span> <span class="s">"Hip Angle"</span>, </span>
<span>  ylab <span class="o">=</span> <span class="s">"Knee Angle"</span>, </span>
<span>  main <span class="o">=</span> <span class="s">"'gait' data : Boy 1"</span></span>
<span><span class="o">)</span></span>
<span><span class="nf"><a href="https://rdrr.io/r/graphics/mtext.html">mtext</a></span><span class="o">(</span></span>
<span>  <span class="s">"all other boys"</span>, </span>
<span>  col <span class="o">=</span> <span class="s">"thistle"</span></span>
<span>  <span class="o">)</span></span>
<span><span class="nf"><a href="https://rdrr.io/r/graphics/grid.html">grid</a></span><span class="o">(</span><span class="o">)</span></span>
<span><span class="nf"><a href="https://rdrr.io/r/graphics/matplot.html">matlines</a></span><span class="o">(</span></span>
<span>  <span class="nv">gait</span><span class="o">[</span>, <span class="o">-</span><span class="m">1</span>, <span class="m">1</span><span class="o">]</span>, </span>
<span>  <span class="nv">gait</span><span class="o">[</span>, <span class="o">-</span><span class="m">1</span>, <span class="m">2</span><span class="o">]</span>, </span>
<span>  type <span class="o">=</span> <span class="s">"l"</span>, </span>
<span>  lty <span class="o">=</span> <span class="m">1</span>, </span>
<span>  col <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/grDevices/adjustcolor.html">adjustcolor</a></span><span class="o">(</span><span class="s">"thistle"</span>, <span class="m">1</span><span class="o">/</span><span class="m">3</span><span class="o">)</span></span>
<span>  <span class="o">)</span></span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2025-04-14-r-version-4-5-0-is-out/figs/gait-plot-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>It is worth noting the references for this data:</p>
<ul>
<li><p>Olshen, R. A., Biden, E. N., Wyatt, M. P., and Sutherland, D. (1989) Gait Analysis and the Bootstrap. Annals of Statistics 17, 4, 1419–1440. <a href="https://doi.org/10.1214/AOS/1176347372">doi:10.1214/AOS/1176347372</a></p></li>
<li><p>Ramsay, J. O., and Silverman, B. W. (2006) Functional Data Analysis, 2nd ed., New York: Springer.</p></li>
<li><p>Ramsay, J. (2023) fda: Functional Data Analysis. R package version 6.1.4, <a href="https://CRAN.R-project.org/package=fda" class="uri">https://CRAN.R-project.org/package=fda</a>.</p></li>
</ul>
</section>
<section id="blas-and-lapack-update" class="level1">
<h1>BLAS and LAPACK update</h1>
<blockquote class="blockquote">
<p>The bundled BLAS and LAPACK sources have been updated to those shipped as part of January 2025’s LAPACK 3.12.1.</p>
</blockquote>
<p>These help power many linear algebra operations in R, and there will likely be speed improvements and other efficiencies. So, worth installing for that alone.</p>
</section>
<section id="a-note-on-reading-news-files" class="level1">
<h1>A note on reading NEWS files</h1>
<p>I have tried to read the R NEWS files since about 2017 or 2018. I believe I heard <a href="https://rdpeng.org/">Roger Peng</a> say he read the R NEWS files on the <a href="https://nssdeviations.com/">Not So Standard Deviations podcast</a> with <a href="https://hilaryparker.com/">Hilary Parker</a>. It seemed like a good idea, so I have tried to do the same.</p>
<p>It usually involves me reading over the NEWS file and looking out for things that seem relevant to me and my work. I don’t always understand everything, in fact, I would say I don’t understand a lot of it. But every now and again something comes up that is important to me. For example, the NEWS item for <a href="https://cran.r-project.org/doc/manuals/r-release/NEWS.html">R 4.0.0</a> about matrices and arrays:</p>
<blockquote class="blockquote">
<p>matrix objects now also inherit from class “array”, so e.g., class(diag(1)) is c(“matrix”, “array”). This invalidates code incorrectly assuming that class(matrix_obj)) has length one.</p>
</blockquote>
<blockquote class="blockquote">
<p>S3 methods for class “array” are now dispatched for matrix objects.</p>
</blockquote>
<p>Resulted in a breaking change in greta, that I was able <a href="https://github.com/greta-dev/greta/pull/409/files">to identify and fix</a>.</p>
<p>Another time that I find it useful to know how to look up the NEWS file is remembering when some key new features were introduced. For example, knowing that the native pipe <code>|&gt;</code> was introduced in 4.1.0, but the underscore <code>_</code> placeholder was only introduced in 4.2.0 is really useful if I’m developing packages to know which version of R to depend on.</p>
<p>I also often visit the <a href="https://cran.r-project.org/bin/windows/base/old/">“Previous releases of R for Windows”</a> page to see <em>when</em> a version of R was released. This is to check if a version of R is more than three years old, which to me, is about old enough that people shouldn’t be depending on it on a regular basis, or if they are and it is mission critical, they would also have other things set up to maintain it. The tidyverse maintains backward compatibility with <a href="https://www.tidyverse.org/blog/2019/04/r-version-support/">the past 5 (minor) versions of R</a> - which ends up being about 4 years. I figure 3 years should be good enough for my work.</p>
</section>
<section id="yes-it-is-annoying-to-reinstall-r-packages-again." class="level1">
<h1>Yes, it <strong>is annoying</strong> to reinstall R packages again.</h1>
<p>When you install a new <strong>minor version</strong> of R (that is, when you change its minor version, for example going from 4.1.0 to 4.2.0, not 4.1.0 to 4.1.1), you need to install all your R packages again.</p>
<p>Sure, it’s annoying. But I see it as an opportunity to start afresh. I usually do something like the following</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" 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;">install.packages</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"pak"</span>)</span>
<span id="cb1-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(pak)</span>
<span id="cb1-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pkg_install</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"tidyverse"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dependencies =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>)</span>
<span id="cb1-4"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pkg_install</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"devtools"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dependencies =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>)</span>
<span id="cb1-5"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pkg_install</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"naniar"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dependencies =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>)</span>
<span id="cb1-6"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pkg_install</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"blogdown"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dependencies =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>)</span>
<span id="cb1-7"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pkg_install</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"greta"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dependencies =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>)</span>
<span id="cb1-8"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pkg_install</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"brolgar"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dependencies =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>)</span>
<span id="cb1-9"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pkg_install</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"targets"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dependencies =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>)</span>
<span id="cb1-10"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pkg_install</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ropensci/geotargets"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dependencies =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>)</span>
<span id="cb1-11"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pkg_install</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"milesmcbain/datapasta"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dependencies =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>)</span></code></pre></div></div>
<p>And this gets me 90% of the way there.</p>
<p>It is worth noting that if you’re a windows user, you can use the <a href="https://talgalili.github.io/installr/"><code>installr</code></a> package to update R and other dependencies.</p>
<p>And on that note it’s ALSO worth mentioning the <a href="https://github.com/r-lib/rig"><code>rig</code></a> command line utility. This allows you to more easily install different, and release versions of R. If you’ve seen <a href="https://github.com/hrbrmstr/RSwitch">Bob Rudis’s RSwitch</a> software, this is the updated version of this (Bob has archived RSwitch).</p>


</section>

 ]]></description>
  <category>rstats</category>
  <category>CRAN</category>
  <category>rse</category>
  <category>research software engineer</category>
  <guid>https://www.njtierney.com/posts/2025-04-14-r-version-4-5-0-is-out/</guid>
  <pubDate>Mon, 14 Apr 2025 00:00:00 GMT</pubDate>
</item>
<item>
  <title>{geotargets} 0.2.0</title>
  <link>https://www.njtierney.com/posts/2024-11-22-geotargets-0-2-0/</link>
  <description><![CDATA[ 
<header class="site-header">
  <h1 class="site-title">
    <a href="../../">
      <img class="hvr-grow site-logo" src="https://www.njtierney.com/assets/njt-logo-small.png" alt="Nick logo">
    </a>
    <span class="hvr-bob site-title-credibly">Credibly</span>
    <span class="hvr-hang site-title-curious">Curious</span>
  </h1>
  <p class="site-subtitle">
    Nick Tierney's (mostly) rstats blog
  </p>
  
</header>




<p>I’m super stoked to announce <a href="https://njtierney.github.io/geotargets/">{geotargets}</a> version 0.2.0! The <a href="https://njtierney.github.io/geotargets/">{geotargets}</a> package extends <a href="https://docs.ropensci.org/targets/">{targets}</a> to work with geospatial data formats.</p>
<p>I’d like to firstly acknowledge the strong work by <a href="https://ericrscott.com/">Eric Scott</a> on getting this release ready. I do want to emphasise that while post is on my website, this project is very much a team effort.</p>
<p>You can download <a href="https://njtierney.github.io/geotargets/">{geotargets}</a> from the R universe like so:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" 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;">install.packages</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"geotargets"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">repos =</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;">"https://njtierney.r-universe.dev"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://cran.r-project.org"</span>))</span></code></pre></div></div>
<section id="why-should-i-use-geotargets-and-targets" class="level1">
<h1>Why should I use geotargets and targets?</h1>
<p>You could benefit from using targets and geotargets if you do geospatial data analysis involving rasters or shapefiles, specifically with terra or stars R packages. For example, if you are doing large downloads of rasters, then operations like cropping, reprojection, resampling, and masking.</p>
<p>The main benefit to using targets and geotargets is your analysis will only rerun when you change relevant parts of your data analysis. For example, you might do a lot of geospatial data processing that feeds downstream into a machine learning model to make predictions on bushfire risk. Writing with targets and geotargets means if you change the parts of the code that related to the machine learning components, then only the relevant parts with machine learning would change. This means you can save time by avoiding running computational expensive spatial data processing.</p>
<p>For more details on what targets is, and why we need geotargets, I would recommend reading the <a href="https://www.njtierney.com/post/2024/05/27/geotargets-0-1-0/">0.1.0 release blog post</a>, as well as <a href="https://books.ropensci.org/targets/">reading the {targets} manual</a>. The <a href="https://github.com/ropensci/targets/?tab=readme-ov-file#get-started-in-4-minutes">“Get started in 4 minutes”</a> guide to targets is also excellent.</p>
</section>
<section id="main-changes-in-0.2.0" class="level1">
<h1>Main changes in 0.2.0?</h1>
<p>In addition to smaller changes and improvements, there are three main additions in this release:</p>
<ul>
<li>Support for <a href="https://books.ropensci.org/targets/dynamic.html#about-dynamic-branching">dynamic branching</a>.</li>
<li>Preserving spatRaster metadata.</li>
<li>Support of <code>stars</code> and <code>stars_proxy</code>.</li>
</ul>
<p>And very in very exciting news, we have a new hex sticker!</p>
<p>Thanks to <a href="https://www.linkedin.com/in/huberthalun/?originalSubdomain=pl">Hubert Hałun</a> for their work on getting this together, we are really happy with the new sticker!</p>
<figure class="figure">
<img src="https://www.njtierney.com/posts/2024-11-22-geotargets-0-2-0/figs/Geotarget_Hex.png" alt="geotargets hex sticker" class="figure-img">

</figure>
<section id="dynamic-branching" class="level2">
<h2 class="anchored" data-anchor-id="dynamic-branching">Dynamic Branching</h2>
<p>The main addition in this release is a demonstration of using <a href="https://books.ropensci.org/targets/dynamic.html#about-dynamic-branching">dynamic branching</a> using a new “target factory” function, <a href="https://njtierney.github.io/geotargets/reference/tar_terra_tiles.html"><code>tar_terra_tiles()</code></a>. This allows you to break raster operations into tiles, and then perform these operations on the tiles and combine them together. This means we can break computationally intensive raster operations that work in pixel-wise manner over tiled subsets of the raster. This is useful when, for example, loading an entire raster into memory and doing computations on it results in out of memory errors.</p>
<p>As part of this addition, we created helper functions:</p>
<ul>
<li><a href="https://njtierney.github.io/geotargets/reference/tile_helpers.html"><code>tile_n()</code></a></li>
<li><a href="https://njtierney.github.io/geotargets/reference/tile_helpers.html"><code>tile_grid()</code></a>, and</li>
<li><a href="https://njtierney.github.io/geotargets/reference/tile_helpers.html"><code>tile_blocksize()</code></a>.</li>
</ul>
<p>These help us define different extents that we can pass along as different parts of the dynamic branches. You can think of these as tools that we can use to specify how to slice, or tile up, a raster into smaller pieces that we can then do analysis on separately and combine later.</p>
<p>Let’s briefly unpack these, and then show how these would be used in dynamic branching. First let’s read in some example elevation data from terra and plot it:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">f</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/system.file.html">system.file</a></span><span class="o">(</span><span class="s">"ex/elev.tif"</span>, package<span class="o">=</span><span class="s">"terra"</span><span class="o">)</span></span>
<span><span class="nv">r</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rspatial.github.io/terra/reference/rast.html">rast</a></span><span class="o">(</span><span class="nv">f</span><span class="o">)</span></span>
<span><span class="nf"><a href="https://rspatial.github.io/terra/reference/plot.html">plot</a></span><span class="o">(</span><span class="nv">r</span><span class="o">)</span></span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2024-11-22-geotargets-0-2-0/figs/unnamed-chunk-1-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<section id="tile_n" class="level3">
<h3 class="anchored" data-anchor-id="tile_n"><code>tile_n()</code></h3>
<p>We can use <a href="https://njtierney.github.io/geotargets/reference/tile_helpers.html"><code>tile_n()</code></a>, which is the simplest of the three. It produces <em>about</em> <code>n</code> tiles in a grid.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">r_tile_4</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://njtierney.github.io/geotargets/reference/tile_helpers.html">tile_n</a></span><span class="o">(</span><span class="nv">r</span>, <span class="m">4</span><span class="o">)</span></span>
<span><span class="c">#&gt; creating 2 * 2 = 4 tile extents</span></span>
<span></span><span><span class="nv">r_tile_4</span></span>
<span><span class="c">#&gt; [[1]]</span></span>
<span><span class="c">#&gt;      xmin      xmax      ymin      ymax </span></span>
<span><span class="c">#&gt;  5.741667  6.141667 49.816667 50.191667 </span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt; [[2]]</span></span>
<span><span class="c">#&gt;      xmin      xmax      ymin      ymax </span></span>
<span><span class="c">#&gt;  6.141667  6.533333 49.816667 50.191667 </span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt; [[3]]</span></span>
<span><span class="c">#&gt;      xmin      xmax      ymin      ymax </span></span>
<span><span class="c">#&gt;  5.741667  6.141667 49.441667 49.816667 </span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt; [[4]]</span></span>
<span><span class="c">#&gt;      xmin      xmax      ymin      ymax </span></span>
<span><span class="c">#&gt;  6.141667  6.533333 49.441667 49.816667</span></span>
<span></span></code></pre>
</div>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="c"># some plot helpers</span></span>
<span><span class="nv">rect_extent</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">x</span>, <span class="nv">...</span><span class="o">)</span> <span class="o">{</span></span>
<span>  <span class="nf"><a href="https://rdrr.io/r/graphics/rect.html">rect</a></span><span class="o">(</span><span class="nv">x</span><span class="o">[</span><span class="m">1</span><span class="o">]</span>, <span class="nv">x</span><span class="o">[</span><span class="m">3</span><span class="o">]</span>, <span class="nv">x</span><span class="o">[</span><span class="m">2</span><span class="o">]</span>, <span class="nv">x</span><span class="o">[</span><span class="m">4</span><span class="o">]</span>, <span class="nv">...</span><span class="o">)</span></span>
<span><span class="o">}</span></span>
<span><span class="nv">plot_extents</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">x</span>, <span class="nv">...</span><span class="o">)</span> <span class="o">{</span></span>
<span>  <span class="nf"><a href="https://rdrr.io/r/base/invisible.html">invisible</a></span><span class="o">(</span><span class="nf"><a href="https://rdrr.io/r/base/lapply.html">lapply</a></span><span class="o">(</span><span class="nv">x</span>, <span class="nv">rect_extent</span>, border <span class="o">=</span> <span class="s">"hotpink"</span>, lwd <span class="o">=</span> <span class="m">2</span><span class="o">)</span><span class="o">)</span></span>
<span><span class="o">}</span></span></code></pre>
</div>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://rspatial.github.io/terra/reference/plot.html">plot</a></span><span class="o">(</span><span class="nv">r</span><span class="o">)</span></span>
<span><span class="nf">plot_extents</span><span class="o">(</span><span class="nv">r_tile_4</span><span class="o">)</span></span>
</code></pre>
<img src="https://www.njtierney.com/posts/2024-11-22-geotargets-0-2-0/figs/unnamed-chunk-4-1.png" width="700px" style="display: block; margin: auto;">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://rspatial.github.io/terra/reference/plot.html">plot</a></span><span class="o">(</span><span class="nv">r</span><span class="o">)</span></span>
<span><span class="nf"><a href="https://njtierney.github.io/geotargets/reference/tile_helpers.html">tile_n</a></span><span class="o">(</span><span class="nv">r</span>, <span class="m">6</span><span class="o">)</span> <span class="o">|&gt;</span> <span class="nf">plot_extents</span><span class="o">(</span><span class="o">)</span></span>
<span><span class="c">#&gt; creating 2 * 3 = 6 tile extents</span></span>
<span></span></code></pre>
<p><img src="https://www.njtierney.com/posts/2024-11-22-geotargets-0-2-0/figs/unnamed-chunk-4-2.png" width="700px" style="display: block; margin: auto;"></p>
</div>
</section>
<section id="tile_grid" class="level3">
<h3 class="anchored" data-anchor-id="tile_grid"><code>tile_grid()</code></h3>
<p>For more control, use <a href="https://njtierney.github.io/geotargets/reference/tile_helpers.html"><code>tile_grid()</code></a>, which allows specification of the number of rows and columns to split the raster into. Here we are specify that we want three columns and 1 row:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">r_grid_3x1</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://njtierney.github.io/geotargets/reference/tile_helpers.html">tile_grid</a></span><span class="o">(</span><span class="nv">r</span>, ncol <span class="o">=</span> <span class="m">3</span>, nrow <span class="o">=</span> <span class="m">1</span><span class="o">)</span></span>
<span><span class="nv">r_grid_3x1</span></span>
<span><span class="c">#&gt; [[1]]</span></span>
<span><span class="c">#&gt;      xmin      xmax      ymin      ymax </span></span>
<span><span class="c">#&gt;  5.741667  6.008333 49.441667 50.191667 </span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt; [[2]]</span></span>
<span><span class="c">#&gt;      xmin      xmax      ymin      ymax </span></span>
<span><span class="c">#&gt;  6.008333  6.266667 49.441667 50.191667 </span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt; [[3]]</span></span>
<span><span class="c">#&gt;      xmin      xmax      ymin      ymax </span></span>
<span><span class="c">#&gt;  6.266667  6.533333 49.441667 50.191667</span></span>
<span></span><span><span class="nf"><a href="https://rspatial.github.io/terra/reference/plot.html">plot</a></span><span class="o">(</span><span class="nv">r</span><span class="o">)</span></span>
<span><span class="nf">plot_extents</span><span class="o">(</span><span class="nv">r_grid_3x1</span><span class="o">)</span></span>
</code></pre>
<img src="https://www.njtierney.com/posts/2024-11-22-geotargets-0-2-0/figs/unnamed-chunk-5-1.png" width="700px" style="display: block; margin: auto;">
<pre class="chroma"><code class="language-r" data-lang="r"><span></span>
<span><span class="nf"><a href="https://rspatial.github.io/terra/reference/plot.html">plot</a></span><span class="o">(</span><span class="nv">r</span><span class="o">)</span></span>
<span><span class="nf"><a href="https://njtierney.github.io/geotargets/reference/tile_helpers.html">tile_grid</a></span><span class="o">(</span><span class="nv">r</span>, ncol <span class="o">=</span> <span class="m">2</span>, nrow <span class="o">=</span> <span class="m">3</span><span class="o">)</span> <span class="o">|&gt;</span> <span class="nf">plot_extents</span><span class="o">(</span><span class="o">)</span></span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2024-11-22-geotargets-0-2-0/figs/unnamed-chunk-5-2.png" width="700px" style="display: block; margin: auto;"></p>
</div>
</section>
<section id="tile_blocksize" class="level3">
<h3 class="anchored" data-anchor-id="tile_blocksize"><code>tile_blocksize()</code></h3>
<p>The third included helper is <a href="https://njtierney.github.io/geotargets/reference/tile_helpers.html"><code>tile_blocksize()</code></a>, which tiles by file <strong>block size</strong>. The <strong>block size</strong> is a property of raster files, and is the number of pixels (in the x and y direction) that is read into memory at a time. Tiling by multiples of block size may therefore be more efficient because only one block should need to be loaded to create each tile target. You can find the blocksize with <code>fileBlocksize</code>:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://rspatial.github.io/terra/reference/readwrite.html">fileBlocksize</a></span><span class="o">(</span><span class="nv">r</span><span class="o">)</span></span>
<span><span class="c">#&gt;      rows cols</span></span>
<span><span class="c">#&gt; [1,]   43   95</span></span>
<span></span></code></pre>
</div>
<p>This tells us that it reads in the raster in 43x95 pixel sizes.</p>
<p>The <code>tile_blocksize</code> function is similar to <code>tile_grid</code>, except instead of saying how many rows and columns, we specify in units of blocksize.</p>
<p>If we just run <a href="https://njtierney.github.io/geotargets/reference/tile_helpers.html"><code>tile_blocksize()</code></a> on <code>r</code> we get the extents of the specified blocksize:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://njtierney.github.io/geotargets/reference/tile_helpers.html">tile_blocksize</a></span><span class="o">(</span><span class="nv">r</span><span class="o">)</span></span>
<span><span class="c">#&gt; [[1]]</span></span>
<span><span class="c">#&gt;      xmin      xmax      ymin      ymax </span></span>
<span><span class="c">#&gt;  5.741667  6.533333 49.833333 50.191667 </span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt; [[2]]</span></span>
<span><span class="c">#&gt;      xmin      xmax      ymin      ymax </span></span>
<span><span class="c">#&gt;  5.741667  6.533333 49.475000 49.833333 </span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt; [[3]]</span></span>
<span><span class="c">#&gt;      xmin      xmax      ymin      ymax </span></span>
<span><span class="c">#&gt;  5.741667  6.533333 49.441667 49.475000</span></span>
<span></span></code></pre>
</div>
<p>Which is the same as specifying blocksize for row and column at unit 1:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">r_block_size_1x1</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://njtierney.github.io/geotargets/reference/tile_helpers.html">tile_blocksize</a></span><span class="o">(</span><span class="nv">r</span>, n_blocks_row <span class="o">=</span> <span class="m">1</span>, n_blocks_col <span class="o">=</span> <span class="m">1</span><span class="o">)</span></span>
<span><span class="nv">r_block_size_1x1</span></span>
<span><span class="c">#&gt; [[1]]</span></span>
<span><span class="c">#&gt;      xmin      xmax      ymin      ymax </span></span>
<span><span class="c">#&gt;  5.741667  6.533333 49.833333 50.191667 </span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt; [[2]]</span></span>
<span><span class="c">#&gt;      xmin      xmax      ymin      ymax </span></span>
<span><span class="c">#&gt;  5.741667  6.533333 49.475000 49.833333 </span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt; [[3]]</span></span>
<span><span class="c">#&gt;      xmin      xmax      ymin      ymax </span></span>
<span><span class="c">#&gt;  5.741667  6.533333 49.441667 49.475000</span></span>
<span></span><span><span class="nf"><a href="https://rspatial.github.io/terra/reference/plot.html">plot</a></span><span class="o">(</span><span class="nv">r</span><span class="o">)</span></span>
<span><span class="nf">plot_extents</span><span class="o">(</span><span class="nv">r_block_size_1x1</span><span class="o">)</span></span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2024-11-22-geotargets-0-2-0/figs/unnamed-chunk-8-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>Here the block size is the same size for the first two blocks, and then a much more narrow block. This is different to the two other tile methods.</p>
<p>Here the column block size is the full width of the raster.</p>
<p>So we could instead have the blocksize extent be written out to 2 blocks in a row, and 1 block size for the columns:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">r_block_size_2x1</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://njtierney.github.io/geotargets/reference/tile_helpers.html">tile_blocksize</a></span><span class="o">(</span><span class="nv">r</span>, n_blocks_row <span class="o">=</span> <span class="m">2</span>, n_blocks_col <span class="o">=</span> <span class="m">1</span><span class="o">)</span></span>
<span><span class="nv">r_block_size_2x1</span></span>
<span><span class="c">#&gt; [[1]]</span></span>
<span><span class="c">#&gt;      xmin      xmax      ymin      ymax </span></span>
<span><span class="c">#&gt;  5.741667  6.533333 49.475000 50.191667 </span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt; [[2]]</span></span>
<span><span class="c">#&gt;      xmin      xmax      ymin      ymax </span></span>
<span><span class="c">#&gt;  5.741667  6.533333 49.441667 49.475000</span></span>
<span></span><span><span class="nf"><a href="https://rspatial.github.io/terra/reference/plot.html">plot</a></span><span class="o">(</span><span class="nv">r</span><span class="o">)</span></span>
<span><span class="nf">plot_extents</span><span class="o">(</span><span class="nv">r_block_size_2x1</span><span class="o">)</span></span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2024-11-22-geotargets-0-2-0/figs/unnamed-chunk-9-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>This only works when the <code>SpatRaster</code> points to a file—in-memory rasters have no inherent block size.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://rspatial.github.io/terra/reference/sources.html">sources</a></span><span class="o">(</span><span class="nv">r</span><span class="o">)</span></span>
<span><span class="c">#&gt; [1] "/Users/nick/Library/R/arm64/4.4/library/terra/ex/elev.tif"</span></span>
<span></span><span><span class="c">#force into memory</span></span>
<span><span class="nv">r2</span> <span class="o">&lt;-</span> <span class="nv">r</span> <span class="o">+</span> <span class="m">0</span></span>
<span><span class="nf"><a href="https://rspatial.github.io/terra/reference/sources.html">sources</a></span><span class="o">(</span><span class="nv">r2</span><span class="o">)</span></span>
<span><span class="c">#&gt; [1] ""</span></span>
<span></span><span><span class="c">#this now errors</span></span>
<span><span class="nf"><a href="https://njtierney.github.io/geotargets/reference/tile_helpers.html">tile_blocksize</a></span><span class="o">(</span><span class="nv">r2</span><span class="o">)</span></span>
<span><span class="c">#&gt; Error: [aggregate] values in argument 'fact' should be &gt; 0</span></span>
<span></span></code></pre>
</div>
<p>For more detail on using this in targets, please see the geotargets vignette, <a href="https://njtierney.github.io/geotargets/articles/tar_terra_tiles.html">“Dynamic branching with raster tiles”</a></p>
</section>
</section>
<section id="preserving-spatraster-metadata" class="level2">
<h2 class="anchored" data-anchor-id="preserving-spatraster-metadata">Preserving spatRaster metadata</h2>
<p><a href="https://njtierney.github.io/geotargets/reference/tar_terra_rast.html"><code>tar_terra_rast()</code></a> gains a <code>preserve_metadata</code> option that when set to <code>"zip"</code> reads/writes targets as zip archives that include aux.json “sidecar” files sometimes written by <code>terra</code> (<a href="https://github.com/njtierney/geotargets/issues/58">#58</a>).</p>
</section>
<section id="support-of-stars-and-stars_proxy" class="level2">
<h2 class="anchored" data-anchor-id="support-of-stars-and-stars_proxy">Support of <code>stars</code> and <code>stars_proxy</code></h2>
<p>We have created <a href="https://njtierney.github.io/geotargets/reference/tar_stars.html"><code>tar_stars()</code></a> and <a href="https://njtierney.github.io/geotargets/reference/tar_stars.html"><code>tar_stars_proxy()</code></a> that create <code>stars</code> and <code>stars_proxy</code> objects, respectively. These are currently experimental.</p>
</section>
</section>
<section id="minor-changes-in-0.2.0" class="level1">
<h1>Minor changes in 0.2.0</h1>
<p>Other changes include:</p>
<ul>
<li>Created utility function <a href="https://njtierney.github.io/geotargets/reference/set_window.html"><code>set_window()</code></a> mostly for internal use within <a href="https://njtierney.github.io/geotargets/reference/tar_terra_tiles.html"><code>tar_terra_tiles()</code></a>.</li>
<li>Removes the <code>iteration</code> argument from all <code>tar_*()</code> functions. <code>iteration</code> now hard-coded as <code>"list"</code> since it is the only option that works (for now at least).</li>
<li>Added the <code>description</code> argument to all <code>tar_*()</code> functions which is passed to <a href="https://docs.ropensci.org/targets/reference/tar_target.html"><code>tar_target()</code></a>.</li>
<li>Suppressed the warning “[rast] skipped sub-datasets” from <a href="https://njtierney.github.io/geotargets/reference/tar_terra_sprc.html"><code>tar_terra_sprc()</code></a>, which is misleading in this context (<a href="https://github.com/njtierney/geotargets/issues/92">#92</a>, <a href="https://github.com/njtierney/geotargets/issues/104">#104</a>).</li>
<li>Requires GDAL 3.1 or greater to use “ESRI Shapefile” driver in <a href="https://njtierney.github.io/geotargets/reference/tar_terra_vect.html"><code>tar_terra_vect()</code></a> (<a href="https://github.com/njtierney/geotargets/issues/71">#71</a>, <a href="https://github.com/njtierney/geotargets/pull/97">#97</a>)</li>
<li><code>geotargets</code> now requires <code>targets</code> version 1.8.0 or higher</li>
<li><code>terra</code> (&gt;= 1.7.71), <code>withr</code> (&gt;= 3.0.0), and <code>zip</code> are now required dependencies of <code>geotargets</code> (moved from <code>Suggests</code> to <code>Imports</code>)</li>
</ul>
</section>
<section id="whats-next" class="level1">
<h1>What’s next?</h1>
<p>We have finished developing the main milestones for geotargets, but will continue actively developing it. Soon we will be submitting the package for review by rOpenSci, and subsequently submit the work to the Journal of Open Source Software (JOSS), and then submit to CRAN.</p>
<p>Currently, the next release will focus on adding support for:</p>
<ul>
<li><p><a href="https://github.com/njtierney/geotargets/issues/110">Add support for ArcGIS services using {arcgislayers}</a></p></li>
<li><p><a href="https://github.com/njtierney/geotargets/issues/112">Adding support for tar_terra_rast on cloud storage</a></p></li>
<li><p><a href="https://github.com/njtierney/geotargets/issues/48">explore support for {gdalraster}</a></p></li>
<li><p><a href="https://github.com/njtierney/geotargets/issues/42">Add support for terra SpatVectorProxy, and format=“file” for SpatRaster</a></p></li>
</ul>
<p>You can see the <a href="https://github.com/njtierney/geotargets/issues">full list of issues</a> for more detail on what we are working on.</p>
</section>
<section id="thanks" class="level1">
<h1>Thanks</h1>
<p>We would like to thank the R Consortium for generously supporting this project, “<a href="https://github.com/cct-datascience/geotargets-isc-proposal">{geotargets}: Enabling geospatial workflow management with {targets}”</a>.</p>
<p>We would also like to thank <a href="https://github.com/mdsumner">Michael Sumner</a>, <a href="https://github.com/anthonynorth">Anthony North</a>, and <a href="https://milesmcbain.xyz/">Miles McBain</a> for their helpful discussions throughout, as well as <a href="https://wlandau.github.io/">Will Landau</a> for writing targets, and being incredibly responsive and helpful to the issues and questions we have asked as we wrote <a href="https://njtierney.github.io/geotargets/">{geotargets}</a>.</p>


</section>

 ]]></description>
  <category>rstats</category>
  <category>functions</category>
  <guid>https://www.njtierney.com/posts/2024-11-22-geotargets-0-2-0/</guid>
  <pubDate>Wed, 27 Nov 2024 00:00:00 GMT</pubDate>
</item>
<item>
  <title>{geotargets} 0.1.0</title>
  <link>https://www.njtierney.com/posts/2024-05-16-geotargets-0-1-0/</link>
  <description><![CDATA[ 
<header class="site-header">
  <h1 class="site-title">
    <a href="../../">
      <img class="hvr-grow site-logo" src="https://www.njtierney.com/assets/njt-logo-small.png" alt="Nick logo">
    </a>
    <span class="hvr-bob site-title-credibly">Credibly</span>
    <span class="hvr-hang site-title-curious">Curious</span>
  </h1>
  <p class="site-subtitle">
    Nick Tierney's (mostly) rstats blog
  </p>
  
</header>




<p>I’m very happy to announce <a href="https://njtierney.github.io/geotargets/">{geotargets}</a> version 0.1.0! The <a href="https://njtierney.github.io/geotargets/">{geotargets}</a> package extends <a href="https://docs.ropensci.org/targets/">{targets}</a> to work with geospatial data formats. Version 0.1.0 supports <a href="https://rspatial.github.io/terra/reference/vect.html"><code>terra::vect()</code></a>, <a href="https://rspatial.github.io/terra/reference/rast.html"><code>terra::rast()</code></a> and <a href="https://rspatial.github.io/terra/reference/sprc.html"><code>terra::sprc()</code></a> formats. This R package is only possible due to the great work by <a href="https://ericrscott.com/">Eric Scott</a> and <a href="https://humus.rocks/">Andrew Brown</a>. While this blog post is on my website, I want to emphasise that this project is very much a team effort.</p>
<p>You can download <a href="https://njtierney.github.io/geotargets/">{geotargets}</a> from the R universe like so:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" 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;">install.packages</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"geotargets"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">repos =</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;">"https://njtierney.r-universe.dev"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://cran.r-project.org"</span>))</span></code></pre></div></div>
<section id="what-is-targets-why-do-i-need-geotargets" class="level1">
<h1>What is targets? Why do I need geotargets?</h1>
<p>The targets package is an R package for managing analytic pipelines. It means that you can write out an analysis in a specific manner, and then as you update code, it will only rerun the necessary parts. Essentially it helps you avoid running large pieces of analysis when you don’t need to. To learn more about targets, I’d highly recommend <a href="https://books.ropensci.org/targets/">reading the {targets} manual</a>.</p>
<p>Let’s show an example. Let’s say we want to get an example raster file from <a href="https://rspatial.github.io/terra/">{terra}</a>, we can do the following:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">terra_rast_example</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/system.file.html">system.file</a></span><span class="o">(</span></span>
<span>  <span class="s">"ex/elev.tif"</span>, </span>
<span>  package <span class="o">=</span> <span class="s">"terra"</span></span>
<span>  <span class="o">)</span> <span class="o">|&gt;</span></span>
<span>  <span class="nf">terra</span><span class="nf">::</span><span class="nf"><a href="https://rspatial.github.io/terra/reference/rast.html">rast</a></span><span class="o">(</span><span class="o">)</span></span>
<span></span>
<span><span class="nv">terra_rast_example</span></span>
<span><span class="c">#&gt; class       : SpatRaster </span></span>
<span><span class="c">#&gt; dimensions  : 90, 95, 1  (nrow, ncol, nlyr)</span></span>
<span><span class="c">#&gt; resolution  : 0.008333333, 0.008333333  (x, y)</span></span>
<span><span class="c">#&gt; extent      : 5.741667, 6.533333, 49.44167, 50.19167  (xmin, xmax, ymin, ymax)</span></span>
<span><span class="c">#&gt; coord. ref. : lon/lat WGS 84 (EPSG:4326) </span></span>
<span><span class="c">#&gt; source      : elev.tif </span></span>
<span><span class="c">#&gt; name        : elevation </span></span>
<span><span class="c">#&gt; min value   :       141 </span></span>
<span><span class="c">#&gt; max value   :       547</span></span>
<span></span></code></pre>
</div>
<p>Here is the equivalent code in a targets pipeline - the reason we want to use <a href="https://books.ropensci.org/targets/">{targets}</a> here is we save the results so we don’t need to run them again. In this case the example code doesn’t take long to run. But imagine reading in the raster was hugely time and computer expensive and we didn’t want to do it again. The <a href="https://books.ropensci.org/targets/">{targets}</a> package stores the information so we can just read it back in later, and if we try and run the code again it will not update the code unless the data input has changed. Neat, right?</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://docs.ropensci.org/targets/">targets</a></span><span class="o">)</span></span>
<span><span class="nf"><a href="https://docs.ropensci.org/targets/reference/tar_dir.html">tar_dir</a></span><span class="o">(</span><span class="o">{</span> <span class="c"># tar_dir() runs code from a temporary directory.</span></span>
<span>  <span class="nf"><a href="https://docs.ropensci.org/targets/reference/tar_script.html">tar_script</a></span><span class="o">(</span><span class="o">{</span></span>
<span>    <span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://docs.ropensci.org/targets/">targets</a></span><span class="o">)</span></span>
<span>    <span class="nf"><a href="https://rdrr.io/r/base/list.html">list</a></span><span class="o">(</span></span>
<span>      <span class="nf"><a href="https://docs.ropensci.org/targets/reference/tar_target.html">tar_target</a></span><span class="o">(</span></span>
<span>        <span class="nv">terra_rast_example</span>,</span>
<span>        <span class="nf"><a href="https://rdrr.io/r/base/system.file.html">system.file</a></span><span class="o">(</span><span class="s">"ex/elev.tif"</span>, package <span class="o">=</span> <span class="s">"terra"</span><span class="o">)</span> <span class="o">|&gt;</span> <span class="nf">terra</span><span class="nf">::</span><span class="nf"><a href="https://rspatial.github.io/terra/reference/rast.html">rast</a></span><span class="o">(</span><span class="o">)</span></span>
<span>      <span class="o">)</span></span>
<span>    <span class="o">)</span></span>
<span>  <span class="o">}</span><span class="o">)</span></span>
<span>  <span class="nf"><a href="https://docs.ropensci.org/targets/reference/tar_make.html">tar_make</a></span><span class="o">(</span><span class="o">)</span></span>
<span>  <span class="nv">x</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://docs.ropensci.org/targets/reference/tar_read.html">tar_read</a></span><span class="o">(</span><span class="nv">terra_rast_example</span><span class="o">)</span></span>
<span>  <span class="nv">x</span></span>
<span><span class="o">}</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #BB0000;">▶ dispatched target terra_rast_example</span></span></span>
<span><span class="c"><span style="color: #BB0000;">#&gt; ● completed target terra_rast_example [1.196 seconds]</span></span></span>
<span><span class="c"><span style="color: #BB0000;">#&gt; ▶ ended pipeline [1.825 seconds]</span></span></span>
<span><span class="c"><span style="color: #BB0000;">#&gt; </span></span></span>
<span></span><span><span class="c">#&gt; class       : SpatRaster</span></span>
<span></span><span><span class="c">#&gt; Error: external pointer is not valid</span></span>
<span></span></code></pre>
</div>
<p>We get an error!</p>
<pre><code>Error: external pointer is not valid</code></pre>
<p>This is a relatively common gotcha moment when using libraries like <a href="https://rspatial.github.io/terra/">{terra}</a>. This is due to limitations with its underlying C++ implementation. There are specific ways to write and read these objects. See <code>?terra</code> for details.</p>
<p>But how do we use <a href="https://njtierney.github.io/geotargets/">{geotargets}</a> to help with this? It helps handle these write and read steps, so you don’t have to worry about them and can use targets as you are used to.</p>
<p>So instead of <a href="https://docs.ropensci.org/targets/reference/tar_target.html"><code>tar_target()</code></a>, you use <a href="https://njtierney.github.io/geotargets/reference/tar_terra_rast.html"><code>tar_terra_rast()</code></a> to save a <a href="https://rspatial.github.io/terra/">{terra}</a> raster:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://docs.ropensci.org/targets/">targets</a></span><span class="o">)</span></span>
<span><span class="nf"><a href="https://docs.ropensci.org/targets/reference/tar_dir.html">tar_dir</a></span><span class="o">(</span><span class="o">{</span> <span class="c"># tar_dir() runs code from a temporary directory.</span></span>
<span>  <span class="nf"><a href="https://docs.ropensci.org/targets/reference/tar_script.html">tar_script</a></span><span class="o">(</span><span class="o">{</span></span>
<span>    <span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://docs.ropensci.org/targets/">targets</a></span><span class="o">)</span></span>
<span>    <span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://github.com/njtierney/geotargets">geotargets</a></span><span class="o">)</span></span>
<span>    <span class="nf"><a href="https://rdrr.io/r/base/list.html">list</a></span><span class="o">(</span></span>
<span>      <span class="nf"><a href="https://njtierney.github.io/geotargets/reference/tar_terra_rast.html">tar_terra_rast</a></span><span class="o">(</span></span>
<span>        <span class="nv">terra_rast_example</span>,</span>
<span>        <span class="nf"><a href="https://rdrr.io/r/base/system.file.html">system.file</a></span><span class="o">(</span><span class="s">"ex/elev.tif"</span>, package <span class="o">=</span> <span class="s">"terra"</span><span class="o">)</span> <span class="o">|&gt;</span> <span class="nf">terra</span><span class="nf">::</span><span class="nf"><a href="https://rspatial.github.io/terra/reference/rast.html">rast</a></span><span class="o">(</span><span class="o">)</span></span>
<span>      <span class="o">)</span></span>
<span>    <span class="o">)</span></span>
<span>  <span class="o">}</span><span class="o">)</span></span>
<span>  <span class="nf"><a href="https://docs.ropensci.org/targets/reference/tar_make.html">tar_make</a></span><span class="o">(</span><span class="o">)</span></span>
<span>  <span class="nv">x</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://docs.ropensci.org/targets/reference/tar_read.html">tar_read</a></span><span class="o">(</span><span class="nv">terra_rast_example</span><span class="o">)</span></span>
<span>  <span class="nv">x</span></span>
<span><span class="o">}</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #BB0000;">▶ dispatched target terra_rast_example</span></span></span>
<span><span class="c"><span style="color: #BB0000;">#&gt; ● completed target terra_rast_example [0.006 seconds]</span></span></span>
<span><span class="c"><span style="color: #BB0000;">#&gt; ▶ ended pipeline [0.061 seconds]</span></span></span>
<span><span class="c"><span style="color: #BB0000;">#&gt; </span></span></span>
<span></span><span><span class="c">#&gt; class       : SpatRaster </span></span>
<span><span class="c">#&gt; dimensions  : 90, 95, 1  (nrow, ncol, nlyr)</span></span>
<span><span class="c">#&gt; resolution  : 0.008333333, 0.008333333  (x, y)</span></span>
<span><span class="c">#&gt; extent      : 5.741667, 6.533333, 49.44167, 50.19167  (xmin, xmax, ymin, ymax)</span></span>
<span><span class="c">#&gt; coord. ref. : lon/lat WGS 84 (EPSG:4326) </span></span>
<span><span class="c">#&gt; source      : terra_rast_example </span></span>
<span><span class="c">#&gt; name        : elevation </span></span>
<span><span class="c">#&gt; min value   :       141 </span></span>
<span><span class="c">#&gt; max value   :       547</span></span>
<span></span></code></pre>
</div>
<p>Similarly, there are <a href="https://njtierney.github.io/geotargets/reference/tar_terra_vect.html"><code>tar_terra_vect()</code></a> and <a href="https://njtierney.github.io/geotargets/reference/tar_terra_sprc.html"><code>tar_terra_sprc()</code></a> for dealing with vector (shapefile) and sprc (collections of rasters). See the <a href="https://github.com/njtierney/geotargets?tab=readme-ov-file#examples">README example</a> for more information.</p>
<p>If you’d like to see these functions being used in a more practical context, see the <a href="https://github.com/njtierney/demo-geotargets">demo-geotargets</a> repository.</p>
</section>
<section id="whats-next" class="level1">
<h1>What’s next?</h1>
<p>We are actively developing <a href="https://njtierney.github.io/geotargets/">{geotargets}</a>, and the next release will focus on adding support for <a href="https://github.com/njtierney/geotargets/pull/76">splitting rasters into tiles</a>, <a href="https://github.com/njtierney/geotargets/pull/63">preserving SpatRaster metadata</a>, and adding <a href="https://github.com/njtierney/geotargets/pull/33">support for {stars}</a>. You can see the <a href="https://github.com/njtierney/geotargets/issues">full list of issues</a> for more detail on what we are working on.</p>
</section>
<section id="thanks" class="level1">
<h1>Thanks</h1>
<p>We have recently generously received support from the R Consortium for our project, <a href="https://github.com/cct-datascience/geotargets-isc-proposal">“{geotargets}: Enabling geospatial workflow management with {targets}”</a>, and so we would like to thank them for their support.</p>
<p>I’d also like to thank <a href="https://github.com/mdsumner">Michael Sumner</a>, <a href="https://github.com/anthonynorth">Anthony North</a>, and <a href="https://milesmcbain.xyz/">Miles McBain</a> for their helpful discussions, as well as <a href="https://wlandau.github.io/">Will Landau</a> for writing targets, and being incredibly responsive and helpful to the issues and questions we have asked as we wrote <a href="https://njtierney.github.io/geotargets/">{geotargets}</a>.</p>


</section>

 ]]></description>
  <category>geospatial</category>
  <category>rstats</category>
  <category>targets</category>
  <category>packages</category>
  <guid>https://www.njtierney.com/posts/2024-05-16-geotargets-0-1-0/</guid>
  <pubDate>Mon, 27 May 2024 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Find Out How many Times Faster your Code is</title>
  <link>https://www.njtierney.com/posts/2024-05-17-summary-benchmark/</link>
  <description><![CDATA[ 
<header class="site-header">
  <h1 class="site-title">
    <a href="../../">
      <img class="hvr-grow site-logo" src="https://www.njtierney.com/assets/njt-logo-small.png" alt="Nick logo">
    </a>
    <span class="hvr-bob site-title-credibly">Credibly</span>
    <span class="hvr-hang site-title-curious">Curious</span>
  </h1>
  <p class="site-subtitle">
    Nick Tierney's (mostly) rstats blog
  </p>
  
</header>




<div class="highlight">
<p><img src="https://www.njtierney.com/posts/2024-05-17-summary-benchmark/blinds.jpg" width="700px" style="display: block; margin: auto;"></p>
</div>
<p><em>My venetian blinds, in black and white</em></p>
<p>I recently watched <a href="https://josiahparry.com/">Josiah Parry’s</a> wonderful video, <a href="https://www.youtube.com/watch?v=-v9qaqaj4Ug">“Making R 300x times faster!”</a> It’s a great demonstration of how to rewrite code to be faster, and it’s worth your time. He rewrites some R code to be faster, then improves the speed again by writing some Rust code, which is called from R. He gets a 300 times speedup, which is really awesome.</p>
<p>Then someone writes in with an example of some code that is even faster than that, just using R code. It ends up being about 6 times faster than his Rust code. So a (300x6) 2000 times speed up. The main thing that helped with that was ensuring to vectorise your R code. Essentially, not working on the rows, but instead working on the columns.</p>
<p>Throughout the video Josiah makes good use of the <a href="https://github.com/r-lib/bench"><code>bench</code></a> R package to evaluate how much faster your code is. This idea is called “microbenchmarking”, and it involves running your code many times to evaluate how much faster it is than some other option. The reason you want to run your code many times is there is often variation around the runtimes in your code, so you don’t just want to base your improvements around a single measurement. It’s a general standard approach to attempt tp truly compare your approach to another.</p>
<p>All this being said, you should be wary of trying to make your code fast first without good reason. You want to make sure your code does the right thing first. Don’t just start trying to write performant code. Or as <a href="https://en.wikiquote.org/wiki/Donald_Knuth">Donald Knuth</a> says:</p>
<blockquote class="blockquote">
<p>“The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; <strong>premature optimization is the root of all evil (or at least most of it) in programming.</strong>”.</p>
</blockquote>
<p>If you want to learn more about how to speed up your code, I think it’s worthwhile reading up on the <a href="https://adv-r.hadley.nz/perf-measure.html">measuring performance</a> chapter in Advanced R.</p>
<section id="an-example-microbenchmark" class="level1">
<h1>An example microbenchmark</h1>
<p>Let’s take an example from the <a href="https://naniar.njtierney.com/"><code>naniar</code></a> package. I’ll give more detail of this story of this optimisation at the end of this section. For the moment, let’s say we want to get the number of missing values in a row of a data frame. We can do something like this:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://dplyr.tidyverse.org">dplyr</a></span><span class="o">)</span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt; Attaching package: 'dplyr'</span></span>
<span></span><span><span class="c">#&gt; The following objects are masked from 'package:stats':</span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt;     filter, lag</span></span>
<span></span><span><span class="c">#&gt; The following objects are masked from 'package:base':</span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt;     intersect, setdiff, setequal, union</span></span>
<span></span><span><span class="nv">my_n_miss</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">data</span><span class="o">)</span><span class="o">{</span></span>
<span>  <span class="nv">data</span> <span class="o">|&gt;</span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/rowwise.html">rowwise</a></span><span class="o">(</span><span class="o">)</span> <span class="o">|&gt;</span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>    n_miss <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/sum.html">sum</a></span><span class="o">(</span><span class="nf"><a href="https://rdrr.io/r/base/NA.html">is.na</a></span><span class="o">(</span><span class="nf"><a href="https://dplyr.tidyverse.org/reference/c_across.html">c_across</a></span><span class="o">(</span><span class="nf"><a href="https://tidyselect.r-lib.org/reference/everything.html">everything</a></span><span class="o">(</span><span class="o">)</span><span class="o">)</span><span class="o">)</span><span class="o">)</span></span>
<span>  <span class="o">)</span> <span class="o">|&gt;</span> </span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/group_by.html">ungroup</a></span><span class="o">(</span><span class="o">)</span></span>
<span><span class="o">}</span></span>
<span></span>
<span><span class="nf">my_n_miss</span><span class="o">(</span><span class="nv">airquality</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 153 × 7</span></span></span>
<span><span class="c">#&gt;    Ozone Solar.R  Wind  Temp Month   Day n_miss</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;int&gt;</span>   <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;int&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;int&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>    41     190   7.4    67     5     1      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>    36     118   8      72     5     2      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>    12     149  12.6    74     5     3      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>    18     313  11.5    62     5     4      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>    <span style="color: #BB0000;">NA</span>      <span style="color: #BB0000;">NA</span>  14.3    56     5     5      2</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>    28      <span style="color: #BB0000;">NA</span>  14.9    66     5     6      1</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>    23     299   8.6    65     5     7      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>    19      99  13.8    59     5     8      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>     8      19  20.1    61     5     9      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>    <span style="color: #BB0000;">NA</span>     194   8.6    69     5    10      1</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># ℹ 143 more rows</span></span></span>
<span></span></code></pre>
</div>
<p>But we can speed this up using <a href="https://rdrr.io/r/base/colSums.html"><code>rowSums()</code></a> instead:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">new_n_miss</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">data</span><span class="o">)</span><span class="o">{</span></span>
<span>  <span class="nv">n_misses</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/colSums.html">rowSums</a></span><span class="o">(</span><span class="nf"><a href="https://rdrr.io/r/base/NA.html">is.na</a></span><span class="o">(</span><span class="nv">data</span><span class="o">)</span><span class="o">)</span></span>
<span>  <span class="nv">data</span> <span class="o">|&gt;</span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>    n_miss <span class="o">=</span> <span class="nv">n_misses</span></span>
<span>  <span class="o">)</span> <span class="o">|&gt;</span> </span>
<span>    <span class="nf"><a href="https://tibble.tidyverse.org/reference/as_tibble.html">as_tibble</a></span><span class="o">(</span><span class="o">)</span></span>
<span><span class="o">}</span></span>
<span></span>
<span><span class="nf">new_n_miss</span><span class="o">(</span><span class="nv">airquality</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 153 × 7</span></span></span>
<span><span class="c">#&gt;    Ozone Solar.R  Wind  Temp Month   Day n_miss</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;int&gt;</span>   <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;int&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>    41     190   7.4    67     5     1      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>    36     118   8      72     5     2      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>    12     149  12.6    74     5     3      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>    18     313  11.5    62     5     4      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>    <span style="color: #BB0000;">NA</span>      <span style="color: #BB0000;">NA</span>  14.3    56     5     5      2</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>    28      <span style="color: #BB0000;">NA</span>  14.9    66     5     6      1</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>    23     299   8.6    65     5     7      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>    19      99  13.8    59     5     8      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>     8      19  20.1    61     5     9      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>    <span style="color: #BB0000;">NA</span>     194   8.6    69     5    10      1</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># ℹ 143 more rows</span></span></span>
<span></span><span><span class="nf">my_n_miss</span><span class="o">(</span><span class="nv">airquality</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 153 × 7</span></span></span>
<span><span class="c">#&gt;    Ozone Solar.R  Wind  Temp Month   Day n_miss</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;int&gt;</span>   <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;int&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;int&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>    41     190   7.4    67     5     1      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>    36     118   8      72     5     2      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>    12     149  12.6    74     5     3      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>    18     313  11.5    62     5     4      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>    <span style="color: #BB0000;">NA</span>      <span style="color: #BB0000;">NA</span>  14.3    56     5     5      2</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>    28      <span style="color: #BB0000;">NA</span>  14.9    66     5     6      1</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>    23     299   8.6    65     5     7      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>    19      99  13.8    59     5     8      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>     8      19  20.1    61     5     9      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>    <span style="color: #BB0000;">NA</span>     194   8.6    69     5    10      1</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># ℹ 143 more rows</span></span></span>
<span></span></code></pre>
</div>
<p>We can measure the speed using <a href="http://bench.r-lib.org/reference/mark.html"><code>bench::mark()</code></a>:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://bench.r-lib.org/">bench</a></span><span class="o">)</span></span>
<span></span>
<span><span class="nv">bm</span> <span class="o">&lt;-</span> <span class="nf"><a href="http://bench.r-lib.org/reference/mark.html">mark</a></span><span class="o">(</span></span>
<span>  old <span class="o">=</span> <span class="nf">my_n_miss</span><span class="o">(</span><span class="nv">airquality</span><span class="o">)</span>,</span>
<span>  new <span class="o">=</span> <span class="nf">new_n_miss</span><span class="o">(</span><span class="nv">airquality</span><span class="o">)</span></span>
<span><span class="o">)</span></span>
<span></span>
<span><span class="nv">bm</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 2 × 6</span></span></span>
<span><span class="c">#&gt;   expression      min   median `itr/sec` mem_alloc `gc/sec`</span></span>
<span><span class="c">#&gt;   <span style="color: #555555; font-style: italic;">&lt;bch:expr&gt;</span> <span style="color: #555555; font-style: italic;">&lt;bch:tm&gt;</span> <span style="color: #555555; font-style: italic;">&lt;bch:tm&gt;</span>     <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;bch:byt&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">1</span> old          23.9ms   23.9ms      41.8   355.5KB    334. </span></span>
<span><span class="c">#&gt; <span style="color: #555555;">2</span> new         347.5µs  384.5µs    <span style="text-decoration: underline;">2</span>385.     81.8KB     34.8</span></span>
<span></span></code></pre>
</div>
<p>This runs the code at least twice, and prints out the amount of time it takes to run the code provided on the right hand side of “old” and “new”. But you can name them whatever you want.</p>
<p>Now, it can be kind of hard to see just <em>how much</em> faster this is, if you just look at comparing the times, as the times are given here in…well, actually I’m not sure why our friend from the greek alphabet mu, µ, from the greek alphabet is here, actually? If, like me, you needed to <a href="https://simple.wikipedia.org/wiki/Order_of_magnitude">double check the standard measures of order of magnitude wiki page</a>, you might not know that “ms” means milli - or one thousandth, and µ means “micro”, or one millionth. The point is that the new one is many times faster than the old one.</p>
<p>We can do a plot to help see this:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://rdrr.io/r/graphics/plot.default.html">plot</a></span><span class="o">(</span><span class="nv">bm</span><span class="o">)</span></span>
<span><span class="c">#&gt; Loading required namespace: tidyr</span></span>
<span></span></code></pre>
<p><img src="https://www.njtierney.com/posts/2024-05-17-summary-benchmark/figs/unnamed-chunk-5-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>So we can see that the new one really is <em>a lot</em> faster.</p>
<p>But if I just want to be able to say something like:</p>
<blockquote class="blockquote">
<p>It is XX times faster</p>
</blockquote>
<p>then we can use the (somewhat unknown?) <code>relative = TRUE</code> option of <a href="https://bench.r-lib.org/reference/summary.bench_mark.html">bench’s S3 method for <code>summary</code> method</a>:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://rdrr.io/r/base/summary.html">summary</a></span><span class="o">(</span><span class="nv">bm</span>, relative <span class="o">=</span> <span class="kc">TRUE</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 2 × 6</span></span></span>
<span><span class="c">#&gt;   expression   min median `itr/sec` mem_alloc `gc/sec`</span></span>
<span><span class="c">#&gt;   <span style="color: #555555; font-style: italic;">&lt;bch:expr&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>     <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>     <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">1</span> old         68.7   62.2       1        4.34     9.62</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">2</span> new          1      1        57.0      1        1</span></span>
<span></span></code></pre>
</div>
<p>And this is great, from this we can see it is about 60 times faster. And that the old approach uses 15 times more memory.</p>
<section id="the-story-behind-this-speedup-in-naniar." class="level2">
<h2 class="anchored" data-anchor-id="the-story-behind-this-speedup-in-naniar.">The story behind this speedup in naniar.</h2>
<p>Now, I didn’t just come up with a speedup for missing values on the fly. The story here is that there was going to be some (very generous) improvements to the naniar package from <a href="https://github.com/romainfrancois">Romain François</a> <a href="https://github.com/njtierney/naniar/issues/113">in the form of C++ code</a>. However, <a href="https://www.jimhester.com/">Jim Hester</a> suggested some changes, I think twitter (which I can’t find anymore), and he then kindly submitted a <a href="https://github.com/njtierney/naniar/pull/112/">pull request showing that rowSums in R ends up being plenty fast</a>.</p>
<p>This is a similar story to Josiah’s, where he used Rust code to get it faster, but then there was a faster way just staying within R.</p>
<p>Sometimes, you don’t need extra C or Fortran or Rust. R is enough!</p>
<p>And if you want to be able to compare the speeds of things, don’t forget the <code>relative = TRUE</code> argument in <code>summary</code> when using <a href="http://bench.r-lib.org/reference/mark.html"><code>bench::mark</code></a>.</p>
</section>
</section>
<section id="other-packages-for-microbenchmarking" class="level1">
<h1>Other packages for microbenchmarking</h1>
<p><code>bench</code> isn’t the only way to measure things! Other ones I’ve enjoyed using in the past are <a href="https://cran.r-project.org/web/packages/microbenchmark/index.html">microbenchmark</a> and <a href="https://cran.r-project.org/web/packages/tictoc/index.html">tictoc</a>. I’ve particularly enjoyed <code>tictoc</code> because you get to do this:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://github.com/jabiru/tictoc">tictoc</a></span><span class="o">)</span></span>
<span><span class="nf"><a href="https://rdrr.io/pkg/tictoc/man/tic.html">tic</a></span><span class="o">(</span><span class="o">)</span></span>
<span><span class="nf">new_n_miss</span><span class="o">(</span><span class="nv">airquality</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 153 × 7</span></span></span>
<span><span class="c">#&gt;    Ozone Solar.R  Wind  Temp Month   Day n_miss</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;int&gt;</span>   <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;int&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>    41     190   7.4    67     5     1      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>    36     118   8      72     5     2      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>    12     149  12.6    74     5     3      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>    18     313  11.5    62     5     4      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>    <span style="color: #BB0000;">NA</span>      <span style="color: #BB0000;">NA</span>  14.3    56     5     5      2</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>    28      <span style="color: #BB0000;">NA</span>  14.9    66     5     6      1</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>    23     299   8.6    65     5     7      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>    19      99  13.8    59     5     8      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>     8      19  20.1    61     5     9      0</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>    <span style="color: #BB0000;">NA</span>     194   8.6    69     5    10      1</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># ℹ 143 more rows</span></span></span>
<span></span><span><span class="nf"><a href="https://rdrr.io/pkg/tictoc/man/tic.html">toc</a></span><span class="o">(</span><span class="o">)</span></span>
<span><span class="c">#&gt; 0.01 sec elapsed</span></span>
<span></span></code></pre>
</div>
<p>Which feels a bit nicer than using <a href="https://rdrr.io/r/base/system.time.html"><code>system.time()</code></a>:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://rdrr.io/r/base/system.time.html">system.time</a></span><span class="o">(</span><span class="o">{</span></span>
<span>  <span class="nf">new_n_miss</span><span class="o">(</span><span class="nv">airquality</span><span class="o">)</span></span>
<span><span class="o">}</span><span class="o">)</span></span>
<span><span class="c">#&gt;    user  system elapsed </span></span>
<span><span class="c">#&gt;   0.001   0.000   0.002</span></span>
<span></span></code></pre>
</div>
<p>Also, notice that those two times are different? This is why we use benchmarking, to run those checks many times!</p>
</section>
<section id="end" class="level1">
<h1>End</h1>
<p>And that’s it, that’s the blog post. The <code>relative = TRUE</code> option in <code>mark</code> is super neat, and I don’t think many people know about it. Thanks again to Jim Hester for originally creating the <code>bench</code> package.</p>


</section>

 ]]></description>
  <category>benchmark</category>
  <category>microbenchmark</category>
  <category>rstats</category>
  <category>functions</category>
  <category>rse</category>
  <category>research software engineer</category>
  <guid>https://www.njtierney.com/posts/2024-05-17-summary-benchmark/</guid>
  <pubDate>Fri, 17 May 2024 00:00:00 GMT</pubDate>
</item>
<item>
  <title>{naniar} version 1.1.0 “Prince Caspian”</title>
  <link>https://www.njtierney.com/posts/2024-03-04-naniar-version-1-1-0-prince-caspian/</link>
  <description><![CDATA[ 
<header class="site-header">
  <h1 class="site-title">
    <a href="../../">
      <img class="hvr-grow site-logo" src="https://www.njtierney.com/assets/njt-logo-small.png" alt="Nick logo">
    </a>
    <span class="hvr-bob site-title-credibly">Credibly</span>
    <span class="hvr-hang site-title-curious">Curious</span>
  </h1>
  <p class="site-subtitle">
    Nick Tierney's (mostly) rstats blog
  </p>
  
</header>




<p>I’m happy to announce that naniar version 1.1.0 “Prince Caspian” is released. It’s been about a year since the last releaase, so I’m happy to include some new features. Let’s explore some of the new changes in this release</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://rdrr.io/r/base/options.html">options</a></span><span class="o">(</span>tidyverse.quiet <span class="o">=</span> <span class="kc">TRUE</span><span class="o">)</span></span>
<span><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://tidyverse.tidyverse.org">tidyverse</a></span><span class="o">)</span></span>
<span><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://github.com/njtierney/naniar">naniar</a></span><span class="o">)</span></span></code></pre>
</div>
<section id="imputation-functions" class="level1">
<h1>Imputation functions</h1>
<p>I’ve always been a hesitant to include imputation helper functions like <a href="http://naniar.njtierney.com/reference/impute_mean.html"><code>impute_mean()</code></a>, and friends in {naniar}, as they aren’t a great tool to use for imputation. I also really believe the <a href="https://cran.r-project.org/web/packages/simputation/">{simputation}</a> R package does a great job at doing much imputation. However, sometimes you do actually want to demonstrate how bad imputing the mean is. Or sometimes you do need to impute the mean. And I’d rather make it easier for people to do this.</p>
<p>This release included some new functions: <a href="http://naniar.njtierney.com/reference/impute_fixed.html"><code>impute_fixed()</code></a>, <a href="http://naniar.njtierney.com/reference/impute_zero.html"><code>impute_zero()</code></a>, <a href="http://naniar.njtierney.com/reference/impute_factor.html"><code>impute_factor()</code></a>, and <a href="http://naniar.njtierney.com/reference/impute_mode.html"><code>impute_mode()</code></a>. Notably, these do not implement “scoped variants” which were previously implemented - for example, <code>impute_fixed_if()</code> etc. This is in favour of using the new <a href="https://dplyr.tidyverse.org/reference/across.html"><code>across()</code></a> workflow within {dplyr}, which is a bit easier to maintain. This resolves issues <a href="https://github.com//njtierney/naniar/issues/261">#261</a> and <a href="https://github.com//njtierney/naniar/issues/213">#213</a>.</p>
<p>To demonstrate these imputation functions, let’s create a vector of missing values:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://github.com/njtierney/naniar">naniar</a></span><span class="o">)</span></span>
<span><span class="nv">vec_num</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/stats/Normal.html">rnorm</a></span><span class="o">(</span><span class="m">10</span><span class="o">)</span></span>
<span><span class="nv">vec_int</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/stats/Poisson.html">rpois</a></span><span class="o">(</span><span class="m">10</span>, <span class="m">5</span><span class="o">)</span></span>
<span><span class="nv">vec_fct</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/factor.html">factor</a></span><span class="o">(</span><span class="nv">LETTERS</span><span class="o">[</span><span class="m">1</span><span class="o">:</span><span class="m">10</span><span class="o">]</span><span class="o">)</span></span>
<span></span>
<span><span class="nv">vec_num</span> <span class="o">&lt;-</span> <span class="nf"><a href="http://naniar.njtierney.com/reference/set-prop-n-miss.html">set_prop_miss</a></span><span class="o">(</span><span class="nv">vec_num</span>, <span class="m">0.4</span><span class="o">)</span></span>
<span><span class="nv">vec_int</span> <span class="o">&lt;-</span> <span class="nf"><a href="http://naniar.njtierney.com/reference/set-prop-n-miss.html">set_prop_miss</a></span><span class="o">(</span><span class="nv">vec_int</span>, <span class="m">0.4</span><span class="o">)</span></span>
<span><span class="nv">vec_fct</span> <span class="o">&lt;-</span> <span class="nf"><a href="http://naniar.njtierney.com/reference/set-prop-n-miss.html">set_prop_miss</a></span><span class="o">(</span><span class="nv">vec_fct</span>, <span class="m">0.4</span><span class="o">)</span></span>
<span></span>
<span><span class="nv">vec_num</span></span>
<span><span class="c">#&gt;  [1]         NA  0.9232763         NA  0.5265162         NA         NA</span></span>
<span><span class="c">#&gt;  [7]  1.4260531  1.3793303 -0.7855565 -0.5928170</span></span>
<span></span><span><span class="nv">vec_int</span></span>
<span><span class="c">#&gt;  [1] NA  5  6  5  5 NA NA  6 NA  6</span></span>
<span></span><span><span class="nv">vec_fct</span></span>
<span><span class="c">#&gt;  [1] &lt;NA&gt; B    &lt;NA&gt; D    &lt;NA&gt; F    G    &lt;NA&gt; I    J   </span></span>
<span><span class="c">#&gt; Levels: A B C D E F G H I J</span></span>
<span></span></code></pre>
</div>
<p>We can use <a href="http://naniar.njtierney.com/reference/impute_fixed.html"><code>impute_fixed()</code></a> to impute fixed values into the numeric of these:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="http://naniar.njtierney.com/reference/impute_fixed.html">impute_fixed</a></span><span class="o">(</span><span class="nv">vec_num</span>, <span class="o">-</span><span class="m">999</span><span class="o">)</span></span>
<span><span class="c">#&gt;  [1] -999.0000000    0.9232763 -999.0000000    0.5265162 -999.0000000</span></span>
<span><span class="c">#&gt;  [6] -999.0000000    1.4260531    1.3793303   -0.7855565   -0.5928170</span></span>
<span></span><span><span class="nf"><a href="http://naniar.njtierney.com/reference/impute_fixed.html">impute_fixed</a></span><span class="o">(</span><span class="nv">vec_int</span>, <span class="o">-</span><span class="m">999</span><span class="o">)</span></span>
<span><span class="c">#&gt;  [1] -999    5    6    5    5 -999 -999    6 -999    6</span></span>
<span></span></code></pre>
</div>
<p>And <code>impute_zero</code> is just a special case of <code>impute_fixed</code>, where the fixed value is 0:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="http://naniar.njtierney.com/reference/impute_zero.html">impute_zero</a></span><span class="o">(</span><span class="nv">vec_num</span><span class="o">)</span></span>
<span><span class="c">#&gt;  [1]  0.0000000  0.9232763  0.0000000  0.5265162  0.0000000  0.0000000</span></span>
<span><span class="c">#&gt;  [7]  1.4260531  1.3793303 -0.7855565 -0.5928170</span></span>
<span></span><span><span class="nf"><a href="http://naniar.njtierney.com/reference/impute_zero.html">impute_zero</a></span><span class="o">(</span><span class="nv">vec_int</span><span class="o">)</span></span>
<span><span class="c">#&gt;  [1] 0 5 6 5 5 0 0 6 0 6</span></span>
<span></span></code></pre>
</div>
<p>Similar to <a href="http://naniar.njtierney.com/reference/impute_mean.html"><code>impute_mean()</code></a>, <a href="http://naniar.njtierney.com/reference/impute_mode.html"><code>impute_mode()</code></a> imputes the mode:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="http://naniar.njtierney.com/reference/impute_mode.html">impute_mode</a></span><span class="o">(</span><span class="nv">vec_num</span><span class="o">)</span></span>
<span><span class="c">#&gt;  [1]  1.0704569  0.9232763  1.0704569  0.5265162  1.0704569  1.0704569</span></span>
<span><span class="c">#&gt;  [7]  1.4260531  1.3793303 -0.7855565 -0.5928170</span></span>
<span></span><span><span class="nf"><a href="http://naniar.njtierney.com/reference/impute_mode.html">impute_mode</a></span><span class="o">(</span><span class="nv">vec_int</span><span class="o">)</span></span>
<span><span class="c">#&gt;  [1] 6 5 6 5 5 6 6 6 6 6</span></span>
<span></span></code></pre>
</div>
<p>You can’t however use <a href="http://naniar.njtierney.com/reference/impute_fixed.html"><code>impute_fixed()</code></a> or <a href="http://naniar.njtierney.com/reference/impute_zero.html"><code>impute_zero()</code></a> on factors, and this doesn’t work for factors, even if it’s a new character.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="http://naniar.njtierney.com/reference/impute_fixed.html">impute_fixed</a></span><span class="o">(</span><span class="nv">vec_fct</span>, <span class="o">-</span><span class="m">999</span><span class="o">)</span></span>
<span><span class="c">#&gt; Warning in `[&lt;-.factor`(`*tmp*`, is.na(x), value = -999): invalid factor level, NA generated</span></span>
<span></span><span><span class="c">#&gt;  [1] &lt;NA&gt; B    &lt;NA&gt; D    &lt;NA&gt; F    G    &lt;NA&gt; I    J   </span></span>
<span><span class="c">#&gt; Levels: A B C D E F G H I J</span></span>
<span></span><span><span class="nf"><a href="http://naniar.njtierney.com/reference/impute_zero.html">impute_zero</a></span><span class="o">(</span><span class="nv">vec_fct</span><span class="o">)</span></span>
<span><span class="c">#&gt; Warning in `[&lt;-.factor`(`*tmp*`, is.na(x), value = 0): invalid factor level, NA generated</span></span>
<span></span><span><span class="c">#&gt;  [1] &lt;NA&gt; B    &lt;NA&gt; D    &lt;NA&gt; F    G    &lt;NA&gt; I    J   </span></span>
<span><span class="c">#&gt; Levels: A B C D E F G H I J</span></span>
<span></span><span><span class="nf"><a href="http://naniar.njtierney.com/reference/impute_fixed.html">impute_fixed</a></span><span class="o">(</span><span class="nv">vec_fct</span>, <span class="s">"ZZ"</span><span class="o">)</span></span>
<span><span class="c">#&gt; Warning in `[&lt;-.factor`(`*tmp*`, is.na(x), value = "ZZ"): invalid factor level, NA generated</span></span>
<span></span><span><span class="c">#&gt;  [1] &lt;NA&gt; B    &lt;NA&gt; D    &lt;NA&gt; F    G    &lt;NA&gt; I    J   </span></span>
<span><span class="c">#&gt; Levels: A B C D E F G H I J</span></span>
<span></span></code></pre>
</div>
<p>However, you can use <a href="http://naniar.njtierney.com/reference/impute_mode.html"><code>impute_mode()</code></a>:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="http://naniar.njtierney.com/reference/impute_mode.html">impute_mode</a></span><span class="o">(</span><span class="nv">vec_fct</span><span class="o">)</span></span>
<span><span class="c">#&gt;  [1] I B I D I F G I I J</span></span>
<span><span class="c">#&gt; Levels: A B C D E F G H I J</span></span>
<span></span></code></pre>
</div>
<p>For factors, you can impute a specific value:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="http://naniar.njtierney.com/reference/impute_factor.html">impute_factor</a></span><span class="o">(</span><span class="nv">vec_fct</span>, value <span class="o">=</span> <span class="s">"ZZ"</span><span class="o">)</span></span>
<span><span class="c">#&gt;  [1] ZZ B  ZZ D  ZZ F  G  ZZ I  J </span></span>
<span><span class="c">#&gt; Levels: A B C D E F G H I J ZZ</span></span>
<span></span></code></pre>
</div>
<p>Think of it like <a href="http://naniar.njtierney.com/reference/impute_fixed.html"><code>impute_fixed()</code></a>, but a special case for factors.</p>
<p>Now let’s demonstrate how to do this in a data frame. First we create the data</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://dplyr.tidyverse.org">dplyr</a></span><span class="o">)</span></span>
<span></span>
<span><span class="nv">dat</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://tibble.tidyverse.org/reference/tibble.html">tibble</a></span><span class="o">(</span></span>
<span>  num <span class="o">=</span> <span class="nv">vec_num</span>,</span>
<span>  int <span class="o">=</span> <span class="nv">vec_int</span>,</span>
<span>  fct <span class="o">=</span> <span class="nv">vec_fct</span></span>
<span><span class="o">)</span></span>
<span></span>
<span><span class="nv">dat</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 10 × 3</span></span></span>
<span><span class="c">#&gt;       num   int fct  </span></span>
<span><span class="c">#&gt;     <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;fct&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span> <span style="color: #BB0000;">NA</span>        <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span>   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>  0.923     5 B    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span> <span style="color: #BB0000;">NA</span>         6 <span style="color: #BB0000;">NA</span>   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>  0.527     5 D    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span> <span style="color: #BB0000;">NA</span>         5 <span style="color: #BB0000;">NA</span>   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span> <span style="color: #BB0000;">NA</span>        <span style="color: #BB0000;">NA</span> F    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>  1.43     <span style="color: #BB0000;">NA</span> G    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>  1.38      6 <span style="color: #BB0000;">NA</span>   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span> -<span style="color: #BB0000;">0.786</span>    <span style="color: #BB0000;">NA</span> I    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span> -<span style="color: #BB0000;">0.593</span>     6 J</span></span>
<span></span></code></pre>
</div>
<p>You can use it inside mutate like so:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">dat</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span></span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>    num <span class="o">=</span> <span class="nf"><a href="http://naniar.njtierney.com/reference/impute_fixed.html">impute_fixed</a></span><span class="o">(</span><span class="nv">num</span>, <span class="o">-</span><span class="m">9999</span><span class="o">)</span>,</span>
<span>    int <span class="o">=</span> <span class="nf"><a href="http://naniar.njtierney.com/reference/impute_zero.html">impute_zero</a></span><span class="o">(</span><span class="nv">int</span><span class="o">)</span>,</span>
<span>    fct <span class="o">=</span> <span class="nf"><a href="http://naniar.njtierney.com/reference/impute_factor.html">impute_factor</a></span><span class="o">(</span><span class="nv">fct</span>, <span class="s">"out"</span><span class="o">)</span></span>
<span>  <span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 10 × 3</span></span></span>
<span><span class="c">#&gt;          num   int fct  </span></span>
<span><span class="c">#&gt;        <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;fct&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span> -<span style="color: #BB0000; text-decoration: underline;">9</span><span style="color: #BB0000;">999</span>         0 out  </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>     0.923     5 B    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span> -<span style="color: #BB0000; text-decoration: underline;">9</span><span style="color: #BB0000;">999</span>         6 out  </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>     0.527     5 D    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span> -<span style="color: #BB0000; text-decoration: underline;">9</span><span style="color: #BB0000;">999</span>         5 out  </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span> -<span style="color: #BB0000; text-decoration: underline;">9</span><span style="color: #BB0000;">999</span>         0 F    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>     1.43      0 G    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>     1.38      6 out  </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>    -<span style="color: #BB0000;">0.786</span>     0 I    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>    -<span style="color: #BB0000;">0.593</span>     6 J</span></span>
<span></span></code></pre>
</div>
<p>Or if you want to impute across all applicable variables with a single function, you could use <code>where</code> like so, to focus on numeric data:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">dat</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span></span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/across.html">across</a></span><span class="o">(</span></span>
<span>      .cols <span class="o">=</span> <span class="nf"><a href="https://tidyselect.r-lib.org/reference/where.html">where</a></span><span class="o">(</span><span class="nv">is.numeric</span><span class="o">)</span>,</span>
<span>      .fn <span class="o">=</span> <span class="nv">impute_zero</span></span>
<span>    <span class="o">)</span></span>
<span>  <span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 10 × 3</span></span></span>
<span><span class="c">#&gt;       num   int fct  </span></span>
<span><span class="c">#&gt;     <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;fct&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>  0         0 <span style="color: #BB0000;">NA</span>   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>  0.923     5 B    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>  0         6 <span style="color: #BB0000;">NA</span>   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>  0.527     5 D    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>  0         5 <span style="color: #BB0000;">NA</span>   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>  0         0 F    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>  1.43      0 G    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>  1.38      6 <span style="color: #BB0000;">NA</span>   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span> -<span style="color: #BB0000;">0.786</span>     0 I    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span> -<span style="color: #BB0000;">0.593</span>     6 J</span></span>
<span></span><span></span>
<span><span class="nv">dat</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span></span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/across.html">across</a></span><span class="o">(</span></span>
<span>      .cols <span class="o">=</span> <span class="nf"><a href="https://tidyselect.r-lib.org/reference/where.html">where</a></span><span class="o">(</span><span class="nv">is.numeric</span><span class="o">)</span>,</span>
<span>      .fn <span class="o">=</span> \<span class="o">(</span><span class="nv">x</span><span class="o">)</span> <span class="nf"><a href="http://naniar.njtierney.com/reference/impute_fixed.html">impute_fixed</a></span><span class="o">(</span><span class="nv">x</span>, <span class="o">-</span><span class="m">99</span><span class="o">)</span></span>
<span>    <span class="o">)</span></span>
<span>  <span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 10 × 3</span></span></span>
<span><span class="c">#&gt;        num   int fct  </span></span>
<span><span class="c">#&gt;      <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;fct&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span> -<span style="color: #BB0000;">99</span>       -<span style="color: #BB0000;">99</span> <span style="color: #BB0000;">NA</span>   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>   0.923     5 B    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span> -<span style="color: #BB0000;">99</span>         6 <span style="color: #BB0000;">NA</span>   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>   0.527     5 D    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span> -<span style="color: #BB0000;">99</span>         5 <span style="color: #BB0000;">NA</span>   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span> -<span style="color: #BB0000;">99</span>       -<span style="color: #BB0000;">99</span> F    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>   1.43    -<span style="color: #BB0000;">99</span> G    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>   1.38      6 <span style="color: #BB0000;">NA</span>   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>  -<span style="color: #BB0000;">0.786</span>   -<span style="color: #BB0000;">99</span> I    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>  -<span style="color: #BB0000;">0.593</span>     6 J</span></span>
<span></span></code></pre>
</div>
</section>
<section id="improvements" class="level1">
<h1>Improvements</h1>
<ul>
<li>Add <code>digit</code> argument to <code>miss_var_summary</code> to help display percentage missing data correctly when there is a very small fraction of missingness - solving <a href="https://github.com//njtierney/naniar/issues/284">#284</a>.</li>
</ul>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">N</span> <span class="o">&lt;-</span> <span class="m">30000000</span></span>
<span></span>
<span><span class="nv">df</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://tibble.tidyverse.org/reference/tibble.html">tibble</a></span><span class="o">(</span>x <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/rep.html">rep</a></span><span class="o">(</span><span class="kc">NA_real_</span>, <span class="nv">N</span><span class="o">)</span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span></span>
<span>  <span class="nf"><a href="https://tibble.tidyverse.org/reference/add_row.html">add_row</a></span><span class="o">(</span>x <span class="o">=</span> <span class="m">0</span><span class="o">)</span></span>
<span></span>
<span><span class="nv">df</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> <span class="nf"><a href="http://naniar.njtierney.com/reference/miss_var_summary.html">miss_var_summary</a></span><span class="o">(</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 1 × 3</span></span></span>
<span><span class="c">#&gt;   variable   n_miss pct_miss</span></span>
<span><span class="c">#&gt;   <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>       <span style="color: #555555; font-style: italic;">&lt;int&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;num&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">1</span> x        30<span style="text-decoration: underline;">000</span>000     100.</span></span>
<span></span><span><span class="nv">df</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> <span class="nf"><a href="http://naniar.njtierney.com/reference/miss_var_summary.html">miss_var_summary</a></span><span class="o">(</span>digits <span class="o">=</span> <span class="m">6</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 1 × 3</span></span></span>
<span><span class="c">#&gt;   variable   n_miss  pct_miss</span></span>
<span><span class="c">#&gt;   <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>       <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;num:.6!&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">1</span> x        30<span style="text-decoration: underline;">000</span>000 99.999<span style="text-decoration: underline;">997</span></span></span>
<span></span></code></pre>
</div>
<ul>
<li><a href="http://naniar.njtierney.com/reference/geom_miss_point.html"><code>geom_miss_point()</code></a> works with <code>shape</code> argument <a href="https://github.com//njtierney/naniar/issues/290">#290</a></li>
</ul>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggplot.html">ggplot</a></span><span class="o">(</span></span>
<span>  <span class="nv">airquality</span>,</span>
<span>  <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/aes.html">aes</a></span><span class="o">(</span></span>
<span>    x <span class="o">=</span> <span class="nv">Ozone</span>,</span>
<span>    y <span class="o">=</span> <span class="nv">Solar.R</span>,</span>
<span>    shape <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/factor.html">factor</a></span><span class="o">(</span><span class="nv">Month</span><span class="o">)</span></span>
<span>  <span class="o">)</span></span>
<span><span class="o">)</span> <span class="o">+</span></span>
<span>  <span class="nf"><a href="http://naniar.njtierney.com/reference/geom_miss_point.html">geom_miss_point</a></span><span class="o">(</span>size <span class="o">=</span> <span class="m">4</span><span class="o">)</span></span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2024-03-04-naniar-version-1-1-0-prince-caspian/figs/unnamed-chunk-13-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<ul>
<li>Implemented <code>Date</code>, <code>POSIXct</code> and <code>POSIXlt</code> methods for <a href="http://naniar.njtierney.com/reference/impute_below.html"><code>impute_below()</code></a> - <a href="https://github.com//njtierney/naniar/issues/158">#158</a></li>
</ul>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">dat_date</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://tibble.tidyverse.org/reference/tibble.html">tibble</a></span><span class="o">(</span></span>
<span>  values <span class="o">=</span> <span class="m">1</span><span class="o">:</span><span class="m">7</span>,</span>
<span>  number <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span><span class="m">111</span>, <span class="m">112</span>, <span class="kc">NA</span>, <span class="kc">NA</span>, <span class="m">108</span>, <span class="m">150</span>, <span class="m">160</span><span class="o">)</span>,</span>
<span>  posixct <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/as.POSIXlt.html">as.POSIXct</a></span><span class="o">(</span><span class="nv">number</span>, origin <span class="o">=</span> <span class="s">"1970-01-01"</span><span class="o">)</span>,</span>
<span>  posixlt <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/as.POSIXlt.html">as.POSIXlt</a></span><span class="o">(</span><span class="nv">number</span>, origin <span class="o">=</span> <span class="s">"1970-01-01"</span><span class="o">)</span>,</span>
<span>  date <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/as.Date.html">as.Date</a></span><span class="o">(</span><span class="nv">number</span><span class="o">)</span></span>
<span>  <span class="o">)</span></span>
<span><span class="nv">dat_date</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 7 × 5</span></span></span>
<span><span class="c">#&gt;   values number posixct             posixlt             date      </span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;int&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dttm&gt;</span>              <span style="color: #555555; font-style: italic;">&lt;dttm&gt;</span>              <span style="color: #555555; font-style: italic;">&lt;date&gt;</span>    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;">1</span>      1    111 1970-01-01 <span style="color: #555555;">10:01:51</span> 1970-01-01 <span style="color: #555555;">10:01:51</span> 1970-04-22</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">2</span>      2    112 1970-01-01 <span style="color: #555555;">10:01:52</span> 1970-01-01 <span style="color: #555555;">10:01:52</span> 1970-04-23</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">3</span>      3     <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span>                  <span style="color: #BB0000;">NA</span>                  <span style="color: #BB0000;">NA</span>        </span></span>
<span><span class="c">#&gt; <span style="color: #555555;">4</span>      4     <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span>                  <span style="color: #BB0000;">NA</span>                  <span style="color: #BB0000;">NA</span>        </span></span>
<span><span class="c">#&gt; <span style="color: #555555;">5</span>      5    108 1970-01-01 <span style="color: #555555;">10:01:48</span> 1970-01-01 <span style="color: #555555;">10:01:48</span> 1970-04-19</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">6</span>      6    150 1970-01-01 <span style="color: #555555;">10:02:30</span> 1970-01-01 <span style="color: #555555;">10:02:30</span> 1970-05-31</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">7</span>      7    160 1970-01-01 <span style="color: #555555;">10:02:40</span> 1970-01-01 <span style="color: #555555;">10:02:40</span> 1970-06-10</span></span>
<span></span><span></span>
<span><span class="nv">date_date_imp</span> <span class="o">&lt;-</span> <span class="nv">dat_date</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>    number_imp <span class="o">=</span> <span class="nf"><a href="http://naniar.njtierney.com/reference/impute_below.html">impute_below</a></span><span class="o">(</span><span class="nv">number</span><span class="o">)</span>,</span>
<span>    .after <span class="o">=</span> <span class="nv">number</span></span>
<span>  <span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>    posixct_imp <span class="o">=</span> <span class="nf"><a href="http://naniar.njtierney.com/reference/impute_below.html">impute_below</a></span><span class="o">(</span><span class="nv">posixct</span><span class="o">)</span>,</span>
<span>    .after <span class="o">=</span> <span class="nv">posixct</span></span>
<span>    <span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>    posixlt_imp <span class="o">=</span> <span class="nf"><a href="http://naniar.njtierney.com/reference/impute_below.html">impute_below</a></span><span class="o">(</span><span class="nv">posixlt</span><span class="o">)</span>,</span>
<span>    .after <span class="o">=</span> <span class="nv">posixlt</span></span>
<span>  <span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>    date_imp <span class="o">=</span> <span class="nf"><a href="http://naniar.njtierney.com/reference/impute_below.html">impute_below</a></span><span class="o">(</span><span class="nv">date</span><span class="o">)</span>,</span>
<span>    .after <span class="o">=</span> <span class="nv">date</span></span>
<span>  <span class="o">)</span></span>
<span></span>
<span><span class="nv">date_date_imp</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 7 × 9</span></span></span>
<span><span class="c">#&gt;   values number number_imp posixct             posixct_imp        </span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;int&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>      <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dttm&gt;</span>              <span style="color: #555555; font-style: italic;">&lt;dttm&gt;</span>             </span></span>
<span><span class="c">#&gt; <span style="color: #555555;">1</span>      1    111       111  1970-01-01 <span style="color: #555555;">10:01:51</span> 1970-01-01 <span style="color: #555555;">10:01:51</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">2</span>      2    112       112  1970-01-01 <span style="color: #555555;">10:01:52</span> 1970-01-01 <span style="color: #555555;">10:01:52</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">3</span>      3     <span style="color: #BB0000;">NA</span>       103. <span style="color: #BB0000;">NA</span>                  1970-01-01 <span style="color: #555555;">10:01:43</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">4</span>      4     <span style="color: #BB0000;">NA</span>       102. <span style="color: #BB0000;">NA</span>                  1970-01-01 <span style="color: #555555;">10:01:41</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">5</span>      5    108       108  1970-01-01 <span style="color: #555555;">10:01:48</span> 1970-01-01 <span style="color: #555555;">10:01:48</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">6</span>      6    150       150  1970-01-01 <span style="color: #555555;">10:02:30</span> 1970-01-01 <span style="color: #555555;">10:02:30</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">7</span>      7    160       160  1970-01-01 <span style="color: #555555;">10:02:40</span> 1970-01-01 <span style="color: #555555;">10:02:40</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># ℹ 4 more variables: posixlt &lt;dttm&gt;, posixlt_imp &lt;dttm&gt;, date &lt;date&gt;,</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">#   date_imp &lt;date&gt;</span></span></span>
<span></span></code></pre>
</div>
</section>
<section id="bug-fixes" class="level1">
<h1>Bug fixes</h1>
<ul>
<li>Fix bug with <a href="http://naniar.njtierney.com/reference/any-all-na-complete.html"><code>all_complete()</code></a>, which was implemented as <code>!anyNA(x)</code> but should be <code>all(complete.cases(x))</code>.</li>
<li>Correctly implement <a href="http://naniar.njtierney.com/reference/any-all-na-complete.html"><code>any_na()</code></a> (and <a href="http://naniar.njtierney.com/reference/any-all-na-complete.html"><code>any_miss()</code></a>) and <a href="http://naniar.njtierney.com/reference/any-all-na-complete.html"><code>any_complete()</code></a>. Rework examples to demonstrate workflow for finding complete variables.</li>
<li>Fix bug with <a href="http://naniar.njtierney.com/reference/shadow_long.html"><code>shadow_long()</code></a> not working when gathering variables of mixed type. Fix involved specifying a value transform, which defaults to character. <a href="https://github.com//njtierney/naniar/issues/314">#314</a></li>
<li>Provide <a href="http://naniar.njtierney.com/reference/replace_na_with.html"><code>replace_na_with()</code></a>, a complement to <a href="http://naniar.njtierney.com/reference/replace_with_na.html"><code>replace_with_na()</code></a> - <a href="https://github.com//njtierney/naniar/issues/129">#129</a></li>
</ul>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">x</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span><span class="m">1</span><span class="o">:</span><span class="m">5</span>, <span class="kc">NA</span>, <span class="kc">NA</span>, <span class="kc">NA</span><span class="o">)</span></span>
<span><span class="nv">x</span></span>
<span><span class="c">#&gt; [1]  1  2  3  4  5 NA NA NA</span></span>
<span></span><span><span class="nf"><a href="http://naniar.njtierney.com/reference/replace_na_with.html">replace_na_with</a></span><span class="o">(</span><span class="nv">x</span>, <span class="m">0</span><span class="o">)</span></span>
<span><span class="c">#&gt; [1] 1 2 3 4 5 0 0 0</span></span>
<span></span><span></span>
<span><span class="nv">dat</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://tibble.tidyverse.org/reference/tibble.html">tibble</a></span><span class="o">(</span></span>
<span>  ones <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span><span class="m">1</span>,<span class="m">1</span>,<span class="kc">NA</span><span class="o">)</span>,</span>
<span>  twos <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span><span class="kc">NA</span>,<span class="kc">NA</span>, <span class="m">2</span><span class="o">)</span>,</span>
<span>  threes <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span><span class="kc">NA</span>, <span class="kc">NA</span>, <span class="kc">NA</span><span class="o">)</span></span>
<span><span class="o">)</span></span>
<span></span>
<span><span class="nv">dat</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>    ones <span class="o">=</span> <span class="nf"><a href="http://naniar.njtierney.com/reference/replace_na_with.html">replace_na_with</a></span><span class="o">(</span><span class="nv">ones</span>, <span class="m">0</span><span class="o">)</span>,</span>
<span>    twos <span class="o">=</span> <span class="nf"><a href="http://naniar.njtierney.com/reference/replace_na_with.html">replace_na_with</a></span><span class="o">(</span><span class="nv">twos</span>, <span class="o">-</span><span class="m">2</span><span class="o">)</span>,</span>
<span>    threes <span class="o">=</span> <span class="nf"><a href="http://naniar.njtierney.com/reference/replace_na_with.html">replace_na_with</a></span><span class="o">(</span><span class="nv">threes</span>, <span class="o">-</span><span class="m">3</span><span class="o">)</span></span>
<span>  <span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 3 × 3</span></span></span>
<span><span class="c">#&gt;    ones  twos threes</span></span>
<span><span class="c">#&gt;   <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">1</span>     1    -<span style="color: #BB0000;">2</span>     -<span style="color: #BB0000;">3</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">2</span>     1    -<span style="color: #BB0000;">2</span>     -<span style="color: #BB0000;">3</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">3</span>     0     2     -<span style="color: #BB0000;">3</span></span></span>
<span></span><span></span>
<span><span class="nv">dat</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/across.html">across</a></span><span class="o">(</span></span>
<span>      <span class="nf"><a href="https://tidyselect.r-lib.org/reference/everything.html">everything</a></span><span class="o">(</span><span class="o">)</span>,</span>
<span>      \<span class="o">(</span><span class="nv">x</span><span class="o">)</span> <span class="nf"><a href="http://naniar.njtierney.com/reference/replace_na_with.html">replace_na_with</a></span><span class="o">(</span><span class="nv">x</span>, <span class="o">-</span><span class="m">99</span><span class="o">)</span></span>
<span>    <span class="o">)</span></span>
<span>  <span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 3 × 3</span></span></span>
<span><span class="c">#&gt;    ones  twos threes</span></span>
<span><span class="c">#&gt;   <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">1</span>     1   -<span style="color: #BB0000;">99</span>    -<span style="color: #BB0000;">99</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">2</span>     1   -<span style="color: #BB0000;">99</span>    -<span style="color: #BB0000;">99</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">3</span>   -<span style="color: #BB0000;">99</span>     2    -<span style="color: #BB0000;">99</span></span></span>
<span></span></code></pre>
</div>
<ul>
<li>Fix bug with <a href="http://naniar.njtierney.com/reference/gg_miss_fct.html"><code>gg_miss_fct()</code></a> where it used a deprecated function from forcats - <a href="https://github.com//njtierney/naniar/issues/342">#342</a></li>
</ul>
</section>
<section id="internal-changes" class="level1">
<h1>Internal changes</h1>
<p>{naniar} now uses <a href="https://cli.r-lib.org/reference/cli_abort.html"><code>cli::cli_abort()</code></a> and <a href="https://cli.r-lib.org/reference/cli_abort.html"><code>cli::cli_warn()</code></a> instead of <a href="https://rdrr.io/r/base/stop.html"><code>stop()</code></a> and <a href="https://rdrr.io/r/base/warning.html"><code>warning()</code></a> (<a href="https://github.com//njtierney/naniar/issues/326">#326</a>). Internally in tests we changed to use <code>expect_snapshot()</code> instead of <code>expect_error()</code>.</p>
</section>
<section id="deprecations" class="level1">
<h1>Deprecations</h1>
<p>The following functions have been soft deprecated, and will eventually be made defunct in future versions of naniar. <a href="http://naniar.njtierney.com/reference/shadow_shift.html"><code>shadow_shift()</code></a> - <a href="https://github.com//njtierney/naniar/issues/193">#193</a> in favour of <a href="http://naniar.njtierney.com/reference/impute_below.html"><code>impute_below()</code></a>, and <a href="http://naniar.njtierney.com/reference/miss_case_cumsum.html"><code>miss_case_cumsum()</code></a> and <a href="http://naniar.njtierney.com/reference/miss_var_cumsum.html"><code>miss_var_cumsum()</code></a> - <a href="https://github.com//njtierney/naniar/issues/257">#257</a> - in favour of <code>miss_case_summary(data, cumsum = TRUE)</code> and <code>miss_var_summary(data, cumsum = TRUE)</code>.</p>
</section>
<section id="thanks" class="level1">
<h1>Thanks!</h1>
<p>Thanks to everyone for using {naniar}, I’m happy that I’ve got another release out the door and am looking forward to more changes in the future. Especially thanks to everyone who contributed to issues and or pull request for this release, including: <a href="https://github.com/szimmer"><span class="citation" data-cites="szimmer">@szimmer</span></a>, <a href="https://github.com/HughParsonage"><span class="citation" data-cites="HughParsonage">@HughParsonage</span></a>, , <a href="https://github.com/siavash-babaei"><span class="citation" data-cites="siavash-babaei">@siavash-babaei</span></a>, <a href="https://github.com/maksymiuks"><span class="citation" data-cites="maksymiuks">@maksymiuks</span></a>, <a href="https://github.com/jonocarroll"><span class="citation" data-cites="jonocarroll">@jonocarroll</span></a>, <a href="https://github.com/jzadra"><span class="citation" data-cites="jzadra">@jzadra</span></a>, <a href="https://github.com/krlmlr"><span class="citation" data-cites="krlmlr">@krlmlr</span></a></p>


</section>

 ]]></description>
  <category>rstats</category>
  <category>missing data</category>
  <category>rbloggers</category>
  <category>research software engineer</category>
  <category>data visualisation</category>
  <guid>https://www.njtierney.com/posts/2024-03-04-naniar-version-1-1-0-prince-caspian/</guid>
  <pubDate>Mon, 04 Mar 2024 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Some Goals for 2024</title>
  <link>https://www.njtierney.com/posts/2024-01-08-goals/</link>
  <description><![CDATA[ 
<header class="site-header">
  <h1 class="site-title">
    <a href="../../">
      <img class="hvr-grow site-logo" src="https://www.njtierney.com/assets/njt-logo-small.png" alt="Nick logo">
    </a>
    <span class="hvr-bob site-title-credibly">Credibly</span>
    <span class="hvr-hang site-title-curious">Curious</span>
  </h1>
  <p class="site-subtitle">
    Nick Tierney's (mostly) rstats blog
  </p>
  
</header>




<figure class="figure">
<img src="https://www.njtierney.com/posts/2024-01-08-goals/img/flower-goals.jpg" alt="Flowers in the Victorian Alps, Ricoh GRiii, Nicholas Tierney." class="figure-img">

</figure>
<p>To help me be more accountable, and also work out how to plan my year and work out what’s important to me, I thought I’d share some of my goals for 2024. Writing it all down is a bit scary, and it makes me think that maybe I might be a bit ambitious here. But I think it’s OK to be ambitious.</p>
<section id="learn-js-and-rust" class="level2">
<h2 class="anchored" data-anchor-id="learn-js-and-rust">Learn JS and Rust</h2>
<p>I’d like to try and pick up another programming language for 2024. I don’t really have good fluency with other languages outside of R. I can fumble my way through python and HTML/CSS, a wee bit of C++. But I think it’s important and useful to learn a new language to help broaden your own understanding. I’d like to focus on JS (javascript) and Rust.</p>
<p>I think JS because it has such an enormous influence on the web, and the tools we use every day. I’ve taken a nice course by <a href="https://github.com/gadenbuie">Garrick Aden Buie</a> (I can’t seem to find the course website) in 2020 (one of the last conferences I went to), but I unfortunately didn’t really use JS that year so it’s sort of all fell out of my head.</p>
<p>To learn JS I was thinking I would start with <a href="https://github.com/wesbos/JavaScript30">JavaScript30</a> by <a href="https://github.com/wesbos">Wes Bos</a>, and then move on to <a href="https://github.com/getify/You-Dont-Know-JS">You Don’t Know JS</a> by <a href="https://github.com/getify">Kyle Simpson</a>. Hopefully I can learn and understand enough to try incorporating JS into R via quarto or htmlwidgets or something.</p>
<p>Rust seems like a better language to use than C++. My experience with the <a href="https://rustlings.cool/">rustlings</a> course was excellent, and the error messages from rust were like, actually understandable? It was bizarre. Plus with the <a href="https://extendr.github.io/">rextender</a> R package you can bundle up your R code just like you do with cpp11 or Rcpp. It’d be cool to build something fast and fun in Rust and then bundle it into an R package.</p>
<p>It’s hard to learn two languages at the same time, so I think I’ll try and do 6 months on JS, and 6 months on Rust.</p>
<ul>
<li>January - June: JS</li>
<li>July - December: Rust</li>
</ul>
</section>
<section id="read-some-more-programming-books" class="level2">
<h2 class="anchored" data-anchor-id="read-some-more-programming-books">Read some more programming books</h2>
<p>I’d really like to read these three books:</p>
<ul>
<li><a href="https://xcelab.net/rm/statistical-rethinking/">Statistical Rethinking</a></li>
<li><a href="https://pragprog.com/titles/tpp20/the-pragmatic-programmer-20th-anniversary-edition/">The Pragmatic Programmer</a></li>
<li><a href="https://web.mit.edu/6.001/6.037/sicp.pdf">Structure and Interpretation of Computer Programs</a> (potentially even the <a href="https://mitpress.mit.edu/9780262543231/structure-and-interpretation-of-computer-programs/">JS edition</a>)</li>
</ul>
<p>Hopefully by saying this out aloud I will be able to actually complete this.</p>
<p>Similar to above, I guess I’ll break this up into 3 parts of the year:</p>
<ul>
<li>January - April: Statistical Rethinking (~4 chapters a month)</li>
<li>May - August: The Pragmatic Programmer (2 chapters a month)</li>
<li>September - December: Structure and Interpretation of Computer Programs (~1 chapter a month. But oh boy is that book massive…)</li>
</ul>
</section>
<section id="make-a-contribution-to-r-core" class="level2">
<h2 class="anchored" data-anchor-id="make-a-contribution-to-r-core">Make a contribution to R Core</h2>
<p>There is now an <a href="https://contributor.r-project.org/working-group">R Contribution Working Group</a>, which is focussed on encouraging new contributors to R core, with a focus on diversity and inclusion. I’ve joined the slack team, and put the next two meetings in my calendar.</p>
</section>
<section id="courses-books" class="level2">
<h2 class="anchored" data-anchor-id="courses-books">Courses &amp; books</h2>
<p>This year I’m going to be helping deliver a few more courses, the rough plan so far is:</p>
<ul>
<li>Feb 7: <a href="https://www.statsoc.org.au/event-5513733">greta course in Canberra</a></li>
<li>March 25/26: <a href="https://github.com/njtierney/qmd4sci">quarto for scientists</a> (online)</li>
<li>June: longitudinal data analysis</li>
<li>Later in the year: another course - functional programming? Missing data?</li>
</ul>
<p>Accompanying these courses I’d like to publish little living books, like I’ve done with the <a href="https://github.com/njtierney/rmd4sci">Rmarkdown for scientists book</a>.</p>
</section>
<section id="r-packages" class="level2">
<h2 class="anchored" data-anchor-id="r-packages">R packages</h2>
<ul>
<li>Publish and finish <a href="https://github.com/njtierney/conmat">conmat</a></li>
<li>Regular releases of <a href="https://github.com/greta-dev/greta">greta</a></li>
<li>Develop and release new pipeline on <a href="https://github.com/idem-lab/map-ir-pipeline">generalised stacking in insecticide resistance</a></li>
<li>Keep my other R packages updated</li>
</ul>
</section>
<section id="work-things" class="level2">
<h2 class="anchored" data-anchor-id="work-things">Work things</h2>
<p>The big goals for work this year are related to the above tasks, but the big ticket items for me are:</p>
<ol type="1">
<li>(Finally) release the Tensorflow 2 version of greta</li>
<li>Establish regular greta releases, create a greta blog</li>
<li>Develop documentation on the internals of greta</li>
<li>Develop a culture and community of practice at work with code review</li>
<li>Win grants for developing software to solve tricky problems in infectious disease modelling</li>
<li>Publish software as JOSS papers</li>
</ol>
</section>
<section id="other-misc-tech-ideas" class="level2">
<h2 class="anchored" data-anchor-id="other-misc-tech-ideas">Other misc tech / ideas</h2>
<ul>
<li>Blog regularly</li>
<li>Remember how to use <code>switch</code> reliably in R</li>
<li>Become more proficient with <code>git</code></li>
<li>Use <a href="https://lintr.r-lib.org/">lintr</a> in my projects</li>
<li>Consider doing a livestream of a tidy tuesday data cleaning / EDA</li>
<li>Condense my internet browsing into an RSS reader</li>
<li>Focus on getting quality sleep</li>
<li>Do more running</li>
</ul>
</section>
<section id="end" class="level1">
<h1>End</h1>
<p>My hope is that I’ll review these goals at the end of 2024. Honestly it’s quite scary to post these plans, and I’m questioning if this is even a good idea to do so publicly. But I think I’ve got the right intention, so let’s leave it at that.</p>


</section>

 ]]></description>
  <category>rstats</category>
  <category>functions</category>
  <category>goals</category>
  <guid>https://www.njtierney.com/posts/2024-01-08-goals/</guid>
  <pubDate>Wed, 10 Jan 2024 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Rstats RSE January Digest</title>
  <link>https://www.njtierney.com/posts/2024-01-10-rse-digest-january/</link>
  <description><![CDATA[ 
<header class="site-header">
  <h1 class="site-title">
    <a href="../../">
      <img class="hvr-grow site-logo" src="https://www.njtierney.com/assets/njt-logo-small.png" alt="Nick logo">
    </a>
    <span class="hvr-bob site-title-credibly">Credibly</span>
    <span class="hvr-hang site-title-curious">Curious</span>
  </h1>
  <p class="site-subtitle">
    Nick Tierney's (mostly) rstats blog
  </p>
  
</header>




<figure class="figure">
<img src="https://www.njtierney.com/posts/2024-01-10-rse-digest-january/img/happy-log.jpg" alt="A Happy Log, near Echo Lake, California. Fuji X100V, Nicholas Tierney." class="figure-img">

</figure>
<p>I’ve been trying to read a bit more widely about R programming and other features of programming lately. I’ve seen some great newsletters from people like Bob Rudis in his <a href="https://dailydrop.hrbrmstr.dev/">“Daily Drop” series</a>, and I think that has inspired me to collect my monthly reading notes into a blog post / digest / newsletter type thing.</p>
<p>I guess to articulate more clearly, want to do it for the following reasons:</p>
<ol type="1">
<li>Help me share bulk links of interest to the Research Software Engineer, with a focus being on those who use R.</li>
<li>Force me to read these links so I can provide a little summary of the content.</li>
<li>Engage more broadly with the RSE rstats community.</li>
<li>Somewhat catch up on the technology/rstats world since I hiked the <a href="https://njt.micro.blog/">pacific crest trail from May - October 2023</a>.</li>
</ol>
<p>My intention is for these to be short lists. But this one is already getting bigger. This might be something regular, or something irregular. Who knows, maybe it’s just a one off. Here we go.</p>
<section id="blog-news-posts" class="level1">
<h1>Blog / news posts</h1>
<p>Some of these links are things I missed, and other ones are just things I thought were really good. They could be new, they could be a few years old!</p>
<p><a href="https://tidydesign.substack.com/">Hadley Wickham’s Design Newsletter</a>. I’ve followed Hadley’s work quite closely since 2013, and I was a little alarmed to see I had somehow missed his starting a newsletter about: “designing and implementing quality R code”. I’d seen his book, <a href="https://design.tidyverse.org/">“tidy design principles”</a> a while back, but it’s super exciting that they are working on it again. I highly recommend the newsletter. It’s also nice to see people engaging with <code>#rstats</code> content in a place that isn’t social media.</p>
<p>The rOpenSci newletter is worth subscribing to, one of my favourite sections is the <a href="https://ropensci.org/blog/2023/11/24/news-november-2023/#package-development-corner">package development corner</a>, which contains lots of useful links to other cool new R features, blog posts, and more.</p>
<p><a href="https://www.mm218.dev/posts/2023-11-07-classed-errors/">Mike Mahoney’s post on classed errors</a> really helped solidify my understanding and the overall benefits to not only the user, but the developer.</p>
<p><a href="https://neopythonic.blogspot.com/2016/04/kings-day-speech.html">King’s Day Speech</a> by <a href="https://en.wikipedia.org/wiki/Guido_van_Rossum">Guido van Rossum</a>, <strong>the creator of the python language</strong>. A nice essay / auto biography. I especially enjoyed this quote:</p>
<blockquote class="blockquote">
<p>In reality, programming languages are how programmers express and communicate ideas — and the audience for those ideas is other programmers, not computers. The reason: the computer can take care of itself, but programmers are always working with other programmers, and poorly communicated ideas can cause expensive flops.</p>
</blockquote>
<p>They say, “science isn’t science until it’s communicated”, and building on that, I think that good science requires good communication. It doesn’t matter if your idea is world changing, if no one can understand it.</p>
<p>Bob Rudis’s <a href="https://dailydrop.hrbrmstr.dev/2024/01/01/drop-395-2024-01-01-happy-new-year/#">“Daily Driver” post</a> contains an amazing list of things he uses daily from hardware to OS, VPN, RSS readers, browsers, browser extensions, and more.</p>
<p><a href="https://yihui.org/en/2024/01/bye-rstudio/">“Bye, RStudio/Posit!”</a> by Yihui Xie. He’s leaving Posit! It came as a surprise to me. I have a lot of positive feelings about his incredible contributions to R and my career and life, I can’t condense them all here. But I know that his work on knitr, rmarkdown, xaringan, blogdown, and bookdown have all had incredibly positive impacts on how I communicate my work, and I simply don’t think I’d have the career I’ve had without him. Thank you, Yihui.</p>
</section>
<section id="r-packages" class="level1">
<h1>R Packages</h1>
<p>It’s hard to pick R packages to showcase, there are I think more than 20K on CRAN now. Rather than a laundry list of R packages I use, here are some of my favourite R packages that I use.</p>
<p><a href="https://tidyverse.tidyverse.org/">tidyverse</a>, I’d be lost without it. It is simply an outstanding collection of software for doing data science and statistics in R.</p>
<p><a href="https://docs.ropensci.org/targets/">targets</a>, one of my favourite R packages. <a href="https://wlandau.github.io/">Will Landau</a>, the developer behind targets is I think perhaps the most responsive and kindest maintainer I’ve ever encountered.</p>
<p><a href="https://github.com/milesmcbain/tflow">tflow</a> by <a href="https://milesmcbain.xyz/">Miles McBain</a>, an ergonomic package that goes alongside the targets package. Use along with Miles’s other package, <a href="https://github.com/milesmcbain/fnmate">fnmate</a>. I think these tips are really useful:</p>
<blockquote class="blockquote">
<ol type="1">
<li>Put all your target code in separate functions in <code>R/</code>. Use <code>fnmate</code> to quickly generate function definitions in the right place. Let the plan in <code>_targets.R</code> define the structure of the workflow and use it as a map for your sources. Use ‘jump to function’ to quickly navigate to them.</li>
</ol>
</blockquote>
<blockquote class="blockquote">
<ol type="1">
<li>Use a call <code>tar_make()</code> to kick off building your plan in a new R session.</li>
</ol>
</blockquote>
<blockquote class="blockquote">
<ol type="1">
<li>Put all your <a href="https://rdrr.io/r/base/library.html"><code>library()</code></a> calls into <code>packages.R</code>. This way you’ll have them in one place when you go to add sandboxing with <code>renv</code>, <code>packarat</code>, and <code>switchr</code> etc.</li>
</ol>
</blockquote>
<blockquote class="blockquote">
<ol type="1">
<li>Take advantage of automation for loading <code>targets</code> targets at the cursor with the ‘load target at cursor’ addin. Or the <code>tflow</code> addin: ‘load editor targets’ to load all targets referred to in the current editor.</li>
</ol>
</blockquote>
<p><a href="https://docs.ropensci.org/autotest/">autotest</a> by <a href="https://mpadge.github.io/">Mark Padgham</a> with <a href="https://ropensci.org/">rOpenSci</a>. This package does rigorous, automated testing of your R package. Useful to help really kick the tyres of your work.</p>
<p>And not quite an R package, but something from within <a href="https://github.com/r-lib/usethis">usethis</a>/<a href="https://github.com/r-lib/rlang/">rlang</a> as advertised by <a href="https://www.garrickadenbuie.com/">Garrick Aden Buie</a>, when <a href="https://aus.social/@grrrck@fosstodon.org/111564560024473157">commenting on</a> my blog post, <a href="https://www.njtierney.com/post/2023/12/06/long-errors-smell/">“Code Smell: Error Handling Eclipse”</a>:</p>
<blockquote class="blockquote">
<p>icymi and because it’s not widely publicized, there are type checking functions in {rlang} that you can copy into your package code with usethis::use_standalone() <a href="https://github.com/r-lib/rlang/blob/main/R/standalone-types-check.R" class="uri">https://github.com/r-lib/rlang/blob/main/R/standalone-types-check.R</a></p>
</blockquote>
<p>This is super useful because it injects selected R functions into your R package. So you can select some standalone functions to import directly into your code with:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" 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;">use_standalone</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://github.com/r-lib/rlang/blob/main/R/standalone-types-check.R"</span>)</span></code></pre></div></div>
<p>Importing code directly is an interesting take on things because normally in R you would import an R package, not copy over code. One benefit of this I think is that it lets you potentially tinker with the imported functions to suit your R package.</p>
</section>
<section id="talks-videos" class="level1">
<h1>Talks / Videos</h1>
<p>In part of writing a bit recently, I was reminded by a friend of <a href="https://jennybryan.org/">Jenny Bryan’s</a> UseR! keynote from 2018, <a href="https://youtu.be/7oyiPBjLAWY?si=bpmCGCJaVCysmUN5">Code Smells and Feels</a> - <a href="https://github.com/jennybc/code-smells-and-feels#readme">talk materials</a>. It is one of my favourite talks. I was there a few rows from the front when she gave it, but taking time to watch it again has been really great. Jenny is a talented communicator, and I’m going to list a couple of my favourite takeaways from the talk, but I don’t want to start just listing the content out from the talk. These tips will make the most sense alongside Jenny’s talk.</p>
<ul>
<li>Write simple condition. Use explaining variables.</li>
<li>Write functions. A few little functions &gt;&gt; than monster function. Small well-named helper function &gt;&gt; commented code.</li>
<li>Every if does not need an else, if you exit or return early. There is no <strong>else</strong> there is only <strong>if</strong>.</li>
<li>If your conditions deal with <strong>class</strong>, it’s time to get object oriented (OO), and use <strong>polymorphism</strong>.</li>
<li><a href="https://rdrr.io/r/base/switch.html"><code>switch()</code></a> is ideal if you need to dispatch different <strong>logic</strong>, based on a <strong>string</strong>.</li>
<li><a href="https://dplyr.tidyverse.org/reference/case_when.html"><code>dplyr::case_when()</code></a> is ideal if you need to dispatch different <strong>data</strong> based on <strong>data (+logic)</strong>.</li>
</ul>
<p><a href="https://www.youtube.com/watch?v=rz3_FDVt9eg">Managing many models with R</a> by <a href="">Hadley Wickham</a>. I couldn’t find the original keynote that I saw of this, which was at the <a href="">WOMBAT 2016 conference</a>. The main takeaway from this for me was understanding one of the major benefits of using functions, and understanding how to use <code>map</code>.</p>
<p><a href="https://www.youtube.com/live/8ZSaAM8hhJ4?si=o_tB4C8bsNezNyZ4">The Rise of the Research Software Engineer</a>, by <a href="https://walkingrandomly.com/?page_id=2">Mike Croucher</a>. A great talk covering a story of becoming a research software engineer, the importance of diversity of people, and technology in a team.</p>
<p><a href="https://www.youtube.com/watch?v=-J3wNP6u5YU">Naming things in code</a> by <a href="https://www.youtube.com/@CodeAesthetic">code aesthetic</a>. I care a lot about naming things, and I really liked these ideas:</p>
<ul>
<li>Avoid single letter variables</li>
<li>Never abbreviate</li>
<li>Don’t put types in your name (e.g., Icost for Integer Cost), aka “hungarian notation”.</li>
<li>Put units in variable names. e.g., weight_kg</li>
<li>Don’t name variables “utils”. Refactor.</li>
</ul>
</section>
<section id="papers" class="level1">
<h1>Papers</h1>
<p><a href="https://projecteuclid.org/journals/statistical-science/volume-16/issue-3/Statistical-Modeling--The-Two-Cultures-with-comments-and-a/10.1214/ss/1009213726.full">Statistical Modeling: The Two Cultures (with comments and a rejoinder by the author)</a>. It’s an absolute classic paper that I found really fundamental to understanding statistical modelling during my PhD. I like it because it introduces the ideas of prediction, and extracting information (inference), which are two really important concepts. It then kind of dunks on the statistics community, saying:</p>
<blockquote class="blockquote">
<p>The statistical community has been committed to the almost exclusive use of data models. This commitment has led to irrelevant theory, questionable conclusions, and has kept statisticians from working on a large range of interesting current problems…If our goal as a field is to use data to solve problems, then we need to move away from exclusive dependence on data models and adopt a more diverse set of tools.</p>
</blockquote>
</section>
<section id="newsletters" class="level1">
<h1>Newsletters</h1>
<p>I get a lot of these links from trawling through various newsletters and things on twitter and mastodon. Here are some of my current favourites.</p>
<p><a href="https://fhdata.substack.com/">Monday Morning Data Science</a> by the Fred Hutch group is great. Once a week, just a couple of links.</p>
<p><a href="https://heidiseibold.com/">Heidi Seibold</a> has a nice newsletter that I enjoy reading: <a href="https://heidiseibold.ck.page/" class="uri">https://heidiseibold.ck.page/</a></p>
<p>rOpenSci’s newsletter - which you can subscrive to at the bottom of this <a href="https://ropensci.org/blog/2023/12/22/news-december-2023/">recent newsletter blog post</a>.</p>
<p>Bob Rudis’s <a href="https://dailydrop.hrbrmstr.dev/">“Daily Drop”</a> newsletter.</p>
</section>
<section id="book-recommendations" class="level1">
<h1>Book recommendations</h1>
<p>I’ve been meaning to collect together a list of books for programming. Mostly through conversations with <a href="https://masalmon.eu/">Maëlle Salmon</a>, I’ve got a few books I’d like to read. I basically just sifted through Maëlle’s list of book notes and have put a couple here.</p>
<ul>
<li>The Pragmatic Programmer - see some reading notes by <a href="https://masalmon.eu/2023/12/11/reading-notes-pragmatic-programmer/">Maëlle Salmon</a></li>
<li>A Philosophy of Software Design - see more reading notes by <a href="https://masalmon.eu/2023/10/19/reading-notes-philosophy-software-design/">Maëlle Salmon</a></li>
</ul>
</section>
<section id="end" class="level1">
<h1>End</h1>
<p>That’s it. Thanks for reading! What have I missed? Let me know in the comments!</p>


</section>

 ]]></description>
  <category>rstats</category>
  <category>research software engineer</category>
  <category>rse</category>
  <category>digest</category>
  <category>newsletter</category>
  <guid>https://www.njtierney.com/posts/2024-01-10-rse-digest-january/</guid>
  <pubDate>Wed, 10 Jan 2024 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Code Smell: Error Handling Eclipse</title>
  <link>https://www.njtierney.com/posts/2023-12-01-long-errors-smell/</link>
  <description><![CDATA[ 
<header class="site-header">
  <h1 class="site-title">
    <a href="../../">
      <img class="hvr-grow site-logo" src="https://www.njtierney.com/assets/njt-logo-small.png" alt="Nick logo">
    </a>
    <span class="hvr-bob site-title-credibly">Credibly</span>
    <span class="hvr-hang site-title-curious">Curious</span>
  </h1>
  <p class="site-subtitle">
    Nick Tierney's (mostly) rstats blog
  </p>
  
</header>




<figure class="figure">
<img src="https://www.njtierney.com/posts/2023-12-01-long-errors-smell/img/no-parking.jpg" alt="An amusing “no parking” sign that threatens to transport your car to another universe. Collingwood, Melbourne" class="figure-img">

</figure>
<p>Error messages are really important, and really hard to write well. When software authors take the time to check your inputs, and share reasons why it fails, they are doing you a favour. So, writing error messages is good.</p>
<p>However, this error checking code can sometimes totally eclipse the intent of the code. We can describe these kinds of patterns as a “code smell”. I first heard about code smells in <a href="https://youtu.be/7oyiPBjLAWY?si=WmuA9wKlZ_kq8eGl">Jenny Bryan’s UseR! Keynote in 2018</a>, which I highly recommend watching. The term “code smell”, comes from <a href="https://martinfowler.com/books/refactoring.html">Martin Fowler’s book: Improving the Design of Existing Code</a>). The definition of a code smell that Jenny gives in her talk is:</p>
<blockquote class="blockquote">
<p>Structures in code that suggest (or scream for) <strong>refactoring</strong></p>
</blockquote>
<p>She then goes on to define refactoring as:</p>
<blockquote class="blockquote">
<p>Making code easier to understand for the next person (which might be you), cheaper to modify by the next person who comes through, <strong>without changing behaviour</strong>.</p>
</blockquote>
<p>The talk is a delight, and watching it again was really awesome. If you haven’t watched it, you should, and if you haven’t seen it for a while, it’s worth another watch.</p>
<p>Anyway, I digress.</p>
<p>I call this code smell, and “Error Handling Eclipse”:</p>
<blockquote class="blockquote">
<p>When error checking code totally eclipses the intent of the code.<sup>1</sup></p>
</blockquote>
<p>The code smell looks like this:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">vector_to_square</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">data</span><span class="o">)</span> <span class="o">{</span></span>
<span>  <span class="nv">dims</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/MathFun.html">sqrt</a></span><span class="o">(</span><span class="nf"><a href="https://rdrr.io/r/base/length.html">length</a></span><span class="o">(</span><span class="nv">data</span><span class="o">)</span><span class="o">)</span></span>
<span>  </span>
<span>  <span class="nv">squarable_length</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/Round.html">floor</a></span><span class="o">(</span><span class="nv">dims</span><span class="o">)</span> <span class="o">==</span> <span class="nv">dims</span></span>
<span>  </span>
<span>  <span class="kr">if</span> <span class="o">(</span><span class="o">!</span><span class="nv">squarable_length</span><span class="o">)</span> <span class="o">{</span></span>
<span>    <span class="nf">cli</span><span class="nf">::</span><span class="nf"><a href="https://cli.r-lib.org/reference/cli_abort.html">cli_abort</a></span><span class="o">(</span></span>
<span>      <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span></span>
<span>        <span class="s">"Provided vector is not of a squarable length"</span>,</span>
<span>        <span class="s">"{.var data} is of length {.num {length(data)}}"</span>,</span>
<span>        <span class="s">"This cannot be represented as a square"</span>,</span>
<span>        <span class="s">"Square root of {.var dim(data)} is: {.num {round(dims, 3)}}."</span></span>
<span>      <span class="o">)</span></span>
<span>    <span class="o">)</span></span>
<span>  <span class="o">}</span></span>
<span>  </span>
<span>  <span class="kr">if</span> <span class="o">(</span><span class="o">!</span><span class="nf"><a href="https://rdrr.io/r/base/numeric.html">is.numeric</a></span><span class="o">(</span><span class="nv">data</span><span class="o">)</span><span class="o">)</span> <span class="o">{</span></span>
<span>    <span class="nf">cli</span><span class="nf">::</span><span class="nf"><a href="https://cli.r-lib.org/reference/cli_abort.html">cli_abort</a></span><span class="o">(</span></span>
<span>      <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span></span>
<span>        <span class="s">"Provided vector must be {.cls numeric}, not {.cls {class(data)}}"</span>,</span>
<span>        <span class="s">"We see that {.run is.numeric(data)} returns {.cls {class(data)}}"</span></span>
<span>      <span class="o">)</span></span>
<span>    <span class="o">)</span></span>
<span>  <span class="o">}</span></span>
<span>  </span>
<span>  <span class="nf"><a href="https://rdrr.io/r/base/matrix.html">matrix</a></span><span class="o">(</span></span>
<span>    data <span class="o">=</span> <span class="nv">data</span>,</span>
<span>    nrow <span class="o">=</span> <span class="nv">dims</span>,</span>
<span>    ncol <span class="o">=</span> <span class="nv">dims</span>,</span>
<span>    byrow <span class="o">=</span> <span class="kc">TRUE</span></span>
<span>  <span class="o">)</span></span>
<span><span class="o">}</span></span></code></pre>
</div>
<p>The code smell, “error handling eclipse”, can be seen here where the long error messages in the body of a function crow the intent. I believe the refactoring move here is to wrap these error functions into a function. This reduces repetition, and makes the intent of the code clearer, since you don’t need to wade through error checking code. <a href="https://design.tidyverse.org/err-constructor.html">The tidyverse design document on error checking</a>) mentions building these “error checking” functions when the error is used three times. I think there is more benefit to write it out every time.</p>
<section id="whats-the-solution" class="level2">
<h2 class="anchored" data-anchor-id="whats-the-solution">What’s the solution?</h2>
<p>This code can be improved by refactoring the errors as <code>check_*</code> functions, something like, <code>check_array_is_square(x)</code>.</p>
</section>
<section id="show-me-the-difference" class="level2">
<h2 class="anchored" data-anchor-id="show-me-the-difference">Show me the difference</h2>
<p>To demonstrate this, let’s take a look again at the example code from above, a function that converts a vector into a square matrix:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">vector_to_square</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">data</span><span class="o">)</span> <span class="o">{</span></span>
<span>  <span class="nv">dims</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/MathFun.html">sqrt</a></span><span class="o">(</span><span class="nf"><a href="https://rdrr.io/r/base/length.html">length</a></span><span class="o">(</span><span class="nv">data</span><span class="o">)</span><span class="o">)</span></span>
<span>  </span>
<span>  <span class="nv">squarable_length</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/Round.html">floor</a></span><span class="o">(</span><span class="nv">dims</span><span class="o">)</span> <span class="o">==</span> <span class="nv">dims</span></span>
<span>  </span>
<span>  <span class="kr">if</span> <span class="o">(</span><span class="o">!</span><span class="nv">squarable_length</span><span class="o">)</span> <span class="o">{</span></span>
<span>    <span class="nf">cli</span><span class="nf">::</span><span class="nf"><a href="https://cli.r-lib.org/reference/cli_abort.html">cli_abort</a></span><span class="o">(</span></span>
<span>      <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span></span>
<span>        <span class="s">"Provided vector is not of a squarable length"</span>,</span>
<span>        <span class="s">"{.var x} is of length {.num {length(data)}}"</span>,</span>
<span>        <span class="s">"This cannot be represented as a square"</span>,</span>
<span>        <span class="s">"Square root of {.var dim(data)} is: {.num {round(dims, 3)}}."</span></span>
<span>      <span class="o">)</span></span>
<span>    <span class="o">)</span></span>
<span>  <span class="o">}</span></span>
<span>  </span>
<span>  <span class="kr">if</span> <span class="o">(</span><span class="o">!</span><span class="nf"><a href="https://rdrr.io/r/base/numeric.html">is.numeric</a></span><span class="o">(</span><span class="nv">data</span><span class="o">)</span><span class="o">)</span> <span class="o">{</span></span>
<span>    <span class="nf">cli</span><span class="nf">::</span><span class="nf"><a href="https://cli.r-lib.org/reference/cli_abort.html">cli_abort</a></span><span class="o">(</span></span>
<span>      <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span></span>
<span>        <span class="s">"Provided vector must be {.cls numeric}, not {.cls {class(data)}}"</span>,</span>
<span>        <span class="s">"We see that {.run is.numeric(data)} returns {.cls {class(data)}}"</span></span>
<span>      <span class="o">)</span></span>
<span>    <span class="o">)</span></span>
<span>  <span class="o">}</span></span>
<span>  </span>
<span>  <span class="nf"><a href="https://rdrr.io/r/base/matrix.html">matrix</a></span><span class="o">(</span></span>
<span>    data <span class="o">=</span> <span class="nv">data</span>,</span>
<span>    nrow <span class="o">=</span> <span class="nv">dims</span>,</span>
<span>    ncol <span class="o">=</span> <span class="nv">dims</span>,</span>
<span>    byrow <span class="o">=</span> <span class="kc">TRUE</span></span>
<span>  <span class="o">)</span></span>
<span><span class="o">}</span></span></code></pre>
</div>
<p>Now let’s demonstrate its use, and what the errors look like:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf">vector_to_square</span><span class="o">(</span>data <span class="o">=</span> <span class="m">1</span><span class="o">:</span><span class="m">4</span><span class="o">)</span></span>
<span><span class="c">#&gt;      [,1] [,2]</span></span>
<span><span class="c">#&gt; [1,]    1    2</span></span>
<span><span class="c">#&gt; [2,]    3    4</span></span>
<span></span><span><span class="nf">vector_to_square</span><span class="o">(</span>data <span class="o">=</span> <span class="m">1</span><span class="o">:</span><span class="m">5</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #BBBB00; font-weight: bold;">Error</span><span style="font-weight: bold;"> in `vector_to_square()`:</span></span></span>
<span><span class="c">#&gt; <span style="color: #BBBB00;">!</span> Provided vector is not of a squarable length</span></span>
<span><span class="c">#&gt; `x` is of length 5</span></span>
<span><span class="c">#&gt; This cannot be represented as a square</span></span>
<span><span class="c">#&gt; Square root of `dim(data)` is: 2.236.</span></span>
<span></span><span><span class="nf">vector_to_square</span><span class="o">(</span>data <span class="o">=</span> <span class="nv">LETTERS</span><span class="o">[</span><span class="m">1</span><span class="o">:</span><span class="m">4</span><span class="o">]</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #BBBB00; font-weight: bold;">Error</span><span style="font-weight: bold;"> in `vector_to_square()`:</span></span></span>
<span><span class="c">#&gt; <span style="color: #BBBB00;">!</span> Provided vector must be <span style="color: #0000BB;">&lt;numeric&gt;</span>, not <span style="color: #0000BB;">&lt;character&gt;</span></span></span>
<span><span class="c">#&gt; We see that `is.numeric(data)` returns <span style="color: #0000BB;">&lt;character&gt;</span></span></span>
<span></span></code></pre>
</div>
<p>So we have some input checking code, which does two things:</p>
<ul>
<li>checks if the inputs can be a square matrix</li>
<li>checks if inputs are not numeric</li>
</ul>
<p>While we like these error messages, wrapping up the error messags as functions clarifies the intent of them, and avoids repitition:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">check_if_squarable</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">x</span><span class="o">)</span> <span class="o">{</span></span>
<span>  <span class="nv">dims</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/MathFun.html">sqrt</a></span><span class="o">(</span><span class="nf"><a href="https://rdrr.io/r/base/length.html">length</a></span><span class="o">(</span><span class="nv">x</span><span class="o">)</span><span class="o">)</span></span>
<span>  </span>
<span>  <span class="nv">squarable_length</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/Round.html">floor</a></span><span class="o">(</span><span class="nv">dims</span><span class="o">)</span> <span class="o">==</span> <span class="nv">dims</span></span>
<span>  </span>
<span>  <span class="kr">if</span> <span class="o">(</span><span class="o">!</span><span class="nv">squarable_length</span><span class="o">)</span> <span class="o">{</span></span>
<span>    <span class="nf">cli</span><span class="nf">::</span><span class="nf"><a href="https://cli.r-lib.org/reference/cli_abort.html">cli_abort</a></span><span class="o">(</span></span>
<span>      <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span></span>
<span>        <span class="s">"Provided vector is not of a squarable length"</span>,</span>
<span>        <span class="s">"{.var x} is of length {.num {length(x)}}"</span>,</span>
<span>        <span class="s">"This cannot be represented as a square"</span>,</span>
<span>        <span class="s">"Square root of {.var dim(x)} is: {.num {round(dims, 3)}}."</span></span>
<span>      <span class="o">)</span></span>
<span>    <span class="o">)</span></span>
<span>  <span class="o">}</span></span>
<span><span class="o">}</span></span>
<span></span>
<span><span class="nv">check_if_not_numeric</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">x</span><span class="o">)</span> <span class="o">{</span></span>
<span>  <span class="kr">if</span> <span class="o">(</span><span class="o">!</span><span class="nf"><a href="https://rdrr.io/r/base/numeric.html">is.numeric</a></span><span class="o">(</span><span class="nv">x</span><span class="o">)</span><span class="o">)</span> <span class="o">{</span></span>
<span>    <span class="nf">cli</span><span class="nf">::</span><span class="nf"><a href="https://cli.r-lib.org/reference/cli_abort.html">cli_abort</a></span><span class="o">(</span></span>
<span>      <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span></span>
<span>        <span class="s">"Provided vector must be {.cls numeric}, not {.cls {class(x)}}"</span>,</span>
<span>        <span class="s">"We see that {.run is.numeric(x)} returns {.cls {class(x)}}"</span></span>
<span>      <span class="o">)</span></span>
<span>    <span class="o">)</span></span>
<span>  <span class="o">}</span></span>
<span>  </span>
<span><span class="o">}</span></span></code></pre>
</div>
<p>These error messages can then be put into the function like so:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">vector_to_square</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">data</span><span class="o">)</span> <span class="o">{</span></span>
<span>  <span class="nf">check_if_squarable</span><span class="o">(</span><span class="nv">data</span><span class="o">)</span></span>
<span>  <span class="nf">check_if_not_numeric</span><span class="o">(</span><span class="nv">data</span><span class="o">)</span></span>
<span>  </span>
<span>  <span class="nv">dims</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/MathFun.html">sqrt</a></span><span class="o">(</span><span class="nf"><a href="https://rdrr.io/r/base/length.html">length</a></span><span class="o">(</span><span class="nv">data</span><span class="o">)</span><span class="o">)</span></span>
<span>  </span>
<span>  <span class="nf"><a href="https://rdrr.io/r/base/matrix.html">matrix</a></span><span class="o">(</span></span>
<span>    data <span class="o">=</span> <span class="nv">data</span>,</span>
<span>    nrow <span class="o">=</span> <span class="nv">dims</span>,</span>
<span>    ncol <span class="o">=</span> <span class="nv">dims</span>,</span>
<span>    byrow <span class="o">=</span> <span class="kc">TRUE</span></span>
<span>  <span class="o">)</span></span>
<span><span class="o">}</span></span></code></pre>
</div>
<p>The error checking code no longer eclipses your intent.</p>
<p>I think the main benefit here is <em>improvement in intent</em> - I don’t have to read some error checking code, I can read the function name <code>check_if_squarable(data)</code> - this tells me it checks if it is squareable, and <code>check_if_not_numeric(data)</code> does what it says on the tin. This means I don’t have to spend time reading error checking code, which can sometimes be quite complex. I can focus on those functions intention. This means I can summarise this function like so:</p>
<ul>
<li><p>Do some checking of the inputs</p></li>
<li><p>Get the dimensions for a square matrix</p></li>
<li><p>Make the matrix, filling in by row</p></li>
</ul>
<p>There are a couple of other benefits to this:</p>
<ul>
<li>All my checking functions can get re-used in the other work I do</li>
<li>I can find common cases of checking and improve them.</li>
<li>I see two checking functions, and it invites me to think about other checks that I might want to perform.</li>
</ul>
</section>
<section id="but-now-the-error-smells" class="level2">
<h2 class="anchored" data-anchor-id="but-now-the-error-smells">But now the error smells</h2>
<p>Ah, but we didn’t check to see what these new errors look like! My friend <a href="https://adamgruer.rbind.io/">Adam Gruer</a> pointed out:</p>
<blockquote class="blockquote">
<p>might a user get confused when then the error is reported as coming from the check_function rather than the function they called? What are your thoughts?</p>
</blockquote>
<p>Indeed, the errors are now different, check it out:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf">vector_to_square</span><span class="o">(</span>data <span class="o">=</span> <span class="m">1</span><span class="o">:</span><span class="m">4</span><span class="o">)</span></span>
<span><span class="c">#&gt;      [,1] [,2]</span></span>
<span><span class="c">#&gt; [1,]    1    2</span></span>
<span><span class="c">#&gt; [2,]    3    4</span></span>
<span></span><span><span class="nf">vector_to_square</span><span class="o">(</span>data <span class="o">=</span> <span class="m">1</span><span class="o">:</span><span class="m">5</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #BBBB00; font-weight: bold;">Error</span><span style="font-weight: bold;"> in `check_if_squarable()`:</span></span></span>
<span><span class="c">#&gt; <span style="color: #BBBB00;">!</span> Provided vector is not of a squarable length</span></span>
<span><span class="c">#&gt; `x` is of length 5</span></span>
<span><span class="c">#&gt; This cannot be represented as a square</span></span>
<span><span class="c">#&gt; Square root of `dim(x)` is: 2.236.</span></span>
<span></span><span><span class="nf">vector_to_square</span><span class="o">(</span>data <span class="o">=</span> <span class="nv">LETTERS</span><span class="o">[</span><span class="m">1</span><span class="o">:</span><span class="m">4</span><span class="o">]</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #BBBB00; font-weight: bold;">Error</span><span style="font-weight: bold;"> in `check_if_not_numeric()`:</span></span></span>
<span><span class="c">#&gt; <span style="color: #BBBB00;">!</span> Provided vector must be <span style="color: #0000BB;">&lt;numeric&gt;</span>, not <span style="color: #0000BB;">&lt;character&gt;</span></span></span>
<span><span class="c">#&gt; We see that `is.numeric(x)` returns <span style="color: #0000BB;">&lt;character&gt;</span></span></span>
<span></span></code></pre>
</div>
<p>The error message is about the <strong>checking</strong> function, <code>check_if_squarable()</code> or <code>check_if_not_numeric()</code>. This could be confusing to the user as the error doesn’t appear to be coming from the <code>vector_to_square()</code> function.</p>
<p>Seeing this also made me realise I’ve seen this problem before and been unsure how to solve it. Thankfully, the rlang team has thought about this, and they have a helpful vignette, <a href="https://rlang.r-lib.org/reference/topic-error-call.html">“Including function calls in error messages”</a>.</p>
<p>They bring up two really great points. Both of which I hadn’t really thought about solving. I just thought this was the compromise.</p>
<p>The first is how to make sure the input checking function references the function it was called in. This is why we see the error being about <code>check_if_squarable()</code>, and not <code>vector_to_square()</code>, which is what we want.</p>
<p>This is solved by passing the <code>check_</code> functions a <code>call</code> environment. So we add <code>call = rlang::caller_env()</code> as an argument:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">check_if_squarable</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">x</span>,</span>
<span>                               <span class="c"># Add this</span></span>
<span>                               <span class="nv">call</span> <span class="o">=</span> <span class="nf">rlang</span><span class="nf">::</span><span class="nf"><a href="https://rlang.r-lib.org/reference/stack.html">caller_env</a></span><span class="o">(</span><span class="o">)</span><span class="o">)</span> <span class="o">{</span></span>
<span>  <span class="nv">dims</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/MathFun.html">sqrt</a></span><span class="o">(</span><span class="nf"><a href="https://rdrr.io/r/base/length.html">length</a></span><span class="o">(</span><span class="nv">x</span><span class="o">)</span><span class="o">)</span></span>
<span>  </span>
<span>  <span class="nv">squarable_length</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/Round.html">floor</a></span><span class="o">(</span><span class="nv">dims</span><span class="o">)</span> <span class="o">==</span> <span class="nv">dims</span></span>
<span>  </span>
<span>  <span class="kr">if</span> <span class="o">(</span><span class="o">!</span><span class="nv">squarable_length</span><span class="o">)</span> <span class="o">{</span></span>
<span>    <span class="nf">cli</span><span class="nf">::</span><span class="nf"><a href="https://cli.r-lib.org/reference/cli_abort.html">cli_abort</a></span><span class="o">(</span></span>
<span>      message <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span></span>
<span>        <span class="s">"Provided vector is not of a squarable length"</span>,</span>
<span>        <span class="s">"{.var x} is of length {.num {length(x)}}"</span>,</span>
<span>        <span class="s">"This cannot be represented as a square"</span>,</span>
<span>        <span class="s">"Square root of {.var dim(x)} is: {.num {round(dims, 3)}}."</span></span>
<span>      <span class="o">)</span>,</span>
<span>      <span class="c"># And this</span></span>
<span>      call <span class="o">=</span> <span class="nv">call</span></span>
<span>    <span class="o">)</span></span>
<span>  <span class="o">}</span></span>
<span><span class="o">}</span></span>
<span></span>
<span><span class="nv">check_if_not_numeric</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">x</span>,</span>
<span>                                 <span class="c"># Add this</span></span>
<span>                                 <span class="nv">call</span> <span class="o">=</span> <span class="nf">rlang</span><span class="nf">::</span><span class="nf"><a href="https://rlang.r-lib.org/reference/stack.html">caller_env</a></span><span class="o">(</span><span class="o">)</span><span class="o">)</span> <span class="o">{</span></span>
<span>  <span class="kr">if</span> <span class="o">(</span><span class="o">!</span><span class="nf"><a href="https://rdrr.io/r/base/numeric.html">is.numeric</a></span><span class="o">(</span><span class="nv">x</span><span class="o">)</span><span class="o">)</span> <span class="o">{</span></span>
<span>    <span class="nf">cli</span><span class="nf">::</span><span class="nf"><a href="https://cli.r-lib.org/reference/cli_abort.html">cli_abort</a></span><span class="o">(</span></span>
<span>      message <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span></span>
<span>        <span class="s">"Provided vector must be {.cls numeric}, not {.cls {class(x)}}"</span>,</span>
<span>        <span class="s">"We see that {.run is.numeric(x)} returns {.cls {class(x)}}"</span></span>
<span>      <span class="o">)</span>,</span>
<span>      <span class="c"># And this</span></span>
<span>      call <span class="o">=</span> <span class="nv">call</span></span>
<span>    <span class="o">)</span></span>
<span>  <span class="o">}</span></span>
<span>  </span>
<span><span class="o">}</span></span></code></pre>
</div>
<p>Let’s see what that looks like now:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf">vector_to_square</span><span class="o">(</span>data <span class="o">=</span> <span class="m">1</span><span class="o">:</span><span class="m">4</span><span class="o">)</span></span>
<span><span class="c">#&gt;      [,1] [,2]</span></span>
<span><span class="c">#&gt; [1,]    1    2</span></span>
<span><span class="c">#&gt; [2,]    3    4</span></span>
<span></span><span><span class="nf">vector_to_square</span><span class="o">(</span>data <span class="o">=</span> <span class="m">1</span><span class="o">:</span><span class="m">5</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #BBBB00; font-weight: bold;">Error</span><span style="font-weight: bold;"> in `vector_to_square()`:</span></span></span>
<span><span class="c">#&gt; <span style="color: #BBBB00;">!</span> Provided vector is not of a squarable length</span></span>
<span><span class="c">#&gt; `x` is of length 5</span></span>
<span><span class="c">#&gt; This cannot be represented as a square</span></span>
<span><span class="c">#&gt; Square root of `dim(x)` is: 2.236.</span></span>
<span></span><span><span class="nf">vector_to_square</span><span class="o">(</span>data <span class="o">=</span> <span class="nv">LETTERS</span><span class="o">[</span><span class="m">1</span><span class="o">:</span><span class="m">4</span><span class="o">]</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #BBBB00; font-weight: bold;">Error</span><span style="font-weight: bold;"> in `vector_to_square()`:</span></span></span>
<span><span class="c">#&gt; <span style="color: #BBBB00;">!</span> Provided vector must be <span style="color: #0000BB;">&lt;numeric&gt;</span>, not <span style="color: #0000BB;">&lt;character&gt;</span></span></span>
<span><span class="c">#&gt; We see that `is.numeric(x)` returns <span style="color: #0000BB;">&lt;character&gt;</span></span></span>
<span></span></code></pre>
</div>
<p>OK much better, the error now starts with: “Error in <code>vector_to_square()</code>”.</p>
<p>The second problem, which is hauntingly familiar, is to do with supplying argument names. Notice that the error message gives the error in terms of the argument <code>x</code>? Despite our argument to <code>vector_to_square</code> using the argument, <code>data</code></p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf">vector_to_square</span><span class="o">(</span>data <span class="o">=</span> <span class="m">1</span><span class="o">:</span><span class="m">4</span><span class="o">)</span></span>
<span><span class="c">#&gt;      [,1] [,2]</span></span>
<span><span class="c">#&gt; [1,]    1    2</span></span>
<span><span class="c">#&gt; [2,]    3    4</span></span>
<span></span><span><span class="nf">vector_to_square</span><span class="o">(</span>data <span class="o">=</span> <span class="m">1</span><span class="o">:</span><span class="m">5</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #BBBB00; font-weight: bold;">Error</span><span style="font-weight: bold;"> in `vector_to_square()`:</span></span></span>
<span><span class="c">#&gt; <span style="color: #BBBB00;">!</span> Provided vector is not of a squarable length</span></span>
<span><span class="c">#&gt; `x` is of length 5</span></span>
<span><span class="c">#&gt; This cannot be represented as a square</span></span>
<span><span class="c">#&gt; Square root of `dim(x)` is: 2.236.</span></span>
<span></span><span><span class="nf">vector_to_square</span><span class="o">(</span>data <span class="o">=</span> <span class="nv">LETTERS</span><span class="o">[</span><span class="m">1</span><span class="o">:</span><span class="m">4</span><span class="o">]</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #BBBB00; font-weight: bold;">Error</span><span style="font-weight: bold;"> in `vector_to_square()`:</span></span></span>
<span><span class="c">#&gt; <span style="color: #BBBB00;">!</span> Provided vector must be <span style="color: #0000BB;">&lt;numeric&gt;</span>, not <span style="color: #0000BB;">&lt;character&gt;</span></span></span>
<span><span class="c">#&gt; We see that `is.numeric(x)` returns <span style="color: #0000BB;">&lt;character&gt;</span></span></span>
<span></span></code></pre>
</div>
<p>A small detail, perhaps? But I think it’s actually kind of a big problem! I don’t want my users to have to try and reckon/think about what <code>x</code> is, or have to imagine that I’ve written some fancy code checking functions. I just want them to know where the error came from. In more complex functions this could be even more confusing.</p>
<p>Thankfully, yet again, the rlang team has thought about this, in <a href="https://rlang.r-lib.org/reference/topic-error-call.html#input-checkers-and-caller-arg-">Input checkers and <code>caller_arg()</code></a>, they suggest adding <code>arg = rlang::caller_arg(x)</code> to our checking function, which helps capture the name of the argument that is passed to the check functions. Super neat.</p>
<p>Let’s demonstrate this - we change uses of <code>x</code> to using <code>arg</code> in the error message.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">check_if_squarable</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">x</span>,</span>
<span>                               <span class="nv">arg</span> <span class="o">=</span> <span class="nf">rlang</span><span class="nf">::</span><span class="nf"><a href="https://rlang.r-lib.org/reference/caller_arg.html">caller_arg</a></span><span class="o">(</span><span class="nv">x</span><span class="o">)</span>,</span>
<span>                               <span class="nv">call</span> <span class="o">=</span> <span class="nf">rlang</span><span class="nf">::</span><span class="nf"><a href="https://rlang.r-lib.org/reference/stack.html">caller_env</a></span><span class="o">(</span><span class="o">)</span><span class="o">)</span> <span class="o">{</span></span>
<span>  <span class="nv">x_len</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/length.html">length</a></span><span class="o">(</span><span class="nv">x</span><span class="o">)</span></span>
<span>  <span class="nv">dims</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/MathFun.html">sqrt</a></span><span class="o">(</span><span class="nv">x_len</span><span class="o">)</span></span>
<span>  </span>
<span>  <span class="nv">squarable_length</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/Round.html">floor</a></span><span class="o">(</span><span class="nv">dims</span><span class="o">)</span> <span class="o">==</span> <span class="nv">dims</span></span>
<span>  </span>
<span>  <span class="kr">if</span> <span class="o">(</span><span class="o">!</span><span class="nv">squarable_length</span><span class="o">)</span> <span class="o">{</span></span>
<span>    <span class="nf">cli</span><span class="nf">::</span><span class="nf"><a href="https://cli.r-lib.org/reference/cli_abort.html">cli_abort</a></span><span class="o">(</span></span>
<span>      message <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span></span>
<span>        <span class="s">"Provided vector is not of a squarable length"</span>,</span>
<span>        <span class="s">"{.arg {arg}} is of length {.num {x_len}}"</span>,</span>
<span>        <span class="s">"This cannot be represented as a square"</span></span>
<span>      <span class="o">)</span>,</span>
<span>      call <span class="o">=</span> <span class="nv">call</span></span>
<span>    <span class="o">)</span></span>
<span>  <span class="o">}</span></span>
<span><span class="o">}</span></span>
<span></span>
<span><span class="nv">check_if_not_numeric</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">x</span>,</span>
<span>                                 <span class="nv">arg</span> <span class="o">=</span> <span class="nf">rlang</span><span class="nf">::</span><span class="nf"><a href="https://rlang.r-lib.org/reference/caller_arg.html">caller_arg</a></span><span class="o">(</span><span class="nv">x</span><span class="o">)</span>,</span>
<span>                                 <span class="nv">call</span> <span class="o">=</span> <span class="nf">rlang</span><span class="nf">::</span><span class="nf"><a href="https://rlang.r-lib.org/reference/stack.html">caller_env</a></span><span class="o">(</span><span class="o">)</span><span class="o">)</span> <span class="o">{</span></span>
<span>  <span class="kr">if</span> <span class="o">(</span><span class="o">!</span><span class="nf"><a href="https://rdrr.io/r/base/numeric.html">is.numeric</a></span><span class="o">(</span><span class="nv">x</span><span class="o">)</span><span class="o">)</span> <span class="o">{</span></span>
<span>    <span class="nf">cli</span><span class="nf">::</span><span class="nf"><a href="https://cli.r-lib.org/reference/cli_abort.html">cli_abort</a></span><span class="o">(</span></span>
<span>      message <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span></span>
<span>        <span class="s">"Provided vector, {.arg {arg}}, must be {.cls numeric}, not {.cls {class(x)}}"</span>,</span>
<span>        <span class="s">"We see that {.run is.numeric({.arg {arg}})} returns {.cls {class(x)}}"</span></span>
<span>      <span class="o">)</span>,</span>
<span>      call <span class="o">=</span> <span class="nv">call</span></span>
<span>    <span class="o">)</span></span>
<span>  <span class="o">}</span></span>
<span>  </span>
<span><span class="o">}</span></span></code></pre>
</div>
<p>(in rewriting-ing this, I realised I don’t need to include the square root of the length to explain to the user, so I deleted that part of the message)</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf">vector_to_square</span><span class="o">(</span>data <span class="o">=</span> <span class="m">1</span><span class="o">:</span><span class="m">4</span><span class="o">)</span></span>
<span><span class="c">#&gt;      [,1] [,2]</span></span>
<span><span class="c">#&gt; [1,]    1    2</span></span>
<span><span class="c">#&gt; [2,]    3    4</span></span>
<span></span><span><span class="nf">vector_to_square</span><span class="o">(</span>data <span class="o">=</span> <span class="m">1</span><span class="o">:</span><span class="m">5</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #BBBB00; font-weight: bold;">Error</span><span style="font-weight: bold;"> in `vector_to_square()`:</span></span></span>
<span><span class="c">#&gt; <span style="color: #BBBB00;">!</span> Provided vector is not of a squarable length</span></span>
<span><span class="c">#&gt; `data` is of length 5</span></span>
<span><span class="c">#&gt; This cannot be represented as a square</span></span>
<span></span><span><span class="nf">vector_to_square</span><span class="o">(</span>data <span class="o">=</span> <span class="nv">LETTERS</span><span class="o">[</span><span class="m">1</span><span class="o">:</span><span class="m">4</span><span class="o">]</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #BBBB00; font-weight: bold;">Error</span><span style="font-weight: bold;"> in `vector_to_square()`:</span></span></span>
<span><span class="c">#&gt; <span style="color: #BBBB00;">!</span> Provided vector, `data`, must be <span style="color: #0000BB;">&lt;numeric&gt;</span>, not <span style="color: #0000BB;">&lt;character&gt;</span></span></span>
<span><span class="c">#&gt; We see that `` is.numeric(`data`) `` returns <span style="color: #0000BB;">&lt;character&gt;</span></span></span>
<span></span></code></pre>
</div>
<p>This now uses <code>data</code> instead of <code>x</code>, which is what we want!</p>
</section>
<section id="on-writing-error-messages" class="level1">
<h1>On writing error messages</h1>
<p>I do think that writing good error messages is hard. Something that helped me think about this differently was something from the <a href="https://style.tidyverse.org/error-messages.html">tidyverse style guide on error messages</a>:</p>
<blockquote class="blockquote">
<p>An error message should start with a general statement of the problem then give a concise description of what went wrong. Consistent use of punctuation and formatting makes errors easier to parse</p>
</blockquote>
<p>They also recommend using <a href="https://cli.r-lib.org/reference/cli_abort.html"><code>cli::cli_abort()</code></a>, which we used above. I’ve really enjoyed using this over <code>stop</code>, because, well, again, the tidyverse team summarises the reasons well, <a href="https://cli.r-lib.org/reference/cli_abort.html"><code>cli::cli_abort()</code></a> is good because it:</p>
<blockquote class="blockquote">
<ul>
<li><p>Makes it easy to generate bulleted lists.</p></li>
<li><p>Uses glue style interpolation to insert data into the error.</p></li>
<li><p>Supports a wide range of <a href="https://cli.r-lib.org/reference/inline-markup.html">inline markup</a>.</p></li>
<li><p>Provides convenient tools to <a href="https://rlang.r-lib.org/reference/topic-error-chaining.html">chain errors together</a>.</p></li>
<li><p>Can control the <a href="https://rlang.r-lib.org/reference/topic-error-call.html">name of the function</a> shown in the error.</p></li>
</ul>
</blockquote>
<p>You should read the <a href="https://style.tidyverse.org/error-messages.html">whole section on error messages</a>, they’ve got great advice on how to write good error messages.</p>
</section>
<section id="on-input-checking-functions" class="level1">
<h1>On input checking functions</h1>
<p>This type of error message is often called an “input checking function”. There’s a really nice blog post <a href="https://blog.r-hub.io/2022/03/10/input-checking/">“Checking the inputs of your R functions”</a>, by <a href="https://hugogruson.fr/">Hugo Gruson</a>, <a href="https://samabbott.co.uk/">Sam Abbott</a>, and <a href="https://twitter.com/cap1024">Carl Pearson</a>, which goes into more detail on the topic. They also recommend a few packages/functions for input checking that are worth checking out, such as <a href="https://mllg.github.io/checkmate/"><code>checkmate</code></a>, <a href="https://vctrs.r-lib.org/reference/vec_assert.html"><code>vec_assert()</code></a>, <a href="https://github.com/brodieG/vetr"><code>vetr</code></a>, and <a href="https://github.com/ropensci/assertr/"><code>assertr</code></a> to list a few.</p>
</section>
<section id="some-more-thoughts" class="level1">
<h1>Some more thoughts</h1>
<p>In writing this blog post I’ve now realised that my pattern of creating <code>check_</code> functions for input checking now also results in a potentially undesirable error for the user where they won’t know where the error has come from. I’ll need to make a note to change this in a lot of my packages.</p>
<p>In the future I’d really like to dive a bit deeper into adding classes or subclasses of errors. <a href="https://www.mm218.dev/posts/2023-11-07-classed-errors/">Mike Mahoney’s blog post, “Classed conditions from rlang functions”</a> provides a good simple usecase of classed errors. And there’s a <a href="https://design.tidyverse.org/err-constructor.html">tidyverse design page on error constructors</a> that I should read more deeply. I’m pretty sure this would be helpful in things like <a href="https://greta-stats.org/"><code>greta</code></a>.</p>
</section>
<section id="functions-are-good" class="level1">
<h1>Functions are good</h1>
<p>I will wrap up by emphasising a point about using functions. <strong>Good functions can be individually reasoned with</strong>, and used repeatedly across your work. This means you can write them once, use them many times, and only need to make changes to one place, rather than in many. Writing functions helps abstract away details, and helps clarify your code. They are an important building block for writing good code that has content that can be easily reasoned with, and extended.</p>
</section>
<section id="thanks" class="level1">
<h1>Thanks</h1>
<p>Thank you very much to the maintainers of <a href="https://cli.r-lib.org/index.html"><code>cli</code></a> (<a href="https://github.com/gaborcsardi">Gábor Csárdi</a>), and <a href="https://rlang.r-lib.org/"><code>rlang</code></a> (<a href="https://github.com/lionel-">Lionel Henry</a>), and the team behind these packages. These are hard problems! Thanks to <a href="https://adamgruer.rbind.io/">Adam Gruer</a> for asking a great question that made me dive deeper into error checking. Special thanks to <a href="https://masalmon.eu/">Maëlle Salmon</a> for providing very useful comments that improved this post greatly, and thank you in general being a kind source of knowledge.</p>
<p>Is there anything I missed? Other questions / problems to explore in this space? Leave me a comment below if you want to chat about any of this :).</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>Thank you to Maëlle Salmon for helping me articulate this point, with inspiration from <a href="https://pragprog.com/titles/tpp20/the-pragmatic-programmer-20th-anniversary-edition/">The Pragmatic Programmer</a>).↩︎</p></li>
</ol>
</section></div> ]]></description>
  <category>error</category>
  <category>functions</category>
  <category>rbloggers</category>
  <category>research software engineer</category>
  <category>rstats</category>
  <guid>https://www.njtierney.com/posts/2023-12-01-long-errors-smell/</guid>
  <pubDate>Wed, 06 Dec 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Get Good with R: Typing Skills and Shortcuts</title>
  <link>https://www.njtierney.com/posts/2023-11-23-get-good-type-fast/</link>
  <description><![CDATA[ 
<header class="site-header">
  <h1 class="site-title">
    <a href="../../">
      <img class="hvr-grow site-logo" src="https://www.njtierney.com/assets/njt-logo-small.png" alt="Nick logo">
    </a>
    <span class="hvr-bob site-title-credibly">Credibly</span>
    <span class="hvr-hang site-title-curious">Curious</span>
  </h1>
  <p class="site-subtitle">
    Nick Tierney's (mostly) rstats blog
  </p>
  
</header>




<figure class="figure">
<img src="https://www.njtierney.com/posts/2023-11-23-get-good-type-fast/img/full-send.jpg" alt="Full Send. A blank trail blaze with a fun message. Fuji X100V" class="figure-img">

</figure>
<p>Previously, I wrote a blog post, <a href="https://www.njtierney.com/post/2023/11/10/how-to-get-good-with-r/">“How to get good with R”</a>, where I touched on a bunch of ideas on how to improve your R skills, focussing on the coding aspect. It is by no means definitive, and I kind of wish I had named it “How to improve your R skills” or something less grandiose. But it was a catchy title. Anyway, I digress. I said I would write another post about the non coding side, but it started to get really big, so I’m breaking them into smaller blog posts, as I think this gives me a bit more mental space to write well on a smaller topic. I will be linking the posts below here as I write them.</p>
<section id="motivation" class="level2">
<h2 class="anchored" data-anchor-id="motivation">Motivation</h2>
<p>Here’s the jam - if you can type faster, then you operate closer to the speed of thought. It’s not just about working faster, as much as it is about being able to clearly express what is in your head. I think when you can clearly express what is in your head, then you put yourself in a good position to enter the wonderful <a href="https://en.wikipedia.org/wiki/Flow_(psychology)">flow state</a> of programming. Flow state, “in the zone”, is where you are completely absorbed, enjoying what you are doing, and things often feel easy and make sense. It’s a good thing. And when you are typing fast, and accurately, you aren’t making too many small stumbling mistakes that would take you out of the flow state. Similarly, when you can use keyboard shortcuts, you are getting more of what is in your head onto the screen fluently, which helps you stay in the flow state.</p>
</section>
<section id="typing-accurately-and-fast" class="level2">
<h2 class="anchored" data-anchor-id="typing-accurately-and-fast">Typing accurately and fast</h2>
<figure class="figure">
<img src="https://www.njtierney.com/posts/2023-11-23-get-good-type-fast/img/keyboard.jpg" alt="My (not entirely clean) Keyboard, Fuji X100V" class="figure-img">

</figure>
<p>Hadley Wickham <a href="https://twitter.com/hadleywickham/status/1169603647614967808?lang=en">tweeted about typing speed back in 2019</a>. My friend <a href="https://milesmcbain.xyz/">Miles</a> had written something about this, I think - although I can’t find it on his blog or twitter. But Miles noticed that an improvement in his typing speed helped him stay in the programming flow state. He was already a very talented programmer at this stage, so it’s basically like giving Usain Bolt a pair of roller skates and asking him to race someone downhill.</p>
<p>I don’t think being a fast typist is <strong>necessary</strong> to be a better programmer, but I think tools that help you work faster and with less resistance are good. I remember changing to a <a href="https://ergodox-ez.com/">new keyboard</a>, and I felt this friction where I couldn’t put what was in my head onto the screen. I felt like I was slow - like I was walking around with a bunch of ankle weights and a large unwieldy backpack. Like a lot of things in life, taking time to revisit the basics helps you with more advanced skills. I took time every day for a couple of months to work on my typing speed, and it resulted in more accurate, faster typing. Which resulted in faster coding. I ended up ditching the new keyboard, but I kept my typing skills.</p>
<p>There are a lot of options out there for programs to help with typing speed. It’s important to remember to focus on accuracy first. There’s not a lot of benefit to being able to type the wrong and intelligible words really quickly. I liked <a href="https://www.keybr.com/">keybr</a> a lot, and I’ve heard good things about <a href="https://monkeytype.com/">monkeytype</a>.</p>
<p>Also worth noting that I don’t think you need to get a new keyboard to be a faster at typing. I still think that my old mac wireless keyboard (pictured above) is my favourite. I’ve spent a lot of time and money trying to find a good keyboard. I’m not there yet. I think it is a better use of your time to practice typing, than to buy a new keyboard. But hey, you might find that isn’t true for you! Get the keyboard if you want it, I say.</p>
</section>
<section id="use-keyboard-shortcuts" class="level2">
<h2 class="anchored" data-anchor-id="use-keyboard-shortcuts">Use keyboard shortcuts</h2>
<figure class="figure">
<img src="https://www.njtierney.com/posts/2023-11-23-get-good-type-fast/img/keyboard-shortcuts.jpg" alt="My old laptop keyboard with some worn down shortcut keys. Fuji X100V" class="figure-img">

</figure>
<p>Learn some keyboard shortcuts, it saves not just keystrokes or your time, but it helps you operate a bit closer to the speed of thought. Here are some shorcuts I use that aren’t R related a lot:</p>
<ul>
<li><code>Cmd / Ctrl + C</code>: copy</li>
<li><code>Cmd / Ctrl + V</code>: paste</li>
<li><code>Cmd / Ctrl + X</code>: cut</li>
<li><code>Cmd / Ctrl + Z</code>: undo last action</li>
<li><code>Cmd / Ctrl + Shift + Z</code>: reverse the undo</li>
<li><code>Cmd / Ctrl + Tab</code>: change application</li>
<li><code>Cmd / Ctrl</code> + <kbd>~</kbd>: change window within an application</li>
<li><code>Cmd + Space</code>: open up “spotlight” in mac, allowing you to search for files</li>
<li><code>Ctrl + Space</code>: open up “Alfred”, which I have configured to look for RStudio project files (<a href="https://www.youtube.com/watch?v=boKFxBniUH0">see Hadley Wickham’s video on workflow</a>).</li>
<li><code>Cmd / Ctrl + Shift + 4</code>: open screenshot tool</li>
</ul>
<p>I use a screenshot tool, <a href="https://shottr.cc/">shottr</a>, for Mac that gives you better control of screenshots - opening up a window that lets you crop an image, get colour swatches, save the screenshot to a given directory. It’s really nice, and it’s free.</p>
<p>In a web browser:</p>
<ul>
<li><code>Cmd / Ctrl + Alt + Left / Right</code>: move one browser tab to the left or right</li>
<li><code>Cmd / Ctrl + L</code>: move cursor to browser</li>
<li><code>Cmd / Ctrl + T</code>: create a new tab</li>
<li><code>Cmd / Ctrl + W</code>: close current tab</li>
<li><code>Cmd / Ctrl + Shift + T</code>: open up last closed tab</li>
<li><code>Cmd / Ctrl + F</code>: Search for a word. I use this across all sorts of apps, PDFs, web browsing, and any code.</li>
</ul>
<p>(Some of) My favourite shortcuts I use in R:</p>
<ul>
<li><p><code>Cmd / Ctrl + Enter</code>: run line of code</p></li>
<li><p><code>Cmd / Ctrl + C</code>: comment/Uncomment current line</p></li>
<li><p><code>Cmd / Ctrl + Shift + K</code>: knit/render document</p></li>
<li><p><code>Cmd / Ctrl + Shift + A</code>: format highlighted code (style the code)</p></li>
<li><p><code>Cmd / Ctrl + D</code>: delete current line</p></li>
<li><p><code>Alt + Up / Down</code>: yank line up or down</p></li>
<li><p><code>Cmd / Ctrl</code> + <kbd>click</kbd> (on a function): take to function definition</p></li>
<li><p><code>Cmd / Ctrl + Alt + I</code>: new code chunk</p></li>
<li><p><code>Cmd / Ctrl + Shift + F</code>: find in files. Search a whole directory, or a specified directory, for files</p></li>
<li><p><code>Cmd / Ctrl + Alt + Up / Down</code>: copy the above line (or selected lines) down or up. Really useful when you want to copy/paste something. Basically copy/paste, but just that little bit quicker.</p></li>
<li><p><code>Ctrl</code> + <kbd>.</kbd>: go to file/function name. Really useful.</p></li>
<li><p><code>Cmd / Ctrl + Shift + Enter</code>: run all code in current code chunk or script</p></li>
<li><p><code>Ctrl + Alt + Up / Down</code>: multiple cursors (!) extend cursor up or down</p></li>
<li><p><code>Cmd / Ctrl + Left / Right</code>: move the cursor to the end or the beginning of the line</p></li>
<li><p><code>Alt + Left / Right</code>: move the cursor one word across (combine with <code>Shift</code> to select one/multiple words)</p></li>
</ul>
<p>It is a small but very useful benefit with being able to move the cursor across by one word or jumping to the start or end of a line. It means you don’t have to lean on the left or right arrow key to end up where you want - you speed up that process quite a bit!</p>
<p>You can see a quick menu display shortcuts in RStudio with: <code>Alt + Shift + K</code> (press <code>Esc</code> to remove the screen)</p>
<p>And you can see all shortcuts and set your own shortcuts in Rstudio by navigating to “Keyboard Shortcuts Help” (Tools &gt; “Keyboard Shortcuts Help”) (<a href="https://support.posit.co/hc/en-us/articles/206382178-Customizing-Keyboard-Shortcuts">Official notes on customising keyboard shortcuts in the RStudio IDE</a>).</p>
<p>Some packages add keyboard shortcuts as “add-ins” in RStudio, which you can then add as shortcuts using “keyboards shortcuts help”.</p>
<p>Some examples of these add in shortcuts are:</p>
<ul>
<li>Render reprex based on selection (I set mine to <code>Cmd / Ctrl + Shift + R</code>) (must have reprex package installed)</li>
<li>define function at cursor using <a href="https://github.com/milesmcbain/fnmate"><code>fnmate</code></a> (very much worth a look, this has accelerated my functional programming).</li>
</ul>
<p><a href="https://www.garrickadenbuie.com/">Garrick Aden-Buie</a> also has a nice R package that allows you to set other keyboard shortcuts, <a href="https://github.com/gadenbuie/shrtcts"><code>shrtcts</code></a></p>
<p>I really like using my keyboard shorcuts, they help me more fluidly move between tasks, and help me stay in that flow state, that zone.</p>
<section id="a-brief-note-about-vim-and-emacs-and-friends" class="level3">
<h3 class="anchored" data-anchor-id="a-brief-note-about-vim-and-emacs-and-friends">A brief note about vim and emacs and friends</h3>
<p>All these keyboard shortcuts are super useful. So much so that there are whole other ecosystems that are built on nice shortcuts. Both emacs and vim are pieces of software/philosophies that take this shortcut idea to another level. I personally don’t use them, but I know plenty of people who do use them, and really enjoy doing so.</p>
<p>A word of warning, if you use vim - know how get out of vim: <code>Esc</code> then <kbd>:</kbd> then <kbd>q</kbd>, then <code>Enter</code>. If you want to learn the basics of vim, <a href="https://www.openvim.com/">openvim</a> and <a href="https://vim-adventures.com/">vim-adventures</a> are great. You can set RStudio to use vim or emacs key bindings if you want (see Tools &gt; Global Options &gt; Code &gt; Editing Tab &gt; Keybindings), but I haven’t used this before, so I’m not sure what the experience is like.</p>
</section>
</section>
<section id="end" class="level2">
<h2 class="anchored" data-anchor-id="end">End</h2>
<p>I hope that these are helpful tips! Are there any keyboard shortcuts I missed? Ones that you particularly like? Other points on typing speed or ways to get faster?</p>


</section>

 ]]></description>
  <category>blag</category>
  <category>rbloggers</category>
  <category>rstats</category>
  <guid>https://www.njtierney.com/posts/2023-11-23-get-good-type-fast/</guid>
  <pubDate>Mon, 04 Dec 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>How to Get Good with R?</title>
  <link>https://www.njtierney.com/posts/2023-10-30-how-to-get-good-with-r/</link>
  <description><![CDATA[ 
<header class="site-header">
  <h1 class="site-title">
    <a href="../../">
      <img class="hvr-grow site-logo" src="https://www.njtierney.com/assets/njt-logo-small.png" alt="Nick logo">
    </a>
    <span class="hvr-bob site-title-credibly">Credibly</span>
    <span class="hvr-hang site-title-curious">Curious</span>
  </h1>
  <p class="site-subtitle">
    Nick Tierney's (mostly) rstats blog
  </p>
  
</header>




<div class="highlight">
<p><img src="https://www.njtierney.com/posts/2023-10-30-how-to-get-good-with-r/imgs/never-stop-sign.jpg" width="700px" style="display: block; margin: auto;"></p>
</div>
<p><em>A Stop Sign in Melbourne, Film, Pentax K1000, Nick Tierney</em></p>
<p>Someone recently asked me, “How do you get good with R?”. It’s a good question. I’m not sure I have a good answer. But I’ve been thinking about it, and I’ve got some ideas. Hopefully they are helpful for people, or can promote discussion on making better ideas. I think you can view “getting good” through two lenses: coding, and non coding. I’ll write about the coding aspects in this blog post, and the non coding aspects in a future one.</p>
<p>This post assumes that you’re somewhat familiar with R, you can open it, you do some analysis, etc. I should probably write a blog post first on “How to get started with R”. But writing introductory materials takes a bit more time, and I’d rather put out some kind of blog post than continue to add to the pile of blog post drafts that have been sitting there since 2017.</p>
<p>How to get good, from the coding side:</p>
<ul>
<li>Try to give things OK names</li>
<li>Consistent naming</li>
<li>Stick to a style guide</li>
<li>Clean up your code as you go (refactor)</li>
<li>Learn how to create a reproducible example (a reprex), and use it a lot</li>
<li>Write functions</li>
<li>Use the debugger</li>
</ul>
<p>How to get good, from the non coding side:</p>
<ul>
<li>Find a community of people who use R</li>
<li>Get better with the keyboard: Typing speed and keyboard shortcuts</li>
<li>Have a strong desire to improve</li>
<li>Learn how to, and practice getting unstuck</li>
<li>Read other peoples code</li>
<li>Read books and learning material</li>
<li>Practice reading the documentation</li>
<li>Ask yourself how much what you are doing now is relevant to the problem you were trying to solve. I get distracted often, this helps me redirect.</li>
<li>Offload ideas and tasks onto github issues (or another system)</li>
<li>Write about your work publicly - this forced me to clean up my code and keep a tidy ship</li>
</ul>
<section id="lets-delve-a-bit-deeper" class="level1">
<h1>Let’s delve a bit deeper</h1>
<p>Let’s give examples of all of these things. I’ve realised now as I’ve been writing this that I won’t have time to write the non-coding aspects, so that will be its own blog post. But I thought it might be useful to outline the points above.</p>
</section>
<section id="from-the-coding-side" class="level1">
<h1>From the coding side</h1>
<section id="try-to-give-things-ok-names" class="level2">
<h2 class="anchored" data-anchor-id="try-to-give-things-ok-names">Try to give things OK names</h2>
<p>There is a quote by Phil Karlton: “There are only two hard things in Computer Science: cache invalidation and naming thing”. We won’t talk about cache invalidation (Although <a href="https://yihui.org/en/2018/06/cache-invalidation/">Yihui has a good post about it if you are interested</a>), but naming things well…is hard. Giving things OK names is a bit easier. Getting in the habit of giving things an OK name will lead to you giving better and better names as you practice. Why should we are about this? Well, compare:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">weight_mean</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/mean.html">mean</a></span><span class="o">(</span><span class="nv">ChickWeight</span><span class="o">$</span><span class="nv">weight</span><span class="o">)</span></span>
<span><span class="nv">weight_sd</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/stats/sd.html">sd</a></span><span class="o">(</span><span class="nv">ChickWeight</span><span class="o">$</span><span class="nv">weight</span><span class="o">)</span></span></code></pre>
</div>
<p>to</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">x</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/mean.html">mean</a></span><span class="o">(</span><span class="nv">ChickWeight</span><span class="o">$</span><span class="nv">weight</span><span class="o">)</span></span>
<span><span class="nv">y</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/stats/sd.html">sd</a></span><span class="o">(</span><span class="nv">ChickWeight</span><span class="o">$</span><span class="nv">weight</span><span class="o">)</span></span></code></pre>
</div>
<p>If I see <code>weight_mean</code> and <code>weight_sd</code> later, I’ve got a clue what they are - the mean and the standard deviation of a thing called weight. I don’t know what <code>x</code> and <code>y</code> are when I see them. A small counter example to this is very small functions. But let’s not get into the weeds.</p>
</section>
<section id="consistent-naming" class="level2">
<h2 class="anchored" data-anchor-id="consistent-naming">Consistent naming</h2>
<p>Building on the previous point, I think it useful to pick a <em>way</em> to name something, and stick to it.</p>
<p>Compare:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">weight_mean</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/mean.html">mean</a></span><span class="o">(</span><span class="nv">ChickWeight</span><span class="o">$</span><span class="nv">weight</span><span class="o">)</span></span>
<span><span class="nv">sd_weight</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/stats/sd.html">sd</a></span><span class="o">(</span><span class="nv">ChickWeight</span><span class="o">$</span><span class="nv">weight</span><span class="o">)</span></span></code></pre>
</div>
<p>and</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">weight_mean</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/mean.html">mean</a></span><span class="o">(</span><span class="nv">ChickWeight</span><span class="o">$</span><span class="nv">weight</span><span class="o">)</span></span>
<span><span class="nv">weight_sd</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/stats/sd.html">sd</a></span><span class="o">(</span><span class="nv">ChickWeight</span><span class="o">$</span><span class="nv">weight</span><span class="o">)</span></span></code></pre>
</div>
<p>The first one changes the order of the naming, which is: <code>variable_operation</code> - the first word describes the variable we are measuring, weight, and the second tells us what operation we’ve done to it. It doesn’t matter about the order, necessarily, but the <em>consistency</em>.</p>
<p>Why? Because if it is consistent we can get benefits in things like tab complete - I can type <code>weight_</code> and hit <code>tab</code> and it tells me all the things related to <code>weight</code> that I’ve done. Similarly, it could also be useful to know all the things I’ve done <code>sd</code> to, <code>sd_</code> could tell me the things with <code>sd</code>. E.g.,</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">sd_height</span> <span class="o">&lt;-</span> <span class="nv">ChickWeight</span><span class="o">$</span><span class="nv">weight</span></span>
<span><span class="nv">sd_time</span> <span class="o">&lt;-</span> <span class="nv">ChickWeight</span><span class="o">$</span><span class="nv">Time</span></span></code></pre>
</div>
<p>It depends what you are doing - do you care more about finding things related to <code>sd</code>, or related to <code>height</code> or <code>weight</code>? My point is that I think it’s worthwhile to stick to a consistent approach. It means you can just remember the more important thing, whether that be things related to <code>weight</code>, or things related to <code>sd</code>.</p>
</section>
<section id="stick-to-a-style-guide" class="level2">
<h2 class="anchored" data-anchor-id="stick-to-a-style-guide">Stick to a style guide</h2>
<p>Style guides are a thing - they help define a set of rules to keep your code easy to read. To quote Hadley Wickham:</p>
<blockquote class="blockquote">
<p>Good coding style is like correct punctuation: you can manage without it, butitsuremakesthingseasiertoread.</p>
</blockquote>
<p>There is a comprehensive guide like the <a href="https://style.tidyverse.org/">Tidyverse Style Guide</a>. Or for a shorter guide, you can see the <a href="http://adv-r.had.co.nz/Style.html">style guide from “Advanced R”, 1st edition</a></p>
<p>I think it is worth your time to read through a style guide once. You’ll notice things that you didn’t before in your code and you’ll see things differently. It is similar to learning about <a href="https://xkcd.com/1015/">kerning</a>. Once you see it, you’ll notice it everywhere.</p>
<p>So, pick something like <code>snake_case</code> or <code>camelCase</code> or <code>CamelCase</code>, and stick to it. I prefer <code>snake_case</code> because I find it easier to read. But you can do whatever you want! Just be consistent.</p>
<p>I find it confusing to go through code that mixes it up or combines different approaches. It means you need to spend time remembering which way something was named. Here’s a “good” vs “bad”</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" 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;"># good</span></span>
<span id="cb1-2">sdWeight</span>
<span id="cb1-3">sdTime</span>
<span id="cb1-4">weightSd</span>
<span id="cb1-5">timeSd</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" 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;"># bad</span></span>
<span id="cb2-2">sd_Weight</span>
<span id="cb2-3">SD_weight</span>
<span id="cb2-4">Long_variable_Name</span></code></pre></div></div>
<p>If you want to have a quick way to help style your code, check out <a href="https://github.com/lorenzwalthert">Lorenz Walthert’s</a> <a href="https://github.com/r-lib/styler"><code>styler</code></a> package.</p>
</section>
<section id="clean-up-your-code-as-you-go-refactor" class="level2">
<h2 class="anchored" data-anchor-id="clean-up-your-code-as-you-go-refactor">Clean up your code as you go (refactor)</h2>
<p>Get into the habit of quickly going back over your code to tidy it up. A kitchen analogy is useful here I think. Professional kitchens clean up as they go. Keeping a tidy workspace helps keep your mind clear. And I rarely write my best code on the first pass. It gets better with iteration. So, iterate on your code briefly as you go. Clean up those random comments that don’t mean anything. Remove those bits of wilted lettuce, these are those commented out bits of code that you <em>might just come back to</em> - you probably won’t, and if they are really important, write a comment explaining why they might be relevant. Clean up the style. Check the names. Consider tidying up the implementation, refactoring it. You might not have time to do all of these things, or do them thoroughly, but doing some of them will help you write better code, and you’ll get better at doing these things the more you practice.</p>
<p>A word worth explaining - “refactor”. It refers to changing the code but keeping it’s behaviour the same. Kind of like giving a car a service, or replacing key parts in a vehicle that get worn out. For a great talk on a related topic, see <a href="https://www.youtube.com/watch?v=7oyiPBjLAWY">Jenny Bryan’s “Code Smells and Feels”</a></p>
</section>
<section id="learn-how-to-create-a-reproducible-example-a-reprex-and-use-it-a-lot" class="level2">
<h2 class="anchored" data-anchor-id="learn-how-to-create-a-reproducible-example-a-reprex-and-use-it-a-lot">Learn how to create a reproducible example (a reprex), and use it a lot</h2>
<p>When you run into a problem, or an error, if you can’t work out the answer after some tinkering about, it can be worthwhile spending some time to construct a small example of the code that breaks. This takes a bit of time, and could be its own little blog post. It takes practice. But in the process of reducing the problem down to its core components, I often can solve the problem myself. It’s kind of like that experience of when you talk to someone to try and describe a problem that you are working on, and in talking about it, you arrive at a solution.</p>
<p>There is a great R package that helps you create these reproducible examples, called <a href="https://reprex.tidyverse.org/"><code>reprex</code></a>, by <a href="https://jennybryan.org/">Jenny Bryan</a>. I’ve written about the reprex package <a href="https://www.njtierney.com/post/2017/01/11/magic-reprex/">here</a></p>
<p>For the purposes of illustration, let’s briefly tear down a small example using the somewhat large dataset of <code>diamonds</code></p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://tidyverse.tidyverse.org">tidyverse</a></span><span class="o">)</span></span>
<span><span class="c">#&gt; ── <span style="font-weight: bold;">Attaching core tidyverse packages</span> ────────────── tidyverse 2.0.0 ──</span></span>
<span><span class="c">#&gt; <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">dplyr    </span> 1.1.3     <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">readr    </span> 2.1.4</span></span>
<span><span class="c">#&gt; <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">forcats  </span> 1.0.0     <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">stringr  </span> 1.5.0</span></span>
<span><span class="c">#&gt; <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">ggplot2  </span> 3.4.4     <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">tibble   </span> 3.2.1</span></span>
<span><span class="c">#&gt; <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">lubridate</span> 1.9.2     <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">tidyr    </span> 1.3.0</span></span>
<span><span class="c">#&gt; <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">purrr    </span> 1.0.2     </span></span>
<span><span class="c">#&gt; ── <span style="font-weight: bold;">Conflicts</span> ──────────────────────────────── tidyverse_conflicts() ──</span></span>
<span><span class="c">#&gt; <span style="color: #BB0000;">✖</span> <span style="color: #0000BB;">dplyr</span>::<span style="color: #00BB00;">filter()</span> masks <span style="color: #0000BB;">stats</span>::filter()</span></span>
<span><span class="c">#&gt; <span style="color: #BB0000;">✖</span> <span style="color: #0000BB;">dplyr</span>::<span style="color: #00BB00;">lag()</span>    masks <span style="color: #0000BB;">stats</span>::lag()</span></span>
<span><span class="c">#&gt; <span style="color: #00BBBB;">ℹ</span> Use the conflicted package (<span style="color: #0000BB; font-style: italic;">&lt;http://conflicted.r-lib.org/&gt;</span>) to force all conflicts to become errors</span></span>
<span></span><span><span class="nv">diamonds</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 53,940 × 10</span></span></span>
<span><span class="c">#&gt;    carat cut       color clarity depth table price     x     y     z</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;ord&gt;</span>     <span style="color: #555555; font-style: italic;">&lt;ord&gt;</span> <span style="color: #555555; font-style: italic;">&lt;ord&gt;</span>   <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>  0.23 Ideal     E     SI2      61.5    55   326  3.95  3.98  2.43</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>  0.21 Premium   E     SI1      59.8    61   326  3.89  3.84  2.31</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>  0.23 Good      E     VS1      56.9    65   327  4.05  4.07  2.31</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>  0.29 Premium   I     VS2      62.4    58   334  4.2   4.23  2.63</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>  0.31 Good      J     SI2      63.3    58   335  4.34  4.35  2.75</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>  0.24 Very Good J     VVS2     62.8    57   336  3.94  3.96  2.48</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>  0.24 Very Good I     VVS1     62.3    57   336  3.95  3.98  2.47</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>  0.26 Very Good H     SI1      61.9    55   337  4.07  4.11  2.53</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>  0.22 Fair      E     VS2      65.1    61   337  3.87  3.78  2.49</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>  0.23 Very Good H     VS1      59.4    61   338  4     4.05  2.39</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># ℹ 53,930 more rows</span></span></span>
<span></span></code></pre>
</div>
<p>Let’s say we had a few steps involved in the data summary of diamonds data:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">diamonds</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span></span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>    price_per_carat <span class="o">=</span> <span class="nv">price</span> <span class="o">/</span> <span class="nv">carat</span></span>
<span>  <span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/group_by.html">group_by</a></span><span class="o">(</span></span>
<span>    <span class="nv">cut</span></span>
<span>    <span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/summarise.html">summarise</a></span><span class="o">(</span></span>
<span>    price_mean <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/mean.html">mean</a></span><span class="o">(</span><span class="nv">price_per_carat</span><span class="o">)</span>,</span>
<span>    price_sd <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/stats/sd.html">sd</a></span><span class="o">(</span><span class="nv">price_per_carat</span><span class="o">)</span>,</span>
<span>    mean_color <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/mean.html">mean</a></span><span class="o">(</span><span class="nv">color</span><span class="o">)</span></span>
<span>  <span class="o">)</span></span>
<span><span class="c">#&gt; Warning: There were 5 warnings in `summarise()`.</span></span>
<span><span class="c">#&gt; The first warning was:</span></span>
<span><span class="c">#&gt; <span style="color: #00BBBB;">ℹ</span> In argument: `mean_color = mean(color)`.</span></span>
<span><span class="c">#&gt; <span style="color: #00BBBB;">ℹ</span> In group 1: `cut = Fair`.</span></span>
<span><span class="c">#&gt; Caused by warning in `mean.default()`:</span></span>
<span><span class="c">#&gt; <span style="color: #BBBB00;">!</span> argument is not numeric or logical: returning NA</span></span>
<span><span class="c">#&gt; <span style="color: #00BBBB;">ℹ</span> Run `dplyr::last_dplyr_warnings()` to see the 4 remaining warnings.</span></span>
<span></span><span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 5 × 4</span></span></span>
<span><span class="c">#&gt;   cut       price_mean price_sd mean_color</span></span>
<span><span class="c">#&gt;   <span style="color: #555555; font-style: italic;">&lt;ord&gt;</span>          <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>      <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">1</span> Fair           <span style="text-decoration: underline;">3</span>767.    <span style="text-decoration: underline;">1</span>540.         <span style="color: #BB0000;">NA</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">2</span> Good           <span style="text-decoration: underline;">3</span>860.    <span style="text-decoration: underline;">1</span>830.         <span style="color: #BB0000;">NA</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">3</span> Very Good      <span style="text-decoration: underline;">4</span>014.    <span style="text-decoration: underline;">2</span>037.         <span style="color: #BB0000;">NA</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">4</span> Premium        <span style="text-decoration: underline;">4</span>223.    <span style="text-decoration: underline;">2</span>035.         <span style="color: #BB0000;">NA</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">5</span> Ideal          <span style="text-decoration: underline;">3</span>920.    <span style="text-decoration: underline;">2</span>043.         <span style="color: #BB0000;">NA</span></span></span>
<span></span></code></pre>
</div>
<p>We get a clue that the error is in the line <code>mean_color</code>, so let’s just try and do that line:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">diamonds</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span></span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>    mean_color <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/mean.html">mean</a></span><span class="o">(</span><span class="nv">color</span><span class="o">)</span></span>
<span>  <span class="o">)</span></span>
<span><span class="c">#&gt; Warning: There was 1 warning in `mutate()`.</span></span>
<span><span class="c">#&gt; <span style="color: #00BBBB;">ℹ</span> In argument: `mean_color = mean(color)`.</span></span>
<span><span class="c">#&gt; Caused by warning in `mean.default()`:</span></span>
<span><span class="c">#&gt; <span style="color: #BBBB00;">!</span> argument is not numeric or logical: returning NA</span></span>
<span></span><span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 53,940 × 11</span></span></span>
<span><span class="c">#&gt;    carat cut       color clarity depth table price     x     y     z mean_color</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;ord&gt;</span>     <span style="color: #555555; font-style: italic;">&lt;ord&gt;</span> <span style="color: #555555; font-style: italic;">&lt;ord&gt;</span>   <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>      <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>  0.23 Ideal     E     SI2      61.5    55   326  3.95  3.98  2.43         <span style="color: #BB0000;">NA</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>  0.21 Premium   E     SI1      59.8    61   326  3.89  3.84  2.31         <span style="color: #BB0000;">NA</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>  0.23 Good      E     VS1      56.9    65   327  4.05  4.07  2.31         <span style="color: #BB0000;">NA</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>  0.29 Premium   I     VS2      62.4    58   334  4.2   4.23  2.63         <span style="color: #BB0000;">NA</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>  0.31 Good      J     SI2      63.3    58   335  4.34  4.35  2.75         <span style="color: #BB0000;">NA</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>  0.24 Very Good J     VVS2     62.8    57   336  3.94  3.96  2.48         <span style="color: #BB0000;">NA</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>  0.24 Very Good I     VVS1     62.3    57   336  3.95  3.98  2.47         <span style="color: #BB0000;">NA</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>  0.26 Very Good H     SI1      61.9    55   337  4.07  4.11  2.53         <span style="color: #BB0000;">NA</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>  0.22 Fair      E     VS2      65.1    61   337  3.87  3.78  2.49         <span style="color: #BB0000;">NA</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>  0.23 Very Good H     VS1      59.4    61   338  4     4.05  2.39         <span style="color: #BB0000;">NA</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># ℹ 53,930 more rows</span></span></span>
<span></span></code></pre>
</div>
<p>We still get that error, so what if we just do</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://rdrr.io/r/base/mean.html">mean</a></span><span class="o">(</span><span class="nv">diamonds</span><span class="o">$</span><span class="nv">color</span><span class="o">)</span></span>
<span><span class="c">#&gt; Warning in mean.default(diamonds$color): argument is not numeric or logical: returning NA</span></span>
<span></span><span><span class="c">#&gt; [1] NA</span></span>
<span></span></code></pre>
</div>
<p>OK same error. What is in color?</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://rdrr.io/r/utils/head.html">head</a></span><span class="o">(</span><span class="nv">diamonds</span><span class="o">$</span><span class="nv">color</span><span class="o">)</span></span>
<span><span class="c">#&gt; [1] E E E I J J</span></span>
<span><span class="c">#&gt; Levels: D &lt; E &lt; F &lt; G &lt; H &lt; I &lt; J</span></span>
<span></span></code></pre>
</div>
<p>Does it really make sense to take the mean of some letters? Ah, of course not!</p>
</section>
<section id="use-other-r-packages" class="level2">
<h2 class="anchored" data-anchor-id="use-other-r-packages">Use other R packages</h2>
<p>You don’t need to write everything yourself from scratch. There are thousands of R packages that people have written to solve problems. Not all of them will suit, but if you find yourself trying to solve a problem, or write a statistical model from scratch, it it worth your time to search google to see if anyone has tried to solve this problem.</p>
<p>At worst, you’ll see no one has thought about this - this is an opportunity for you to do something cool! Or you might see ways people have tried to solve this, which can help you get started, and you’ll learn the other words people use to describe the problem you are facing, which can help you search this problem better in the future. At best you’ll find an exact answer.</p>
</section>
<section id="write-functions" class="level2">
<h2 class="anchored" data-anchor-id="write-functions">Write functions</h2>
<p>I don’t think I can overstate this, but learning how to write functions changed how I think about code and how I think about solving problems. I think it is a skill that takes some time to develop, but the payoff is enormous. A function is an abstraction of a problem. Kind of like a shortcut. Save yourself writing many many lines of code and replace them with a function. But that’s an oversimplification.</p>
<p>Here’s a short primer on why functions are good, adapted from the <a href="https://r4ds.had.co.nz/functions.html#functions">functions chapter of R4DS</a>, which I recommend you read.</p>
<p>What does the following code do?</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">dat</span> <span class="o">&lt;-</span> <span class="nf">tibble</span><span class="nf">::</span><span class="nf"><a href="https://tibble.tidyverse.org/reference/tibble.html">tibble</a></span><span class="o">(</span></span>
<span>  weight <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/stats/Normal.html">rnorm</a></span><span class="o">(</span><span class="m">10</span>, mean <span class="o">=</span> <span class="m">80</span>, sd <span class="o">=</span> <span class="m">6</span><span class="o">)</span>,</span>
<span>  height <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/stats/Normal.html">rnorm</a></span><span class="o">(</span><span class="m">10</span>, mean <span class="o">=</span> <span class="m">165</span>, sd <span class="o">=</span> <span class="m">10</span><span class="o">)</span>,</span>
<span><span class="o">)</span></span>
<span></span>
<span><span class="nv">dat</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 10 × 2</span></span></span>
<span><span class="c">#&gt;    weight height</span></span>
<span><span class="c">#&gt;     <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>   78.0   167.</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>   76.0   152.</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>   81.2   173.</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>   71.9   156.</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>   88.1   160.</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>   80.2   180.</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>   67.1   168.</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>   82.7   180.</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>   81.7   160.</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>   81.6   157.</span></span>
<span></span><span></span>
<span><span class="nv">dat</span><span class="o">$</span><span class="nv">weight_0</span> <span class="o">&lt;-</span> <span class="o">(</span><span class="nv">dat</span><span class="o">$</span><span class="nv">weight</span> <span class="o">-</span> <span class="nf"><a href="https://rdrr.io/r/base/mean.html">mean</a></span><span class="o">(</span><span class="nv">dat</span><span class="o">$</span><span class="nv">weight</span>, na.rm <span class="o">=</span> <span class="kc">TRUE</span><span class="o">)</span><span class="o">)</span> <span class="o">/</span> <span class="nf"><a href="https://rdrr.io/r/stats/sd.html">sd</a></span><span class="o">(</span><span class="nv">dat</span><span class="o">$</span><span class="nv">weight</span>, na.rm <span class="o">=</span> <span class="kc">TRUE</span><span class="o">)</span></span>
<span></span>
<span><span class="nv">dat</span><span class="o">$</span><span class="nv">height_0</span> <span class="o">&lt;-</span> <span class="o">(</span><span class="nv">dat</span><span class="o">$</span><span class="nv">height</span> <span class="o">-</span> <span class="nf"><a href="https://rdrr.io/r/base/mean.html">mean</a></span><span class="o">(</span><span class="nv">dat</span><span class="o">$</span><span class="nv">height</span>, na.rm <span class="o">=</span> <span class="kc">TRUE</span><span class="o">)</span><span class="o">)</span> <span class="o">/</span> <span class="nf"><a href="https://rdrr.io/r/stats/sd.html">sd</a></span><span class="o">(</span><span class="nv">dat</span><span class="o">$</span><span class="nv">weight</span>, na.rm <span class="o">=</span> <span class="kc">TRUE</span><span class="o">)</span></span></code></pre>
</div>
<p>This is a kind of transformation called mean centering and scaling. It can be useful in some statistical models to have your data have a mean of 0 and a standard deviation of 1.</p>
<p>But read through that code it can be hard to understand that is what is happening, and it also leads to potential errors - you have to repeat <code>dat$weight</code> or <code>dat$height</code> many times. And if you copy and paste this code then you might end up with an error. Which there is. for <code>height_0</code>, I divide by the standard deviation of weight, not height.</p>
<p>A function helps clarify this by <em>abstracting away</em> the need to write the variable in each time. We can break this into two steps:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">mean_center</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">variable</span><span class="o">)</span><span class="o">{</span></span>
<span>  <span class="nv">variable</span> <span class="o">-</span> <span class="nf"><a href="https://rdrr.io/r/base/mean.html">mean</a></span><span class="o">(</span><span class="nv">variable</span>, na.rm <span class="o">=</span> <span class="kc">TRUE</span><span class="o">)</span></span>
<span><span class="o">}</span></span>
<span></span>
<span><span class="nv">scale_sd</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">variable</span><span class="o">)</span><span class="o">{</span></span>
<span>  <span class="nv">variable</span> <span class="o">/</span> <span class="nf"><a href="https://rdrr.io/r/stats/sd.html">sd</a></span><span class="o">(</span><span class="nv">variable</span>, na.rm <span class="o">=</span> <span class="kc">TRUE</span><span class="o">)</span></span>
<span><span class="o">}</span></span></code></pre>
</div>
<p>Now we can express this as follows:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">dat</span><span class="o">$</span><span class="nv">height</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf">mean_center</span><span class="o">(</span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf">scale_sd</span><span class="o">(</span><span class="o">)</span></span>
<span><span class="c">#&gt;  [1]  0.1832022 -1.3362374  0.7525296 -0.9848021 -0.4937227  1.4924404</span></span>
<span><span class="c">#&gt;  [7]  0.3021602  1.4477151 -0.5125610 -0.8507242</span></span>
<span></span></code></pre>
</div>
<p>or, we can write a function that does both of these steps:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">center_scale</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">variable</span><span class="o">)</span><span class="o">{</span></span>
<span>  <span class="nv">centered</span> <span class="o">&lt;-</span> <span class="nf">mean_center</span><span class="o">(</span><span class="nv">variable</span><span class="o">)</span></span>
<span>  <span class="nv">centered_scaled</span> <span class="o">&lt;-</span> <span class="nf">scale_sd</span><span class="o">(</span><span class="nv">centered</span><span class="o">)</span></span>
<span>  <span class="nv">centered_scaled</span></span>
<span><span class="o">}</span></span></code></pre>
</div>
<p>What is nice about this is that each of the functions <em>describes what it does</em> in its name. So when we look at the code for <code>center_scale</code>, we can see that it does a thing called <code>mean_center</code> first, then <code>scale_sd</code> next. Another useful principle to follow with writing functions is to generally try to aim to get them to do one thing, and to return one thing. There are many exceptions to this rule, but it’s a useful practice to stick to.</p>
<p>So compare:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span></span>
<span><span class="nv">dat</span><span class="o">$</span><span class="nv">weight_0</span> <span class="o">&lt;-</span> <span class="o">(</span><span class="nv">dat</span><span class="o">$</span><span class="nv">weight</span> <span class="o">-</span> <span class="nf"><a href="https://rdrr.io/r/base/mean.html">mean</a></span><span class="o">(</span><span class="nv">dat</span><span class="o">$</span><span class="nv">weight</span>, na.rm <span class="o">=</span> <span class="kc">TRUE</span><span class="o">)</span><span class="o">)</span> <span class="o">/</span> <span class="nf"><a href="https://rdrr.io/r/stats/sd.html">sd</a></span><span class="o">(</span><span class="nv">dat</span><span class="o">$</span><span class="nv">weight</span>, na.rm <span class="o">=</span> <span class="kc">TRUE</span><span class="o">)</span></span>
<span></span>
<span><span class="nv">dat</span><span class="o">$</span><span class="nv">height_0</span> <span class="o">&lt;-</span> <span class="o">(</span><span class="nv">dat</span><span class="o">$</span><span class="nv">height</span> <span class="o">-</span> <span class="nf"><a href="https://rdrr.io/r/base/mean.html">mean</a></span><span class="o">(</span><span class="nv">dat</span><span class="o">$</span><span class="nv">height</span>, na.rm <span class="o">=</span> <span class="kc">TRUE</span><span class="o">)</span><span class="o">)</span> <span class="o">/</span> <span class="nf"><a href="https://rdrr.io/r/stats/sd.html">sd</a></span><span class="o">(</span><span class="nv">dat</span><span class="o">$</span><span class="nv">weight</span>, na.rm <span class="o">=</span> <span class="kc">TRUE</span><span class="o">)</span></span>
<span></span>
<span><span class="nv">dat</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 10 × 4</span></span></span>
<span><span class="c">#&gt;    weight height weight_0 height_0</span></span>
<span><span class="c">#&gt;     <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>   78.0   167.   -<span style="color: #BB0000;">0.138</span>    0.308</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>   76.0   152.   -<span style="color: #BB0000;">0.476</span>   -<span style="color: #BB0000;">2.25</span> </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>   81.2   173.    0.394    1.27 </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>   71.9   156.   -<span style="color: #BB0000;">1.18</span>    -<span style="color: #BB0000;">1.66</span> </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>   88.1   160.    1.56    -<span style="color: #BB0000;">0.831</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>   80.2   180.    0.224    2.51 </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>   67.1   168.   -<span style="color: #BB0000;">1.97</span>     0.508</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>   82.7   180.    0.644    2.44 </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>   81.7   160.    0.482   -<span style="color: #BB0000;">0.862</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>   81.6   157.    0.456   -<span style="color: #BB0000;">1.43</span></span></span>
<span></span></code></pre>
</div>
<p>to</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span></span>
<span><span class="nv">dat</span><span class="o">$</span><span class="nv">weight_0</span> <span class="o">&lt;-</span> <span class="nf">center_scale</span><span class="o">(</span><span class="nv">dat</span><span class="o">$</span><span class="nv">weight</span><span class="o">)</span></span>
<span></span>
<span><span class="nv">dat</span><span class="o">$</span><span class="nv">height_0</span> <span class="o">&lt;-</span> <span class="nf">center_scale</span><span class="o">(</span><span class="nv">dat</span><span class="o">$</span><span class="nv">height</span><span class="o">)</span></span>
<span></span>
<span><span class="nv">dat</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 10 × 4</span></span></span>
<span><span class="c">#&gt;    weight height weight_0 height_0</span></span>
<span><span class="c">#&gt;     <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>   78.0   167.   -<span style="color: #BB0000;">0.138</span>    0.183</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>   76.0   152.   -<span style="color: #BB0000;">0.476</span>   -<span style="color: #BB0000;">1.34</span> </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>   81.2   173.    0.394    0.753</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>   71.9   156.   -<span style="color: #BB0000;">1.18</span>    -<span style="color: #BB0000;">0.985</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>   88.1   160.    1.56    -<span style="color: #BB0000;">0.494</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>   80.2   180.    0.224    1.49 </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>   67.1   168.   -<span style="color: #BB0000;">1.97</span>     0.302</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>   82.7   180.    0.644    1.45 </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>   81.7   160.    0.482   -<span style="color: #BB0000;">0.513</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>   81.6   157.    0.456   -<span style="color: #BB0000;">0.851</span></span></span>
<span></span></code></pre>
</div>
<p>It is worth noting that there is a function called <code>scale</code> in base R that does this, however it returns a matrix, so you’ll need to wrap it in <code>as.numeric</code></p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">dat</span><span class="o">$</span><span class="nv">weight_0</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/numeric.html">as.numeric</a></span><span class="o">(</span><span class="nf"><a href="https://rdrr.io/r/base/scale.html">scale</a></span><span class="o">(</span><span class="nv">dat</span><span class="o">$</span><span class="nv">weight</span><span class="o">)</span><span class="o">)</span></span>
<span><span class="nv">dat</span><span class="o">$</span><span class="nv">height_0</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/numeric.html">as.numeric</a></span><span class="o">(</span><span class="nf"><a href="https://rdrr.io/r/base/scale.html">scale</a></span><span class="o">(</span><span class="nv">dat</span><span class="o">$</span><span class="nv">height</span><span class="o">)</span><span class="o">)</span></span>
<span><span class="nv">dat</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 10 × 4</span></span></span>
<span><span class="c">#&gt;    weight height weight_0 height_0</span></span>
<span><span class="c">#&gt;     <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>   78.0   167.   -<span style="color: #BB0000;">0.138</span>    0.183</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>   76.0   152.   -<span style="color: #BB0000;">0.476</span>   -<span style="color: #BB0000;">1.34</span> </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>   81.2   173.    0.394    0.753</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>   71.9   156.   -<span style="color: #BB0000;">1.18</span>    -<span style="color: #BB0000;">0.985</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>   88.1   160.    1.56    -<span style="color: #BB0000;">0.494</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>   80.2   180.    0.224    1.49 </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>   67.1   168.   -<span style="color: #BB0000;">1.97</span>     0.302</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>   82.7   180.    0.644    1.45 </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>   81.7   160.    0.482   -<span style="color: #BB0000;">0.513</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>   81.6   157.    0.456   -<span style="color: #BB0000;">0.851</span></span></span>
<span></span></code></pre>
</div>
<p>Which is why it is worthwhile looking to see if a solution to a problem exists :)</p>
<p>To summarise writing functions:</p>
<ol type="1">
<li>Functions help us reason with our code by abstracting away details we don’t need to care about</li>
<li>Give Functions good names, they should describe what they do</li>
<li>Functions should do one task</li>
<li>Functions should return one thing</li>
</ol>
</section>
<section id="learn-how-to-use-debugging-tools" class="level2">
<h2 class="anchored" data-anchor-id="learn-how-to-use-debugging-tools">Learn how to use debugging tools</h2>
<p>R is interactive, you can run some code and see the output immediately. It’s a really nice way to code for data analysis. It means that when you encounter a bug or an error, you can poke around and see what the error is. But if you write a function and want to see how it behaves or what goes on inside, you’ll need to use a special tool called a debugger.</p>
<p>If you’ve found yourself copying the internals of a function over to another script and hard coding the arguments at the top of the script and running the code line by line, then this is especially for you. I say this as someone who did that for years. Ahem.</p>
<p>Three debugging tools to know about:</p>
<ol type="1">
<li><a href="https://rdrr.io/r/base/browser.html"><code>browser()</code></a></li>
<li><a href="https://rdrr.io/r/base/debug.html"><code>debug()</code></a> and <a href="https://rdrr.io/r/base/debug.html"><code>undebug()</code></a></li>
<li><a href="https://rdrr.io/r/base/debug.html"><code>debugonce()</code></a></li>
</ol>
<p><a href="https://rdrr.io/r/base/browser.html"><code>browser()</code></a> gets placed inside a function, and then when you run the function, you land at that point in the code. For example:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">mean_center</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">variable</span><span class="o">)</span><span class="o">{</span></span>
<span>  <span class="nf"><a href="https://rdrr.io/r/base/browser.html">browser</a></span><span class="o">(</span><span class="o">)</span></span>
<span>  <span class="nv">variable</span> <span class="o">-</span> <span class="nf"><a href="https://rdrr.io/r/base/mean.html">mean</a></span><span class="o">(</span><span class="nv">variable</span>, na.rm <span class="o">=</span> <span class="kc">TRUE</span><span class="o">)</span></span>
<span><span class="o">}</span></span></code></pre>
</div>
<p>If you run this function, and then try and use it later, you will be landed at where the <a href="https://rdrr.io/r/base/browser.html"><code>browser()</code></a> line is. Try running the code above and then doing <code>mean_center(1:10)</code> afterwards. An important thing to remember with <a href="https://rdrr.io/r/base/browser.html"><code>browser()</code></a> is that you need to remove <a href="https://rdrr.io/r/base/browser.html"><code>browser()</code></a> after the fact.</p>
<p><a href="https://rdrr.io/r/base/debug.html"><code>debug()</code></a> and <a href="https://rdrr.io/r/base/debug.html"><code>undebug()</code></a> are like <a href="https://rdrr.io/r/base/browser.html"><code>browser()</code></a>, but you run them on a function and that turns on debugging mode. Just like putting <a href="https://rdrr.io/r/base/browser.html"><code>browser()</code></a> at the top line of a function.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" 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;">debug</span>(mean_center)</span>
<span id="cb3-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mean_center</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;">10</span>)</span>
<span id="cb3-3"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## enter debug mode here, tinker around with the outputs</span></span>
<span id="cb3-4"><span class="do" style="color: #5E5E5E;
background-color: null;
font-style: italic;">## then turn off the debugger</span></span>
<span id="cb3-5"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">undebug</span>(mean_center)</span></code></pre></div></div>
<p><a href="https://rdrr.io/r/base/debug.html"><code>debugonce()</code></a> does the <a href="https://rdrr.io/r/base/debug.html"><code>debug()</code></a> step, but just one time. It’s handy because it means you don’t need to run <a href="https://rdrr.io/r/base/debug.html"><code>undebug()</code></a> - sometimes I’ve forgotten I needed to do <a href="https://rdrr.io/r/base/debug.html"><code>undebug()</code></a> and i’ve felt like a madness has descended upon me.</p>
<p>So what to remember about this? If you want to see where a function is erroring, then you probably want to use <a href="https://rdrr.io/r/base/debug.html"><code>debugonce()</code></a> on it.</p>
</section>
</section>
<section id="not-the-end" class="level1">
<h1>(Not) The End</h1>
<p>There’s more to this. I don’t have all the answers. I’m a decent R programmer. But I’m still learning all the time, and I make mistakes a lot. I’m not perfect, far from it! But maybe these things can help you on your journey in improving in R programming.</p>
<p>I didn’t go into as much detail as I would have liked - there are a lot of topics here, what did I miss? What do you think are the ways to get good with R? Write a comment below :)</p>


</section>

 ]]></description>
  <category>rstats</category>
  <guid>https://www.njtierney.com/posts/2023-10-30-how-to-get-good-with-r/</guid>
  <pubDate>Fri, 10 Nov 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Continuing to Improve R’s Ability to Visualise and Explore Missing Values: Milestone 1</title>
  <link>https://www.njtierney.com/posts/2023-04-24-improving-missing-data-m1/</link>
  <description><![CDATA[ 
<header class="site-header">
  <h1 class="site-title">
    <a href="../../">
      <img class="hvr-grow site-logo" src="https://www.njtierney.com/assets/njt-logo-small.png" alt="Nick logo">
    </a>
    <span class="hvr-bob site-title-credibly">Credibly</span>
    <span class="hvr-hang site-title-curious">Curious</span>
  </h1>
  <p class="site-subtitle">
    Nick Tierney's (mostly) rstats blog
  </p>
  
</header>




<p>I am very pleased to say that I have received funding from the R consortium for improving R’s capacity to explore and handle missing values! More accurately, this funding was initially awarded in 2022, but this has been bubbling along now and is now picking up steam, so I wanted to give an update. In this blog post I will discuss the first milestone for this project, and outline the plan for the next one.</p>
<p>Here is an excerpt from the first milestone:</p>
<blockquote class="blockquote">
<p>Part one: Evaluating additional missing data visualisations We will explore additional visualisations that have been implemented for exploring missing data, which are not yet implemented in the R packages {visdat} or {naniar}. This will include, for example, looking at other software languages, such as {missingno} in Python: <a href="https://github.com/ResidentMario/missingno" class="uri">https://github.com/ResidentMario/missingno</a>. In addition to this, we will review the existing requests and ideas that are currently listed in the {naniar} and {visdat} repositories - there are many ideas here, and part of this initial work will be identifying the low hanging fruit for easy implementations. Throughout all of these parts, we will be engaging with the community, and other key contributors to these projects.</p>
</blockquote>
<p>I’d like to now outline how I’ve addressed milestone one, and what the plans are from here!</p>
<section id="milestone-one-outline-feature-set-to-implement-in-the-first-round-m1" class="level2">
<h2 class="anchored" data-anchor-id="milestone-one-outline-feature-set-to-implement-in-the-first-round-m1">Milestone one: Outline feature set to implement in the first round (M1)</h2>
<section id="find-a-suitable-developer-for-this-project" class="level3">
<h3 class="anchored" data-anchor-id="find-a-suitable-developer-for-this-project">Find a suitable developer for this project</h3>
<p>Due to my current time constraints and capacity for supervision, it was simplest for myself to be the developer for this project.</p>
</section>
<section id="identify-key-areas-of-maintenance-required-for-software" class="level3">
<h3 class="anchored" data-anchor-id="identify-key-areas-of-maintenance-required-for-software">Identify key areas of maintenance required for software</h3>
<p>Some of key areas of maintenance were outlined and addressed in releases that we have submitted to CRAN:</p>
<ul>
<li>In February 2023 for visdat version o.6.0, which was discussed in a blog post <a href="https://www.njtierney.com/post/2023/02/02/visdat-060/">here</a>,</li>
<li>In February 2023, for naniar, version 1.0.0, which was discussed <a href="https://www.njtierney.com/post/2023/02/07/naniar-version-1/">here</a></li>
</ul>
<p>In the next release, we will be implementing other maintenance areas alongside the new features for naniar and visdat.</p>
</section>
<section id="identify-feature-set-for-round-one" class="level3">
<h3 class="anchored" data-anchor-id="identify-feature-set-for-round-one">Identify feature set for round one</h3>
<p>There are always more features to add, and I wanted to be conscious of scope creep stopping a version of software from getting released. So I have implemented two stages of releases: the first a maintenance release, the second a “feature release”, in which I have also added “priority” labels, in which I have labelled the features that have the greatest impact/ease of implementation as priority 1 through to priority 3.</p>
<section id="for-naniar" class="level4">
<h4 class="anchored" data-anchor-id="for-naniar">For {naniar}</h4>
<p>This has been broken up into two parts, there is a maintenance set, and a feature set. These are outlined in the milestones for <a href="https://github.com/njtierney/naniar/milestone/6">version 1.1.0</a>, and <a href="https://github.com/njtierney/naniar/milestone/7">version 1.2.0</a>.</p>
<p>Some of these maintenance components include:</p>
<ul>
<li>Implementing shapes in <code>geom_miss_point()</code> (<a href="https://github.com/njtierney/naniar/issues/290">#290</a>)</li>
<li>Allowing <code>impute_below()</code> to work for dates (<a href="https://github.com/njtierney/naniar/issues/158">#158</a>)</li>
<li>Using the <code>cli</code> package for warnings and error messages (<a href="https://github.com/njtierney/naniar/issues/326">#326</a>)</li>
<li>deprecating functions <code>shadow_shift()</code> (<a href="https://github.com/njtierney/naniar/issues/193">#193</a>) and <code>miss_var_cumsum()</code> and <code>miss_case_cumsum()</code> (<a href="https://github.com/njtierney/naniar/issues/257">#257</a>)</li>
</ul>
<p>And some of the features include:</p>
<ul>
<li>More imputation helpers (imputing zero, median, mode, etc) (<a href="https://github.com/njtierney/naniar/issues/261">#261</a> and <a href="https://github.com/njtierney/naniar/issues/213">#213</a>)</li>
<li>Helpers for dropping columns with set amounts of missingness (<a href="https://github.com/njtierney/naniar/issues/317">#317</a>)</li>
<li>Providing a nice print method for a summary of missing data (<a href="https://github.com/njtierney/naniar/issues/317">#317</a>)</li>
<li>More geoms for naniar, such as <code>geom_miss_rug()</code> (<a href="https://github.com/njtierney/naniar/issues/225">#225</a>)</li>
<li>Improving support for <code>across</code> in the package functions (<a href="https://github.com/njtierney/naniar/issues/262">#262</a>)</li>
</ul>
<p>Again, for a full list of these, see the milestones for <a href="https://github.com/njtierney/naniar/milestone/6">version 1.1.0</a>, and <a href="https://github.com/njtierney/naniar/milestone/7">version 1.2.0</a>. The plan is to complete both of these sets and then submit them to CRAN.</p>
</section>
<section id="for-visdat" class="level4">
<h4 class="anchored" data-anchor-id="for-visdat">For {visdat}</h4>
<p>Similarly, for visdat, there are some further maintenance issues and then a feature set of issues, which you can see in milestones <a href="https://github.com/ropensci/visdat/milestone/3">version 0.7.0</a> and <a href="https://github.com/ropensci/visdat/milestone/5">version 0.8.0</a></p>
<p>Some of the maintenance issues include:</p>
<ul>
<li>Colour scale is incorrect when all data is missing (<a href="https://github.com/ropensci/visdat/issues/98">#98</a>)</li>
<li>Exposing data and summaries for plot methods (<a href="https://github.com/ropensci/visdat/issues/83">#83</a>)</li>
</ul>
<p>Some of the feature issues include:</p>
<ul>
<li>Implementing <code>vis_fct</code> for visualising factors (<a href="https://github.com/ropensci/visdat/issues/91">#91</a>)</li>
<li>Implement facetting for vis_value(), vis_binary(), vis_compare(), vis_expect(), and vis_guess(). (<a href="https://github.com/ropensci/visdat/issues/159">#159</a>)</li>
</ul>
</section>
</section>
</section>
<section id="summary" class="level2">
<h2 class="anchored" data-anchor-id="summary">Summary</h2>
<p>Thanks to the R Consortium for providing support for this project, I am very excited to be sharing these updates with the R community, and to be making new improvements to how we think about missing data in R.</p>
</section>
<section id="your-turn" class="level2">
<h2 class="anchored" data-anchor-id="your-turn">Your Turn</h2>
<p>Are there things I’ve missed? Other features you’d like to see implemented? Please do drop a comment in this blog post, or <a href="https://github.com/njtierney/naniar/issues/new">write an issue in naniar</a>, or <a href="https://github.com/ropensci/visdat/issues/new">write an issue in visdat</a>.</p>


</section>

 ]]></description>
  <category>missing data</category>
  <category>data visualisation</category>
  <category>ggplot2</category>
  <category>rstats</category>
  <guid>https://www.njtierney.com/posts/2023-04-24-improving-missing-data-m1/</guid>
  <pubDate>Mon, 24 Apr 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>naniar Version 1.0.0</title>
  <link>https://www.njtierney.com/posts/2023-02-02-naniar-version-0-6-0/</link>
  <description><![CDATA[ 
<header class="site-header">
  <h1 class="site-title">
    <a href="../../">
      <img class="hvr-grow site-logo" src="https://www.njtierney.com/assets/njt-logo-small.png" alt="Nick logo">
    </a>
    <span class="hvr-bob site-title-credibly">Credibly</span>
    <span class="hvr-hang site-title-curious">Curious</span>
  </h1>
  <p class="site-subtitle">
    Nick Tierney's (mostly) rstats blog
  </p>
  
</header>




<section id="naniar-1.0.0" class="level1">
<h1>naniar 1.0.0</h1>
<p>I’m very pleased to announce that naniar version 1.0.0 is now on CRAN!</p>
<p>Version 1.0.0 of naniar is to signify that this release is associated with the publication of the associated JSS paper <a href="doi:10.18637/jss.v105.i07" class="uri">doi:10.18637/jss.v105.i07</a> (!!!). This paper has been the labour of a lot of effort between myself and <a href="http://www.dicook.org/">Di Cook</a>, and I am very excited to be able to share it.</p>
<p>There is still a lot to do in naniar, and this release does not signify that there are no changes upcoming. It is a 1.0.0 release to establish that this is a stable release, and any changes upcoming will go through a more formal deprecation process.</p>
<p>Here’s a brief description of some of the changes in this release</p>
</section>
<section id="new-things" class="level1">
<h1>New things</h1>
<section id="jss-publication" class="level2">
<h2 class="anchored" data-anchor-id="jss-publication">JSS publication</h2>
<p>You can now retrieve a citation for <code>naniar</code> with <a href="https://rdrr.io/r/utils/citation.html"><code>citation()</code></a>:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://rdrr.io/r/utils/citation.html">citation</a></span><span class="o">(</span><span class="s">"naniar"</span><span class="o">)</span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt; To cite naniar in publications use:</span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt;   Tierney N, Cook D (2023). "Expanding Tidy Data Principles to</span></span>
<span><span class="c">#&gt;   Facilitate Missing Data Exploration, Visualization and Assessment of</span></span>
<span><span class="c">#&gt;   Imputations." _Journal of Statistical Software_, *105*(7), 1-31.</span></span>
<span><span class="c">#&gt;   doi:10.18637/jss.v105.i07 &lt;https://doi.org/10.18637/jss.v105.i07&gt;.</span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt; A BibTeX entry for LaTeX users is</span></span>
<span><span class="c">#&gt; </span></span>
<span><span class="c">#&gt;   @Article{,</span></span>
<span><span class="c">#&gt;     title = {Expanding Tidy Data Principles to Facilitate Missing Data Exploration, Visualization and Assessment of Imputations},</span></span>
<span><span class="c">#&gt;     author = {Nicholas Tierney and Dianne Cook},</span></span>
<span><span class="c">#&gt;     journal = {Journal of Statistical Software},</span></span>
<span><span class="c">#&gt;     year = {2023},</span></span>
<span><span class="c">#&gt;     volume = {105},</span></span>
<span><span class="c">#&gt;     number = {7},</span></span>
<span><span class="c">#&gt;     pages = {1--31},</span></span>
<span><span class="c">#&gt;     doi = {10.18637/jss.v105.i07},</span></span>
<span><span class="c">#&gt;   }</span></span>
<span></span></code></pre>
</div>
</section>
<section id="set-missing-values-with-set_n_miss-and-set_prop_miss" class="level2">
<h2 class="anchored" data-anchor-id="set-missing-values-with-set_n_miss-and-set_prop_miss">Set missing values with <code>set_n_miss()</code> and <code>set_prop_miss()</code></h2>
<p>These functions allow you to set a random amount of missingness either as a number of values, or as a proportion:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://github.com/njtierney/naniar">naniar</a></span><span class="o">)</span></span>
<span><span class="nv">vec</span> <span class="o">&lt;-</span> <span class="m">1</span><span class="o">:</span><span class="m">10</span></span>
<span><span class="c"># different each time</span></span>
<span><span class="nf"><a href="https://rdrr.io/pkg/naniar/man/set-prop-n-miss.html">set_n_miss</a></span><span class="o">(</span><span class="nv">vec</span>, n <span class="o">=</span> <span class="m">1</span><span class="o">)</span></span>
<span><span class="c">#&gt;  [1] NA  2  3  4  5  6  7  8  9 10</span></span>
<span></span><span><span class="nf"><a href="https://rdrr.io/pkg/naniar/man/set-prop-n-miss.html">set_n_miss</a></span><span class="o">(</span><span class="nv">vec</span>, n <span class="o">=</span> <span class="m">1</span><span class="o">)</span></span>
<span><span class="c">#&gt;  [1]  1  2  3  4  5  6  7  8  9 NA</span></span>
<span></span><span></span>
<span><span class="nf"><a href="https://rdrr.io/pkg/naniar/man/set-prop-n-miss.html">set_prop_miss</a></span><span class="o">(</span><span class="nv">vec</span>, prop <span class="o">=</span> <span class="m">0.2</span><span class="o">)</span></span>
<span><span class="c">#&gt;  [1] NA  2  3 NA  5  6  7  8  9 10</span></span>
<span></span><span><span class="nf"><a href="https://rdrr.io/pkg/naniar/man/set-prop-n-miss.html">set_prop_miss</a></span><span class="o">(</span><span class="nv">vec</span>, prop <span class="o">=</span> <span class="m">0.6</span><span class="o">)</span></span>
<span><span class="c">#&gt;  [1]  1 NA NA  4 NA NA NA  8  9 NA</span></span>
<span></span></code></pre>
</div>
<p>I would suggest that these functions are used inside a dataframe. I will provide a few examples below using <code>dplyr</code>. For just one variable, you could set missingness like so:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://tidyverse.tidyverse.org">tidyverse</a></span><span class="o">)</span></span>
<span><span class="c">#&gt; ── <span style="font-weight: bold;">Attaching packages</span> ───────────────────────────── tidyverse 1.3.2 ──</span></span>
<span><span class="c">#&gt; <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">ggplot2</span> 3.4.0     <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">purrr  </span> 1.0.1</span></span>
<span><span class="c">#&gt; <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">tibble </span> 3.1.8     <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">dplyr  </span> 1.1.0</span></span>
<span><span class="c">#&gt; <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">tidyr  </span> 1.3.0     <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">stringr</span> 1.5.0</span></span>
<span><span class="c">#&gt; <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">readr  </span> 2.1.3     <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">forcats</span> 1.0.0</span></span>
<span><span class="c">#&gt; ── <span style="font-weight: bold;">Conflicts</span> ──────────────────────────────── tidyverse_conflicts() ──</span></span>
<span><span class="c">#&gt; <span style="color: #BB0000;">✖</span> <span style="color: #0000BB;">dplyr</span>::<span style="color: #00BB00;">filter()</span> masks <span style="color: #0000BB;">stats</span>::filter()</span></span>
<span><span class="c">#&gt; <span style="color: #BB0000;">✖</span> <span style="color: #0000BB;">dplyr</span>::<span style="color: #00BB00;">lag()</span>    masks <span style="color: #0000BB;">stats</span>::lag()</span></span>
<span></span><span><span class="nv">mtcars_df</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://tibble.tidyverse.org/reference/as_tibble.html">as_tibble</a></span><span class="o">(</span><span class="nv">mtcars</span><span class="o">)</span></span>
<span></span>
<span><span class="nf"><a href="https://docs.ropensci.org/visdat/reference/vis_miss.html">vis_miss</a></span><span class="o">(</span><span class="nv">mtcars_df</span><span class="o">)</span></span>
</code></pre>
<img src="https://www.njtierney.com/posts/2023-02-02-naniar-version-0-6-0/figs/miss-one-1.png" width="700px" style="display: block; margin: auto;">
<pre class="chroma"><code class="language-r" data-lang="r"><span></span>
<span><span class="nv">mtcars_miss_mpg</span> <span class="o">&lt;-</span> <span class="nv">mtcars_df</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span>mpg <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/pkg/naniar/man/set-prop-n-miss.html">set_prop_miss</a></span><span class="o">(</span><span class="nv">mpg</span>, <span class="m">0.5</span><span class="o">)</span><span class="o">)</span></span>
<span></span>
<span><span class="nf"><a href="https://docs.ropensci.org/visdat/reference/vis_miss.html">vis_miss</a></span><span class="o">(</span><span class="nv">mtcars_miss_mpg</span><span class="o">)</span></span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2023-02-02-naniar-version-0-6-0/figs/miss-one-2.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>Or add missingness to a few variables:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">mtcars_miss_some</span> <span class="o">&lt;-</span> <span class="nv">mtcars_df</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/across.html">across</a></span><span class="o">(</span></span>
<span>      <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span><span class="nv">mpg</span>, <span class="nv">cyl</span>, <span class="nv">disp</span><span class="o">)</span>,</span>
<span>      \<span class="o">(</span><span class="nv">x</span><span class="o">)</span> <span class="nf"><a href="https://rdrr.io/pkg/naniar/man/set-prop-n-miss.html">set_prop_miss</a></span><span class="o">(</span><span class="nv">x</span>, <span class="m">0.5</span><span class="o">)</span></span>
<span>    <span class="o">)</span></span>
<span>  <span class="o">)</span></span>
<span></span>
<span><span class="nv">mtcars_miss_some</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 32 × 11</span></span></span>
<span><span class="c">#&gt;      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>  <span style="color: #BB0000;">NA</span>      <span style="color: #BB0000;">NA</span>   <span style="color: #BB0000;">NA</span>    110  3.9   2.62  16.5     0     1     4     4</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>  21      <span style="color: #BB0000;">NA</span>   <span style="color: #BB0000;">NA</span>    110  3.9   2.88  17.0     0     1     4     4</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>  22.8     4  108     93  3.85  2.32  18.6     1     1     4     1</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>  21.4    <span style="color: #BB0000;">NA</span>  258    110  3.08  3.22  19.4     1     0     3     1</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>  <span style="color: #BB0000;">NA</span>      <span style="color: #BB0000;">NA</span>   <span style="color: #BB0000;">NA</span>    175  3.15  3.44  17.0     0     0     3     2</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>  18.1     6   <span style="color: #BB0000;">NA</span>    105  2.76  3.46  20.2     1     0     3     1</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>  14.3     8   <span style="color: #BB0000;">NA</span>    245  3.21  3.57  15.8     0     0     3     4</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>  <span style="color: #BB0000;">NA</span>      <span style="color: #BB0000;">NA</span>  147.    62  3.69  3.19  20       1     0     4     2</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>  22.8    <span style="color: #BB0000;">NA</span>  141.    95  3.92  3.15  22.9     1     0     4     2</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>  19.2     6   <span style="color: #BB0000;">NA</span>    123  3.92  3.44  18.3     1     0     4     4</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># … with 22 more rows</span></span></span>
<span></span><span></span>
<span><span class="nf"><a href="https://docs.ropensci.org/visdat/reference/vis_miss.html">vis_miss</a></span><span class="o">(</span><span class="nv">mtcars_miss_some</span><span class="o">)</span></span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2023-02-02-naniar-version-0-6-0/figs/miss-some-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>Or you can add missingness to all variables like so:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">mtcars_miss_all</span> <span class="o">&lt;-</span> <span class="nv">mtcars_df</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/across.html">across</a></span><span class="o">(</span></span>
<span>      <span class="nf"><a href="https://tidyselect.r-lib.org/reference/everything.html">everything</a></span><span class="o">(</span><span class="o">)</span>,</span>
<span>      \<span class="o">(</span><span class="nv">x</span><span class="o">)</span> <span class="nf"><a href="https://rdrr.io/pkg/naniar/man/set-prop-n-miss.html">set_prop_miss</a></span><span class="o">(</span><span class="nv">x</span>, <span class="m">0.5</span><span class="o">)</span></span>
<span>    <span class="o">)</span></span>
<span>  <span class="o">)</span></span>
<span></span>
<span><span class="nv">mtcars_miss_all</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 32 × 11</span></span></span>
<span><span class="c">#&gt;      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>  <span style="color: #BB0000;">NA</span>      <span style="color: #BB0000;">NA</span>  160    110  3.9   2.62  16.5    <span style="color: #BB0000;">NA</span>    <span style="color: #BB0000;">NA</span>     4    <span style="color: #BB0000;">NA</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>  21      <span style="color: #BB0000;">NA</span>   <span style="color: #BB0000;">NA</span>    110  3.9   2.88  17.0     0     1    <span style="color: #BB0000;">NA</span>    <span style="color: #BB0000;">NA</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>  22.8     4   <span style="color: #BB0000;">NA</span>     <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span>    <span style="color: #BB0000;">NA</span>     18.6     1    <span style="color: #BB0000;">NA</span>     4    <span style="color: #BB0000;">NA</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>  <span style="color: #BB0000;">NA</span>      <span style="color: #BB0000;">NA</span>   <span style="color: #BB0000;">NA</span>    110 <span style="color: #BB0000;">NA</span>    <span style="color: #BB0000;">NA</span>     19.4    <span style="color: #BB0000;">NA</span>    <span style="color: #BB0000;">NA</span>    <span style="color: #BB0000;">NA</span>     1</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>  <span style="color: #BB0000;">NA</span>       8   <span style="color: #BB0000;">NA</span>     <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span>     3.44  <span style="color: #BB0000;">NA</span>      <span style="color: #BB0000;">NA</span>    <span style="color: #BB0000;">NA</span>     3     2</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>  18.1     6  225     <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span>    <span style="color: #BB0000;">NA</span>     20.2     1     0     3     1</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>  <span style="color: #BB0000;">NA</span>      <span style="color: #BB0000;">NA</span>   <span style="color: #BB0000;">NA</span>     <span style="color: #BB0000;">NA</span>  3.21  3.57  <span style="color: #BB0000;">NA</span>       0    <span style="color: #BB0000;">NA</span>    <span style="color: #BB0000;">NA</span>     4</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>  24.4    <span style="color: #BB0000;">NA</span>  147.    <span style="color: #BB0000;">NA</span>  3.69  3.19  20      <span style="color: #BB0000;">NA</span>    <span style="color: #BB0000;">NA</span>     4     2</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>  <span style="color: #BB0000;">NA</span>       4  141.    95  3.92  3.15  22.9    <span style="color: #BB0000;">NA</span>     0    <span style="color: #BB0000;">NA</span>    <span style="color: #BB0000;">NA</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>  <span style="color: #BB0000;">NA</span>      <span style="color: #BB0000;">NA</span>  168.   123  3.92 <span style="color: #BB0000;">NA</span>     <span style="color: #BB0000;">NA</span>      <span style="color: #BB0000;">NA</span>     0     4     4</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># … with 22 more rows</span></span></span>
<span></span><span></span>
<span><span class="nf"><a href="https://docs.ropensci.org/visdat/reference/vis_miss.html">vis_miss</a></span><span class="o">(</span><span class="nv">mtcars_miss_all</span><span class="o">)</span></span>
</code></pre>
<img src="https://www.njtierney.com/posts/2023-02-02-naniar-version-0-6-0/figs/miss-all-1.png" width="700px" style="display: block; margin: auto;">
<pre class="chroma"><code class="language-r" data-lang="r"><span></span>
<span><span class="nf"><a href="https://rdrr.io/pkg/naniar/man/miss_var_summary.html">miss_var_summary</a></span><span class="o">(</span><span class="nv">mtcars_miss_all</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 11 × 3</span></span></span>
<span><span class="c">#&gt;    variable n_miss pct_miss</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>     <span style="color: #555555; font-style: italic;">&lt;int&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span> mpg          16       50</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span> cyl          16       50</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span> disp         16       50</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span> hp           16       50</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span> drat         16       50</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span> wt           16       50</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span> qsec         16       50</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span> vs           16       50</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span> am           16       50</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span> gear         16       50</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">11</span> carb         16       50</span></span>
<span></span></code></pre>
</div>
<p>This resolves <a href="https://github.com/njtierney/naniar/issues/298">#298</a>.</p>
</section>
<section id="bug-fixes-and-other-small-changes" class="level2">
<h2 class="anchored" data-anchor-id="bug-fixes-and-other-small-changes">Bug Fixes and other small changes</h2>
<ul>
<li><p>Replaced <a href="https://tidyr.tidyverse.org/reference/gather.html"><code>tidyr::gather</code></a> with <a href="https://tidyr.tidyverse.org/reference/pivot_longer.html"><code>tidyr::pivot_longer</code></a> (<a href="https://github.com/njtierney/naniar/issues/301">#301</a>)</p></li>
<li><p>Fixed bug in <a href="https://rdrr.io/pkg/naniar/man/gg_miss_var.html"><code>gg_miss_var()</code></a> where a warning appears to due change in how to remove legend (<a href="https://github.com/njtierney/naniar/issues/288">#288</a>).</p></li>
<li><p>Removed package <code>gdtools</code> as it is no longer needed (<a href="https://github.com/njtierney/naniar/issues/302">302</a>).</p></li>
<li><p>Imported the packages, <code>vctrs</code> and <code>cli</code> to assist with internal checking and error messages. Both of these packages are “free” dependencies, as they imported by existing dependencies, <code>dplyr</code> and <code>ggplot2</code>.</p></li>
</ul>
</section>
</section>
<section id="some-thank-yous" class="level1">
<h1>Some thank yous</h1>
<p>Thank you to everyone who has contributed to this release! Especially the following people: <a href="https://github.com/ddauber"><span class="citation" data-cites="ddauber">@ddauber</span></a>, <a href="https://github.com/davidgohel"><span class="citation" data-cites="davidgohel">@davidgohel</span></a>.</p>
<p>I am also excited to announce that I have been supported by the R Consortium to improve how R handles missing values! Through this grant, I will be improving the R packages <code>naniar</code> and <code>visdat</code>. I will be posting more details about this soon, but what this means for you the user is that there will be more updates and improvements to both of these packages in the coming months. Stay tuned.</p>


</section>

 ]]></description>
  <category>rstats</category>
  <category>data visualisation</category>
  <category>missing data</category>
  <guid>https://www.njtierney.com/posts/2023-02-02-naniar-version-0-6-0/</guid>
  <pubDate>Tue, 07 Feb 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>visdat Version 0.6.0</title>
  <link>https://www.njtierney.com/posts/2023-02-01-visdat-version-0-6-0/</link>
  <description><![CDATA[ 
<header class="site-header">
  <h1 class="site-title">
    <a href="../../">
      <img class="hvr-grow site-logo" src="https://www.njtierney.com/assets/njt-logo-small.png" alt="Nick logo">
    </a>
    <span class="hvr-bob site-title-credibly">Credibly</span>
    <span class="hvr-hang site-title-curious">Curious</span>
  </h1>
  <p class="site-subtitle">
    Nick Tierney's (mostly) rstats blog
  </p>
  
</header>




<p>I’m please to say that visdat version 0.6.0 (codename: “Superman, Lazlo Bane”) is now on CRAN. This is the first release in nearly 3 years, there are a couple of new functions for visualising numeric and binary data, as well as some maintenance and bug fixes.</p>
<p>Let’s walk through some of the new features, bug fixes, and other misc changes.</p>
<section id="new-features" class="level1">
<h1>New Features</h1>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://rdrr.io/r/base/options.html">options</a></span><span class="o">(</span>tidyverse.quiet <span class="o">=</span> <span class="kc">TRUE</span><span class="o">)</span></span>
<span><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://tidyverse.tidyverse.org">tidyverse</a></span><span class="o">)</span></span>
<span><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://docs.ropensci.org/visdat/">visdat</a></span><span class="o">)</span></span></code></pre>
</div>
<section id="vis_value---visualise-values" class="level2">
<h2 class="anchored" data-anchor-id="vis_value---visualise-values"><code>vis_value()</code> - visualise values</h2>
<p>The idea of <a href="https://docs.ropensci.org/visdat/reference/vis_value.html"><code>vis_value()</code></a> is to visualise numeric data, so that you can get a quick idea of the values in your dataset. It does this by scaling all the data between 0 and 1, but it only works with numeric data.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://docs.ropensci.org/visdat/reference/vis_value.html">vis_value</a></span><span class="o">(</span><span class="nv">mtcars</span><span class="o">)</span></span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2023-02-01-visdat-version-0-6-0/figs/vis-value-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>It can be fun and interesting to arrange by a variable and then show see how that changes the plot.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://docs.ropensci.org/visdat/reference/vis_cor.html">vis_cor</a></span><span class="o">(</span><span class="nv">mtcars</span><span class="o">)</span></span>
</code></pre>
<img src="https://www.njtierney.com/posts/2023-02-01-visdat-version-0-6-0/figs/vis-cor-1.png" width="700px" style="display: block; margin: auto;">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">mtcars</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> <span class="nf"><a href="https://dplyr.tidyverse.org/reference/arrange.html">arrange</a></span><span class="o">(</span><span class="nv">cyl</span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> <span class="nf"><a href="https://docs.ropensci.org/visdat/reference/vis_value.html">vis_value</a></span><span class="o">(</span><span class="o">)</span></span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2023-02-01-visdat-version-0-6-0/figs/vis-cor-2.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>Although fair warning that there’s a whole set of statistics/data visualisation that focusses on how to arrange rows and columns - a technique called seriation. For a fun introduction, I’d recommend this lovely <a href="http://nicolas.kruchten.com/content/2018/02/seriation/">blogpost</a> by <a href="https://github.com/nicolaskruchten">Nicholas Kruchten</a>. One day I will <a href="https://github.com/ropensci/visdat/issues/8">implement seriation in visdat</a>.</p>
<p>Note that if you use <a href="https://docs.ropensci.org/visdat/reference/vis_value.html"><code>vis_value()</code></a> on a dataset that isn’t entirely numeric, you will get an error:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://docs.ropensci.org/visdat/reference/vis_value.html">vis_value</a></span><span class="o">(</span><span class="nv">diamonds</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #BBBB00; font-weight: bold;">Error</span><span style="font-weight: bold;"> in `test_if_all_numeric()` at </span><a href="file:///Users/nick/github/njtierney/visdat/R/vis-value.R"><span style="font-weight: bold;">visdat/R/vis-value.R:33:2</span></a><span style="font-weight: bold;">:</span></span></span>
<span><span class="c">#&gt; <span style="color: #BBBB00;">!</span> Data input can only contain numeric values</span></span>
<span><span class="c">#&gt; Please subset the data to the numeric values you would like.</span></span>
<span><span class="c">#&gt; `dplyr::select(&lt;data&gt;, where(is.numeric))`</span></span>
<span><span class="c">#&gt; Can be helpful here!</span></span>
<span></span></code></pre>
</div>
</section>
<section id="vis_binary-visualise-binary-values" class="level2">
<h2 class="anchored" data-anchor-id="vis_binary-visualise-binary-values"><code>vis_binary()</code> visualise binary values</h2>
<p>The <a href="https://docs.ropensci.org/visdat/reference/vis_binary.html"><code>vis_binary()</code></a> function is for visualising datasets with binary values - similar to <a href="https://docs.ropensci.org/visdat/reference/vis_value.html"><code>vis_value()</code></a>, but just for binary data (0, 1, NA).</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://docs.ropensci.org/visdat/reference/vis_binary.html">vis_binary</a></span><span class="o">(</span><span class="nv">dat_bin</span><span class="o">)</span></span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2023-02-01-visdat-version-0-6-0/figs/vis-binary-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>Thank you to <a href="https://child-health-research.centre.uq.edu.au/profile/3264/trish-gilholm">Trish Gilholm</a> for her suggested use case for this.</p>
</section>
<section id="facetting-in-visdat" class="level2">
<h2 class="anchored" data-anchor-id="facetting-in-visdat">Facetting in visdat</h2>
<p>It is now possible to perform facetting for the following functions in visdat: <a href="https://docs.ropensci.org/visdat/reference/vis_dat.html"><code>vis_dat()</code></a>, <a href="https://docs.ropensci.org/visdat/reference/vis_cor.html"><code>vis_cor()</code></a>, and <a href="https://docs.ropensci.org/visdat/reference/vis_miss.html"><code>vis_miss()</code></a> via the <code>facet</code> argument. This lead to some internal cleaning up of package code (always fun to revisit some old code and refactor!) Here’s an example of facetting:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://docs.ropensci.org/visdat/reference/vis_dat.html">vis_dat</a></span><span class="o">(</span><span class="nv">airquality</span>, facet <span class="o">=</span> <span class="nv">Month</span><span class="o">)</span> </span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2023-02-01-visdat-version-0-6-0/figs/vis-dat-facet-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://docs.ropensci.org/visdat/reference/vis_cor.html">vis_cor</a></span><span class="o">(</span><span class="nv">airquality</span>, facet <span class="o">=</span> <span class="nv">Month</span><span class="o">)</span> </span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2023-02-01-visdat-version-0-6-0/figs/vis-cor-facet-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://docs.ropensci.org/visdat/reference/vis_miss.html">vis_miss</a></span><span class="o">(</span><span class="nv">airquality</span>, facet <span class="o">=</span> <span class="nv">Month</span><span class="o">)</span> </span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2023-02-01-visdat-version-0-6-0/figs/vis-miss-facet-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>Notably for <code>vis_miss</code> when using facetting, you don’t get column missingness summaries, as I couldn’t quite work out how to do this for each facet.</p>
<p>Thank you to <a href="https://twitter.com/samfirke/status/984425923243134976">Sam Firke’s</a> initial tweet on this that inspired this, and <a href="https://github.com/jzadra">Jonathan Zadra’s</a> contributions in the <a href="https://github.com/ropensci/visdat/issues/78">issue thread</a>.</p>
<p>The next release will implement facetting for <a href="https://docs.ropensci.org/visdat/reference/vis_value.html"><code>vis_value()</code></a>, <a href="https://docs.ropensci.org/visdat/reference/vis_binary.html"><code>vis_binary()</code></a>, <a href="https://docs.ropensci.org/visdat/reference/vis_compare.html"><code>vis_compare()</code></a>, <a href="https://docs.ropensci.org/visdat/reference/vis_expect.html"><code>vis_expect()</code></a>, and <a href="https://docs.ropensci.org/visdat/reference/vis_guess.html"><code>vis_guess()</code></a> - see <a href="https://github.com/ropensci/visdat/issues/159">#159</a> to keep track.</p>
</section>
<section id="data-methods-for-plotting" class="level2">
<h2 class="anchored" data-anchor-id="data-methods-for-plotting">Data methods for plotting</h2>
<p>Related to facetting, I have implemented methods that provide data methods for plots with <a href="https://docs.ropensci.org/visdat/reference/data-vis-dat.html"><code>data_vis_dat()</code></a>, <a href="https://docs.ropensci.org/visdat/reference/data-vis-cor.html"><code>data_vis_cor()</code></a>, and <a href="https://docs.ropensci.org/visdat/reference/data-vis-miss.html"><code>data_vis_miss()</code></a>:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://docs.ropensci.org/visdat/reference/data-vis-dat.html">data_vis_dat</a></span><span class="o">(</span><span class="nv">airquality</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 918 × 4</span></span></span>
<span><span class="c">#&gt;     rows variable valueType value</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>     <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>     1 Day      integer   41   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>     1 Month    integer   190  </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>     1 Ozone    integer   7.4  </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>     1 Solar.R  integer   67   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>     1 Temp     integer   5    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>     1 Wind     numeric   1    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>     2 Day      integer   36   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>     2 Month    integer   118  </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>     2 Ozone    integer   8    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>     2 Solar.R  integer   72   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># … with 908 more rows</span></span></span>
<span></span></code></pre>
</div>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://docs.ropensci.org/visdat/reference/data-vis-miss.html">data_vis_miss</a></span><span class="o">(</span><span class="nv">airquality</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 918 × 4</span></span></span>
<span><span class="c">#&gt;     rows variable valueType value</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>     <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>     1 Day      FALSE     FALSE</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>     1 Month    FALSE     FALSE</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>     1 Ozone    FALSE     FALSE</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>     1 Solar.R  FALSE     FALSE</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>     1 Temp     FALSE     FALSE</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>     1 Wind     FALSE     FALSE</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>     2 Day      FALSE     FALSE</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>     2 Month    FALSE     FALSE</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>     2 Ozone    FALSE     FALSE</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>     2 Solar.R  FALSE     FALSE</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># … with 908 more rows</span></span></span>
<span></span></code></pre>
</div>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://docs.ropensci.org/visdat/reference/data-vis-cor.html">data_vis_cor</a></span><span class="o">(</span><span class="nv">airquality</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 36 × 3</span></span></span>
<span><span class="c">#&gt;    row_1   row_2     value</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>   <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>     <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span> Ozone   Ozone    1     </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span> Ozone   Solar.R  0.348 </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span> Ozone   Wind    -<span style="color: #BB0000;">0.602</span> </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span> Ozone   Temp     0.698 </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span> Ozone   Month    0.165 </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span> Ozone   Day     -<span style="color: #BB0000;">0.013</span><span style="color: #BB0000; text-decoration: underline;">2</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span> Solar.R Ozone    0.348 </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span> Solar.R Solar.R  1     </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span> Solar.R Wind    -<span style="color: #BB0000;">0.056</span><span style="color: #BB0000; text-decoration: underline;">8</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span> Solar.R Temp     0.276 </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># … with 26 more rows</span></span></span>
<span></span></code></pre>
</div>
<p>The implementation of this works by providing these functions as S3 methods that have a <code>.grouped_df</code> method to facilitate plotting with facets.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">airquality</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> <span class="nf"><a href="https://dplyr.tidyverse.org/reference/group_by.html">group_by</a></span><span class="o">(</span><span class="nv">Month</span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> <span class="nf"><a href="https://docs.ropensci.org/visdat/reference/data-vis-dat.html">data_vis_dat</a></span><span class="o">(</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 765 × 5</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># Groups:   Month [5]</span></span></span>
<span><span class="c">#&gt;    Month  rows variable valueType value</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>     <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>     5     1 Day      integer   41   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>     5     1 Ozone    integer   190  </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>     5     1 Solar.R  integer   7.4  </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>     5     1 Temp     integer   67   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>     5     1 Wind     numeric   1    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>     5     2 Day      integer   36   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>     5     2 Ozone    integer   118  </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>     5     2 Solar.R  integer   8    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>     5     2 Temp     integer   72   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>     5     2 Wind     numeric   2    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># … with 755 more rows</span></span></span>
<span></span></code></pre>
</div>
</section>
<section id="missing-values-show-up-in-list-columns" class="level2">
<h2 class="anchored" data-anchor-id="missing-values-show-up-in-list-columns">Missing values show up in list columns</h2>
<p><a href="https://docs.ropensci.org/visdat/reference/vis_dat.html"><code>vis_dat()</code></a> <a href="https://docs.ropensci.org/visdat/reference/vis_miss.html"><code>vis_miss()</code></a> and <a href="https://docs.ropensci.org/visdat/reference/vis_guess.html"><code>vis_guess()</code></a> now render missing values in list-columns. Let’s demonstrate this with the <code>star_wars</code> dataset from <code>dplyr</code>, which has a few list columns.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">starwars</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 87 × 14</span></span></span>
<span><span class="c">#&gt;    name        height  mass hair_…¹ skin_…² eye_c…³ birth…⁴ sex   gender homew…⁵</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>        <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>   <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>   <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>     <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span> <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>  </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span> Luke Skywa…    172    77 blond   fair    blue       19   male  mascu… Tatooi…</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span> C-3PO          167    75 <span style="color: #BB0000;">NA</span>      gold    yellow    112   none  mascu… Tatooi…</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span> R2-D2           96    32 <span style="color: #BB0000;">NA</span>      white,… red        33   none  mascu… Naboo  </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span> Darth Vader    202   136 none    white   yellow     41.9 male  mascu… Tatooi…</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span> Leia Organa    150    49 brown   light   brown      19   fema… femin… Aldera…</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span> Owen Lars      178   120 brown,… light   blue       52   male  mascu… Tatooi…</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span> Beru White…    165    75 brown   light   blue       47   fema… femin… Tatooi…</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span> R5-D4           97    32 <span style="color: #BB0000;">NA</span>      white,… red        <span style="color: #BB0000;">NA</span>   none  mascu… Tatooi…</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span> Biggs Dark…    183    84 black   light   brown      24   male  mascu… Tatooi…</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span> Obi-Wan Ke…    182    77 auburn… fair    blue-g…    57   male  mascu… Stewjon</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># … with 77 more rows, 4 more variables: species &lt;chr&gt;, films &lt;list&gt;,</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">#   vehicles &lt;list&gt;, starships &lt;list&gt;, and abbreviated variable names</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">#   ¹​hair_color, ²​skin_color, ³​eye_color, ⁴​birth_year, ⁵​homeworld</span></span></span>
<span></span></code></pre>
</div>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://pillar.r-lib.org/reference/glimpse.html">glimpse</a></span><span class="o">(</span><span class="nv">starwars</span><span class="o">)</span></span>
<span><span class="c">#&gt; Rows: 87</span></span>
<span><span class="c">#&gt; Columns: 14</span></span>
<span><span class="c">#&gt; $ name       <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span> "Luke Skywalker", "C-3PO", "R2-D2", "Darth Vader", "Leia Or…</span></span>
<span><span class="c">#&gt; $ height     <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> 172, 167, 96, 202, 150, 178, 165, 97, 183, 182, 188, 180, 2…</span></span>
<span><span class="c">#&gt; $ mass       <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> 77.0, 75.0, 32.0, 136.0, 49.0, 120.0, 75.0, 32.0, 84.0, 77.…</span></span>
<span><span class="c">#&gt; $ hair_color <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span> "blond", NA, NA, "none", "brown", "brown, grey", "brown", N…</span></span>
<span><span class="c">#&gt; $ skin_color <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span> "fair", "gold", "white, blue", "white", "light", "light", "…</span></span>
<span><span class="c">#&gt; $ eye_color  <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span> "blue", "yellow", "red", "yellow", "brown", "blue", "blue",…</span></span>
<span><span class="c">#&gt; $ birth_year <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> 19.0, 112.0, 33.0, 41.9, 19.0, 52.0, 47.0, NA, 24.0, 57.0, …</span></span>
<span><span class="c">#&gt; $ sex        <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span> "male", "none", "none", "male", "female", "male", "female",…</span></span>
<span><span class="c">#&gt; $ gender     <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span> "masculine", "masculine", "masculine", "masculine", "femini…</span></span>
<span><span class="c">#&gt; $ homeworld  <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span> "Tatooine", "Tatooine", "Naboo", "Tatooine", "Alderaan", "T…</span></span>
<span><span class="c">#&gt; $ species    <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span> "Human", "Droid", "Droid", "Human", "Human", "Human", "Huma…</span></span>
<span><span class="c">#&gt; $ films      <span style="color: #555555; font-style: italic;">&lt;list&gt;</span> &lt;"The Empire Strikes Back", "Revenge of the Sith", "Return…</span></span>
<span><span class="c">#&gt; $ vehicles   <span style="color: #555555; font-style: italic;">&lt;list&gt;</span> &lt;"Snowspeeder", "Imperial Speeder Bike"&gt;, &lt;&gt;, &lt;&gt;, &lt;&gt;, "Imp…</span></span>
<span><span class="c">#&gt; $ starships  <span style="color: #555555; font-style: italic;">&lt;list&gt;</span> &lt;"X-wing", "Imperial shuttle"&gt;, &lt;&gt;, &lt;&gt;, "TIE Advanced x1",…</span></span>
<span></span></code></pre>
</div>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://docs.ropensci.org/visdat/reference/vis_dat.html">vis_dat</a></span><span class="o">(</span><span class="nv">starwars</span><span class="o">)</span></span>
</code></pre>
<img src="https://www.njtierney.com/posts/2023-02-01-visdat-version-0-6-0/figs/show-vis-lists-1.png" width="700px" style="display: block; margin: auto;">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://docs.ropensci.org/visdat/reference/vis_miss.html">vis_miss</a></span><span class="o">(</span><span class="nv">starwars</span><span class="o">)</span></span>
</code></pre>
<img src="https://www.njtierney.com/posts/2023-02-01-visdat-version-0-6-0/figs/show-vis-lists-2.png" width="700px" style="display: block; margin: auto;">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://docs.ropensci.org/visdat/reference/vis_guess.html">vis_guess</a></span><span class="o">(</span><span class="nv">starwars</span><span class="o">)</span></span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2023-02-01-visdat-version-0-6-0/figs/show-vis-lists-3.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>As you can see, lists are now displayed in the visualisation. Unfortunately <code>vis_guess</code> has trouble guessing lists, but that is a limitation due to how it guesses variable types.</p>
<p>Thank you to github user <a href="https://github.com/cregouby">cregouby</a> for adding this in <a href="https://github.com/ropensci/visdat/pull/138">#138</a>.</p>
</section>
<section id="abbreviation-helpers" class="level2">
<h2 class="anchored" data-anchor-id="abbreviation-helpers">Abbreviation helpers</h2>
<p>Long variable names can be annoying and can crowd a plot. The <a href="https://docs.ropensci.org/visdat/reference/abbreviate_vars.html"><code>abbreviate_vars()</code></a> function can be used to help with this:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">long_data</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://tibble.tidyverse.org/reference/tibble.html">tibble</a></span><span class="o">(</span></span>
<span>  really_really_long_name <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span><span class="kc">NA</span>, <span class="kc">NA</span>, <span class="m">1</span><span class="o">:</span><span class="m">8</span><span class="o">)</span>,</span>
<span>  very_quite_long_name <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span><span class="o">-</span><span class="m">1</span><span class="o">:</span><span class="o">-</span><span class="m">8</span>, <span class="kc">NA</span>, <span class="kc">NA</span><span class="o">)</span>,</span>
<span>  this_long_name_is_something_else <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span><span class="kc">NA</span>, <span class="kc">NA</span>,</span>
<span>                                       <span class="nf"><a href="https://rdrr.io/r/base/seq.html">seq</a></span><span class="o">(</span>from <span class="o">=</span> <span class="m">0</span>, to <span class="o">=</span> <span class="m">1</span>, length.out <span class="o">=</span> <span class="m">8</span><span class="o">)</span><span class="o">)</span></span>
<span><span class="o">)</span></span>
<span></span>
<span><span class="nf"><a href="https://docs.ropensci.org/visdat/reference/vis_miss.html">vis_miss</a></span><span class="o">(</span><span class="nv">long_data</span><span class="o">)</span></span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2023-02-01-visdat-version-0-6-0/figs/long-data-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>Ugh no good.</p>
<p>Use <a href="https://docs.ropensci.org/visdat/reference/abbreviate_vars.html"><code>abbreviate_vars()</code></a> to help:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">long_data</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> <span class="nf"><a href="https://docs.ropensci.org/visdat/reference/abbreviate_vars.html">abbreviate_vars</a></span><span class="o">(</span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> <span class="nf"><a href="https://docs.ropensci.org/visdat/reference/vis_miss.html">vis_miss</a></span><span class="o">(</span><span class="o">)</span></span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2023-02-01-visdat-version-0-6-0/figs/show-abbreviate-vars-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>You can control the length of the abbreviation with <code>min_length</code>:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">long_data</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> <span class="nf"><a href="https://docs.ropensci.org/visdat/reference/abbreviate_vars.html">abbreviate_vars</a></span><span class="o">(</span>min_length <span class="o">=</span> <span class="m">5</span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> <span class="nf"><a href="https://docs.ropensci.org/visdat/reference/vis_miss.html">vis_miss</a></span><span class="o">(</span><span class="o">)</span></span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2023-02-01-visdat-version-0-6-0/figs/show-abbreviation-length-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>Under the hood this uses the base R function, <a href="https://rdrr.io/r/base/abbreviate.html"><code>abbreviate()</code></a> - a gem of a function.</p>
<p>Thank you to <a href="https://github.com/chapau3">chapau3</a>, and <a href="https://github.com/ivanhanigan">ivanhanigan</a> for requesting this feature (<a href="https://github.com/ropensci/visdat/issues/140">#140</a> and <a href="https://github.com/ropensci/visdat/issues/9">#9</a>).</p>
</section>
<section id="missingness-percentages-are-now-integers." class="level2">
<h2 class="anchored" data-anchor-id="missingness-percentages-are-now-integers.">Missingness percentages are now integers.</h2>
<p>The <a href="https://docs.ropensci.org/visdat/reference/vis_miss.html"><code>vis_miss()</code></a> function shows a percentage missing of the missing values in each column - I’ve decided to make this round to integers, as it is only a guide and I found them to be a bit cluttered. I also do not like the idea of extracting summary statistics from graphics, so they now look like this:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://docs.ropensci.org/visdat/reference/vis_miss.html">vis_miss</a></span><span class="o">(</span><span class="nv">airquality</span><span class="o">)</span></span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2023-02-01-visdat-version-0-6-0/figs/show-vis-miss-again-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>For more accurate representation of missingness summaries please use the <a href="http://naniar.njtierney.com/"><code>naniar</code> R package</a> functions like <a href="https://rdrr.io/pkg/naniar/man/miss_var_summary.html"><code>miss_var_summary()</code></a>:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://github.com/njtierney/naniar">naniar</a></span><span class="o">)</span></span>
<span><span class="nf"><a href="https://rdrr.io/pkg/naniar/man/miss_var_summary.html">miss_var_summary</a></span><span class="o">(</span><span class="nv">airquality</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 6 × 3</span></span></span>
<span><span class="c">#&gt;   variable n_miss pct_miss</span></span>
<span><span class="c">#&gt;   <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>     <span style="color: #555555; font-style: italic;">&lt;int&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">1</span> Ozone        37    24.2 </span></span>
<span><span class="c">#&gt; <span style="color: #555555;">2</span> Solar.R       7     4.58</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">3</span> Wind          0     0   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;">4</span> Temp          0     0   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;">5</span> Month         0     0   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;">6</span> Day           0     0</span></span>
<span></span></code></pre>
</div>
<p>Which also works with <a href="https://dplyr.tidyverse.org/reference/group_by.html"><code>dplyr::group_by()</code></a>:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">airquality</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/group_by.html">group_by</a></span><span class="o">(</span><span class="nv">Month</span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://rdrr.io/pkg/naniar/man/miss_var_summary.html">miss_var_summary</a></span><span class="o">(</span><span class="o">)</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 25 × 4</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># Groups:   Month [5]</span></span></span>
<span><span class="c">#&gt;    Month variable n_miss pct_miss</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>     <span style="color: #555555; font-style: italic;">&lt;int&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>     5 Ozone         5     16.1</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>     5 Solar.R       4     12.9</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>     5 Wind          0      0  </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>     5 Temp          0      0  </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>     5 Day           0      0  </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>     6 Ozone        21     70  </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>     6 Solar.R       0      0  </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>     6 Wind          0      0  </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>     6 Temp          0      0  </span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>     6 Day           0      0  </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># … with 15 more rows</span></span></span>
<span></span></code></pre>
</div>
<p>If you find that this really bothers you and you want to have control over the percentage missingness in the columns, please file an issue on visdat and I will look into adding more user control. Ideally I would have added control for users in the first place, but it just wasn’t something I was certain users wanted, and would require more arguments to a function, which require more tests…and so on. So with the mindset of keeping this package easy to maintain, I figured this might be the easiest way forward.</p>
</section>
<section id="bug-fixes-and-other-changes" class="level2">
<h2 class="anchored" data-anchor-id="bug-fixes-and-other-changes">Bug Fixes and Other changes</h2>
<p>Here is a quick listing of the other changes in this release of visdat:</p>
<ul>
<li>No longer use <code>gather</code> internally: <a href="https://github.com/ropensci/visdat/issues/141">#141</a></li>
<li>Resolve bug where <a href="https://docs.ropensci.org/visdat/reference/vis_value.html"><code>vis_value()</code></a> displayed constant values as NA values <a href="https://github.com/ropensci/visdat/issues/128">128</a> - these constant values are now shown as 1.</li>
<li>Removed use of the now deprecated “aes_string” from ggplot2</li>
<li>Output of plot in <code>vis_expect</code> would reorder columns (<a href="https://github.com/ropensci/visdat/issues/133">#133</a>), fixed in <a href="https://github.com/ropensci/visdat/pull/134">#143</a> by <a href="https://github.com/muschellij2">muschellij2</a>.</li>
<li>A new vignette on customising colour palettes in visdat, “Customising colour palettes in visdat”.</li>
<li>No longer uses gdtools for testing <a href="https://github.com/ropensci/visdat/issues/145">#145</a></li>
<li>Use <code>cli</code> internally for error messages.</li>
<li>Speed up some internal functions</li>
</ul>
</section>
</section>
<section id="thanks" class="level1">
<h1>Thanks</h1>
<p>Thank you to all the users who contributed to this release!</p>
<p><a href="https://github.com/muschellij2">muschellij2</a>, <a href="https://github.com/chapau3">chapau3</a>, <a href="https://github.com/ivanhanigan">ivanhanigan</a>, <a href="https://github.com/cregouby">cregouby</a>, <a href="https://github.com/jzadra">jzadra</a>.</p>


</section>

 ]]></description>
  <category>rstats</category>
  <category>data visualisation</category>
  <category>missing data</category>
  <category>rbloggers</category>
  <guid>https://www.njtierney.com/posts/2023-02-01-visdat-version-0-6-0/</guid>
  <pubDate>Thu, 02 Feb 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Population Pyramid Plots in ggplot2</title>
  <link>https://www.njtierney.com/posts/2022-08-09-pyramid-plots-in-ggplot2/</link>
  <description><![CDATA[ 
<header class="site-header">
  <h1 class="site-title">
    <a href="../../">
      <img class="hvr-grow site-logo" src="https://www.njtierney.com/assets/njt-logo-small.png" alt="Nick logo">
    </a>
    <span class="hvr-bob site-title-credibly">Credibly</span>
    <span class="hvr-hang site-title-curious">Curious</span>
  </h1>
  <p class="site-subtitle">
    Nick Tierney's (mostly) rstats blog
  </p>
  
</header>




<div class="highlight">
<p><img src="https://www.njtierney.com/posts/2022-08-09-pyramid-plots-in-ggplot2/imgs/two-shopping-carts.jpg" width="700px" style="display: block; margin: auto;"></p>
</div>
<p><em>Two Abandoned Trolleys, Nick Tierney, Film, Olympus XA</em></p>
<p>I recently had to make some pyramid plots in R. They are a useful way to compare age structures of populations. They look like this:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="figs/show-pop-pyramid-1.png" class="lightbox" data-gallery="quarto-lightbox-gallery-1" title="Age population structure of Sydney vs Melbourne"><img src="https://www.njtierney.com/posts/2022-08-09-pyramid-plots-in-ggplot2/figs/show-pop-pyramid-1.png" class="img-fluid figure-img" alt="Age population structure of Sydney vs Melbourne"></a></p>
<figcaption>Age population structure of Sydney vs Melbourne</figcaption>
</figure>
</div>
<p>It’s been a while since I had to make them, and in the past I’ve cooked them up in a relatively bespoke way. This time I needed to be able to have some level of programming to them - I wanted to be able to provide any two LGAs in Australia and then make a pyramid plot of them that looked nice.</p>
<p>I started by looking at this <a href="https://stackoverflow.com/questions/14680075/simpler-population-pyramid-in-ggplot2">SO thread</a> - overall this gave me what I wanted, but I thought I’d walk through my solution, as it is a little different, and might hopefully be useful to others.</p>
<section id="the-data" class="level1">
<h1>The data</h1>
<p>The data is comes from the Australian Bureau of Statistics, which is then cleaned up, and packaged in the <a href="https://github.com/njtierney/conmat">conmat</a> R package, which I maintain. Before I show that, I’ll load the packages I need, <code>tidyverse</code> , and <code>conmat</code>:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://tidyverse.tidyverse.org">tidyverse</a></span><span class="o">)</span></span><span><span class="c">#&gt; ── <span style="font-weight: bold;">Attaching packages</span> ───────────────────────────── tidyverse 1.3.1 ──</span></span><span><span class="c">#&gt; <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">ggplot2</span> 3.3.6     <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">purrr  </span> 0.3.4</span></span>
<span><span class="c">#&gt; <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">tibble </span> 3.1.7     <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">dplyr  </span> 1.0.9</span></span>
<span><span class="c">#&gt; <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">tidyr  </span> 1.2.0     <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">stringr</span> 1.4.0</span></span>
<span><span class="c">#&gt; <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">readr  </span> 2.1.2     <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">forcats</span> 0.5.1</span></span><span><span class="c">#&gt; ── <span style="font-weight: bold;">Conflicts</span> ──────────────────────────────── tidyverse_conflicts() ──</span></span>
<span><span class="c">#&gt; <span style="color: #BB0000;">✖</span> <span style="color: #0000BB;">dplyr</span>::<span style="color: #00BB00;">filter()</span> masks <span style="color: #0000BB;">stats</span>::filter()</span></span>
<span><span class="c">#&gt; <span style="color: #BB0000;">✖</span> <span style="color: #0000BB;">dplyr</span>::<span style="color: #00BB00;">lag()</span>    masks <span style="color: #0000BB;">stats</span>::lag()</span></span><span><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv">conmat</span><span class="o">)</span></span><span><span class="c">#&gt; Warning: package 'conmat' was built under R version 4.2.1</span></span></code></pre>
</div>
<p>You can access the age structured population for a given LGA like so:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="c"># |label: LGA-hobart</span></span>
<span><span class="nf"><a href="https://rdrr.io/pkg/conmat/man/abs_age_lga.html">abs_age_lga</a></span><span class="o">(</span><span class="s">"Hobart (C)"</span><span class="o">)</span></span><span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 18 × 4</span></span></span>
<span><span class="c">#&gt;    lga        lower.age.limit  year population</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>                <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>      <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span> Hobart (C)               0  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">2</span>442</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span> Hobart (C)               5  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">2</span>833</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span> Hobart (C)              10  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">2</span>771</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span> Hobart (C)              15  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">3</span>038</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span> Hobart (C)              20  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">4</span>982</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span> Hobart (C)              25  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">5</span>132</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span> Hobart (C)              30  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">4</span>196</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span> Hobart (C)              35  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">3</span>510</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span> Hobart (C)              40  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">3</span>214</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span> Hobart (C)              45  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">3</span>428</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">11</span> Hobart (C)              50  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">3</span>202</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">12</span> Hobart (C)              55  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">3</span>381</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">13</span> Hobart (C)              60  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">3</span>291</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">14</span> Hobart (C)              65  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">3</span>036</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">15</span> Hobart (C)              70  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">2</span>512</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">16</span> Hobart (C)              75  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">1</span>721</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">17</span> Hobart (C)              80  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">1</span>189</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">18</span> Hobart (C)              85  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">1</span>372</span></span></code></pre>
</div>
<p>In our case, we want to combine two LGAs and compare them. So let’s write a little helper function, <code>two_abs_age_lga</code>:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">two_abs_age_lga</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">lga_1</span>, <span class="nv">lga_2</span><span class="o">)</span><span class="o">{</span></span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/bind.html">bind_rows</a></span><span class="o">(</span></span>
<span>    <span class="nf"><a href="https://rdrr.io/pkg/conmat/man/abs_age_lga.html">abs_age_lga</a></span><span class="o">(</span><span class="nv">lga_1</span><span class="o">)</span>,</span>
<span>    <span class="nf"><a href="https://rdrr.io/pkg/conmat/man/abs_age_lga.html">abs_age_lga</a></span><span class="o">(</span><span class="nv">lga_2</span><span class="o">)</span></span>
<span>  <span class="o">)</span></span>
<span><span class="o">}</span></span></code></pre>
</div>
<p>So now we can get say, Melbourne and Sydney, like so:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">melb_syd</span> <span class="o">&lt;-</span> <span class="nf">two_abs_age_lga</span><span class="o">(</span><span class="s">"Melbourne (C)"</span>, <span class="s">"Sydney (C)"</span><span class="o">)</span></span>
<span><span class="nv">melb_syd</span></span><span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 36 × 4</span></span></span>
<span><span class="c">#&gt;    lga           lower.age.limit  year population</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>                   <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>      <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span> Melbourne (C)               0  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">4</span>882</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span> Melbourne (C)               5  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">3</span>450</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span> Melbourne (C)              10  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">2</span>675</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span> Melbourne (C)              15  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">9</span>396</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span> Melbourne (C)              20  <span style="text-decoration: underline;">2</span>020      <span style="text-decoration: underline;">38</span>434</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span> Melbourne (C)              25  <span style="text-decoration: underline;">2</span>020      <span style="text-decoration: underline;">38</span>546</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span> Melbourne (C)              30  <span style="text-decoration: underline;">2</span>020      <span style="text-decoration: underline;">25</span>834</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span> Melbourne (C)              35  <span style="text-decoration: underline;">2</span>020      <span style="text-decoration: underline;">15</span>072</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span> Melbourne (C)              40  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">8</span>554</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span> Melbourne (C)              45  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">6</span>753</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># … with 26 more rows</span></span></span><span><span class="nf"><a href="https://rdrr.io/r/utils/head.html">tail</a></span><span class="o">(</span><span class="nv">melb_syd</span><span class="o">)</span></span><span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 6 × 4</span></span></span>
<span><span class="c">#&gt;   lga        lower.age.limit  year population</span></span>
<span><span class="c">#&gt;   <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>                <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>      <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;">1</span> Sydney (C)              60  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">8</span>950</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">2</span> Sydney (C)              65  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">7</span>377</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">3</span> Sydney (C)              70  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">6</span>308</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">4</span> Sydney (C)              75  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">4</span>002</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">5</span> Sydney (C)              80  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">2</span>583</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">6</span> Sydney (C)              85  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">2</span>506</span></span></code></pre>
</div>
</section>
<section id="the-data-wrangling" class="level1">
<h1>The data wrangling</h1>
<p>Now, to get the data into this plot, what we want is a plot of the population against each age group. To illustrate this I’ll just use Melbourne data:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">melb</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/pkg/conmat/man/abs_age_lga.html">abs_age_lga</a></span><span class="o">(</span><span class="s">"Melbourne (C)"</span><span class="o">)</span></span>
<span><span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggplot.html">ggplot</a></span><span class="o">(</span><span class="nv">melb</span>,</span>
<span>       <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/aes.html">aes</a></span><span class="o">(</span>x <span class="o">=</span> <span class="nv">population</span>,</span>
<span>           y <span class="o">=</span> <span class="nv">lower.age.limit</span>,</span>
<span>           fill <span class="o">=</span> <span class="nv">lga</span><span class="o">)</span><span class="o">)</span> <span class="o">+</span> </span>
<span>  <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/geom_bar.html">geom_col</a></span><span class="o">(</span><span class="o">)</span></span></code></pre>
<p><img src="https://www.njtierney.com/posts/2022-08-09-pyramid-plots-in-ggplot2/figs/gg-melbourne-popn-oops-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>Ack, we need the <code>y</code> variable to be a factor</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggplot.html">ggplot</a></span><span class="o">(</span><span class="nv">melb</span>,</span>
<span>       <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/aes.html">aes</a></span><span class="o">(</span>x <span class="o">=</span> <span class="nv">population</span>,</span>
<span>           y <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/factor.html">factor</a></span><span class="o">(</span><span class="nv">lower.age.limit</span><span class="o">)</span>,</span>
<span>           fill <span class="o">=</span> <span class="nv">lga</span><span class="o">)</span><span class="o">)</span> <span class="o">+</span> </span>
<span>  <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/geom_bar.html">geom_col</a></span><span class="o">(</span><span class="o">)</span></span></code></pre>
<p><img src="https://www.njtierney.com/posts/2022-08-09-pyramid-plots-in-ggplot2/figs/gg-melbourne-popn-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>But what we actually want are two plots, one going the other way for the other group. We can make this happen by making the population negative:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">syd</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/pkg/conmat/man/abs_age_lga.html">abs_age_lga</a></span><span class="o">(</span><span class="s">"Sydney (C)"</span><span class="o">)</span></span>
<span><span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggplot.html">ggplot</a></span><span class="o">(</span><span class="nv">syd</span>,</span>
<span>       <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/aes.html">aes</a></span><span class="o">(</span>x <span class="o">=</span> <span class="o">-</span><span class="nv">population</span>,</span>
<span>           y <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/factor.html">factor</a></span><span class="o">(</span><span class="nv">lower.age.limit</span><span class="o">)</span>,</span>
<span>           fill <span class="o">=</span> <span class="nv">lga</span><span class="o">)</span><span class="o">)</span> <span class="o">+</span> </span>
<span>  <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/geom_bar.html">geom_col</a></span><span class="o">(</span><span class="o">)</span></span></code></pre>
<p><img src="https://www.njtierney.com/posts/2022-08-09-pyramid-plots-in-ggplot2/figs/gg-sydney-popn-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>And then we want to combine those two plots - so we can write something bespoke, like this. Let’s also make that age limit data a factor while we are here</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">melb_syd_pyramid</span> <span class="o">&lt;-</span> <span class="nv">melb_syd</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>    population <span class="o">=</span> <span class="nf"><a href="https://dplyr.tidyverse.org/reference/case_when.html">case_when</a></span><span class="o">(</span></span>
<span>      <span class="nv">lga</span> <span class="o">==</span> <span class="s">"Sydney (C)"</span> <span class="o">~</span> <span class="o">-</span><span class="nv">population</span>,</span>
<span>      <span class="kc">TRUE</span> <span class="o">~</span> <span class="nv">population</span></span>
<span>    <span class="o">)</span>,</span>
<span>    lower.age.limit <span class="o">=</span> <span class="nf"><a href="https://forcats.tidyverse.org/reference/as_factor.html">as_factor</a></span><span class="o">(</span><span class="nv">lower.age.limit</span><span class="o">)</span></span>
<span>  <span class="o">)</span></span>
<span></span>
<span><span class="nv">melb_syd_pyramid</span></span><span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 36 × 4</span></span></span>
<span><span class="c">#&gt;    lga           lower.age.limit  year population</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>         <span style="color: #555555; font-style: italic;">&lt;fct&gt;</span>           <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>      <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span> Melbourne (C) 0                <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">4</span>882</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span> Melbourne (C) 5                <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">3</span>450</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span> Melbourne (C) 10               <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">2</span>675</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span> Melbourne (C) 15               <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">9</span>396</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span> Melbourne (C) 20               <span style="text-decoration: underline;">2</span>020      <span style="text-decoration: underline;">38</span>434</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span> Melbourne (C) 25               <span style="text-decoration: underline;">2</span>020      <span style="text-decoration: underline;">38</span>546</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span> Melbourne (C) 30               <span style="text-decoration: underline;">2</span>020      <span style="text-decoration: underline;">25</span>834</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span> Melbourne (C) 35               <span style="text-decoration: underline;">2</span>020      <span style="text-decoration: underline;">15</span>072</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span> Melbourne (C) 40               <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">8</span>554</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span> Melbourne (C) 45               <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">6</span>753</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># … with 26 more rows</span></span></span></code></pre>
</div>
<p>So now we can get this:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggplot.html">ggplot</a></span><span class="o">(</span><span class="nv">melb_syd_pyramid</span>,</span>
<span>         <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/aes.html">aes</a></span><span class="o">(</span>x <span class="o">=</span> <span class="nv">population</span>,</span>
<span>             y <span class="o">=</span> <span class="nv">lower.age.limit</span>,</span>
<span>             fill <span class="o">=</span> <span class="nv">lga</span><span class="o">)</span><span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/geom_bar.html">geom_col</a></span><span class="o">(</span><span class="o">)</span> </span></code></pre>
<p><img src="https://www.njtierney.com/posts/2022-08-09-pyramid-plots-in-ggplot2/figs/beta-version-pyramid-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>And that’s pretty good!</p>
<p>Let’s tidy it up a little bit - we want to change the axis on the bottom to be positive in both directions, so we’ll need to specify the break points for the axis marks, as well as the labels. So we want a sequence from one end to the other, but for it to be symmetric. Let’s start by getting the range, by using the <code>range</code> function:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">pop_range</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/range.html">range</a></span><span class="o">(</span><span class="nv">melb_syd_pyramid</span><span class="o">$</span><span class="nv">population</span><span class="o">)</span></span>
<span><span class="nv">pop_range</span></span><span><span class="c">#&gt; [1] -45686  38546</span></span></code></pre>
</div>
<p>Now we want a sequence from there to the end value. We can use <code>seq</code> to make a sequence</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">pop_range_seq</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/seq.html">seq</a></span><span class="o">(</span><span class="nv">pop_range</span><span class="o">[</span><span class="m">1</span><span class="o">]</span>, <span class="nv">pop_range</span><span class="o">[</span><span class="m">2</span><span class="o">]</span>, by <span class="o">=</span> <span class="m">15000</span><span class="o">)</span></span>
<span><span class="nv">pop_range_seq</span></span><span><span class="c">#&gt; [1] -45686 -30686 -15686   -686  14314  29314</span></span></code></pre>
</div>
<p>Briefly, what we want to do is something like this:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggplot.html">ggplot</a></span><span class="o">(</span><span class="nv">melb_syd_pyramid</span>,</span>
<span>         <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/aes.html">aes</a></span><span class="o">(</span>x <span class="o">=</span> <span class="nv">population</span>,</span>
<span>             y <span class="o">=</span> <span class="nv">lower.age.limit</span>,</span>
<span>             fill <span class="o">=</span> <span class="nv">lga</span><span class="o">)</span><span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/geom_bar.html">geom_col</a></span><span class="o">(</span><span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/scale_continuous.html">scale_x_continuous</a></span><span class="o">(</span>breaks  <span class="o">=</span> <span class="nv">pop_range_seq</span>,</span>
<span>                       labels <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/MathFun.html">abs</a></span><span class="o">(</span><span class="nv">pop_range_seq</span><span class="o">)</span><span class="o">)</span></span></code></pre>
<p><img src="https://www.njtierney.com/posts/2022-08-09-pyramid-plots-in-ggplot2/figs/first-pass-pyramid-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>Ugh, but the numbers aren’t very nice. We want some nicer numbers. We can use a negative number in <code>round</code> to give us something slightly better.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://rdrr.io/r/base/Round.html">round</a></span><span class="o">(</span><span class="nv">pop_range</span>, <span class="o">-</span><span class="m">2</span><span class="o">)</span></span><span><span class="c">#&gt; [1] -45700  38500</span></span></code></pre>
</div>
<p>But I’d like to round to the nearest 500…and we also need to have a 0 in there as well.</p>
</section>
<section id="basepretty" class="level1">
<h1><code>base::pretty()</code></h1>
<p>Turns out this is a pretty common thing to do, and base R has us covered, with <a href="https://rdrr.io/r/base/pretty.html"><code>pretty()</code></a>! It even includes 0!</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://rdrr.io/r/base/pretty.html">pretty</a></span><span class="o">(</span><span class="nv">pop_range</span><span class="o">)</span></span><span><span class="c">#&gt; [1] -60000 -40000 -20000      0  20000  40000</span></span></code></pre>
</div>
<p>There are loads of options, but we’ll just specify <code>n</code> to change the number of breaks</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">pop_range_breaks</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/pretty.html">pretty</a></span><span class="o">(</span><span class="nv">pop_range</span>, n <span class="o">=</span> <span class="m">7</span><span class="o">)</span></span></code></pre>
</div>
<p>So now we have something that looks pretty good</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggplot.html">ggplot</a></span><span class="o">(</span><span class="nv">melb_syd_pyramid</span>,</span>
<span>         <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/aes.html">aes</a></span><span class="o">(</span>x <span class="o">=</span> <span class="nv">population</span>,</span>
<span>             y <span class="o">=</span> <span class="nv">lower.age.limit</span>,</span>
<span>             fill <span class="o">=</span> <span class="nv">lga</span><span class="o">)</span><span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/geom_bar.html">geom_col</a></span><span class="o">(</span><span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/scale_continuous.html">scale_x_continuous</a></span><span class="o">(</span>breaks  <span class="o">=</span> <span class="nv">pop_range_breaks</span>,</span>
<span>                       labels <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/MathFun.html">abs</a></span><span class="o">(</span><span class="nv">pop_range_breaks</span><span class="o">)</span><span class="o">)</span></span></code></pre>
<p><img src="https://www.njtierney.com/posts/2022-08-09-pyramid-plots-in-ggplot2/figs/pretty-good-pyramid-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>OK, but a few more gripes:</p>
<ul>
<li><p>The numbers are a bit hard to read - we can add a comma into them to improve that with <a href="https://scales.r-lib.org/reference/comma.html"><code>scales::comma</code></a></p></li>
<li><p>the legend needs to be on top</p></li>
<li><p>The colour scale should be colourblind friendly</p></li>
</ul>
<section id="scalescomma" class="level2">
<h2 class="anchored" data-anchor-id="scalescomma"><code>scales::comma()</code></h2>
<p>A really cool function! It takes number input and adds commas into them.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf">scales</span><span class="nf">::</span><span class="nf"><a href="https://scales.r-lib.org/reference/comma.html">comma</a></span><span class="o">(</span><span class="m">10</span><span class="o">)</span></span><span><span class="c">#&gt; [1] "10"</span></span><span><span class="nf">scales</span><span class="nf">::</span><span class="nf"><a href="https://scales.r-lib.org/reference/comma.html">comma</a></span><span class="o">(</span><span class="m">100</span><span class="o">)</span></span><span><span class="c">#&gt; [1] "100"</span></span><span><span class="nf">scales</span><span class="nf">::</span><span class="nf"><a href="https://scales.r-lib.org/reference/comma.html">comma</a></span><span class="o">(</span><span class="m">1000</span><span class="o">)</span></span><span><span class="c">#&gt; [1] "1,000"</span></span><span><span class="nf">scales</span><span class="nf">::</span><span class="nf"><a href="https://scales.r-lib.org/reference/comma.html">comma</a></span><span class="o">(</span><span class="m">1000000</span><span class="o">)</span></span><span><span class="c">#&gt; [1] "1,000,000"</span></span></code></pre>
</div>
<p>Let’s add that in, along with the changes to the legend, as well as an improved colour scale</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggplot.html">ggplot</a></span><span class="o">(</span><span class="nv">melb_syd_pyramid</span>,</span>
<span>         <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/aes.html">aes</a></span><span class="o">(</span>x <span class="o">=</span> <span class="nv">population</span>,</span>
<span>             y <span class="o">=</span> <span class="nv">lower.age.limit</span>,</span>
<span>             fill <span class="o">=</span> <span class="nv">lga</span><span class="o">)</span><span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/geom_bar.html">geom_col</a></span><span class="o">(</span><span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/scale_continuous.html">scale_x_continuous</a></span><span class="o">(</span>breaks  <span class="o">=</span> <span class="nv">pop_range_breaks</span>,</span>
<span>                       labels <span class="o">=</span> <span class="nf">scales</span><span class="nf">::</span><span class="nf"><a href="https://scales.r-lib.org/reference/comma.html">comma</a></span><span class="o">(</span><span class="nf"><a href="https://rdrr.io/r/base/MathFun.html">abs</a></span><span class="o">(</span><span class="nv">pop_range_breaks</span><span class="o">)</span><span class="o">)</span><span class="o">)</span> <span class="o">+</span> </span>
<span>  <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/scale_brewer.html">scale_fill_brewer</a></span><span class="o">(</span>palette <span class="o">=</span> <span class="s">"Dark2"</span><span class="o">)</span> <span class="o">+</span></span>
<span>  <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggtheme.html">theme_minimal</a></span><span class="o">(</span><span class="o">)</span> <span class="o">+</span></span>
<span>  <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/theme.html">theme</a></span><span class="o">(</span>legend.position <span class="o">=</span> <span class="s">"top"</span><span class="o">)</span> </span></code></pre>
<p><img src="https://www.njtierney.com/posts/2022-08-09-pyramid-plots-in-ggplot2/figs/improved-pyramid-scale-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
</section>
</section>
<section id="this-doesnt-generalise-to-other-data" class="level1">
<h1>This doesn’t generalise to other data</h1>
<p>Unfortunately, if I want to do this to another dataset, which doesn’t have Sydney and Melbourne, I’ll need to write custom code each time. We can do a little better, let’s write this as a function, which takes two inputs, the name of each of the LGAs we want to explore.</p>
<p>This involves a few steps - first, we need to modify the data as we’ve done above. Let’s call this a <code>prep_pop_pyramid</code> function. First let’s scratch out what it will do.</p>
<p>So we need to get the data.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">melb_syd</span> <span class="o">&lt;-</span> <span class="nf">two_abs_age_lga</span><span class="o">(</span><span class="s">"Melbourne (C)"</span>, <span class="s">"Sydney (C)"</span><span class="o">)</span></span></code></pre>
</div>
<p>Then we need to multiply one of the populations by -1, so that we get the reflected population in the other direction. We had previously done:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">melb_syd</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>    population <span class="o">=</span> <span class="nf"><a href="https://dplyr.tidyverse.org/reference/case_when.html">case_when</a></span><span class="o">(</span></span>
<span>      <span class="nv">lga</span> <span class="o">==</span> <span class="s">"Sydney (C)"</span> <span class="o">~</span> <span class="o">-</span><span class="nv">population</span>,</span>
<span>      <span class="kc">TRUE</span> <span class="o">~</span> <span class="nv">population</span></span>
<span>    <span class="o">)</span></span>
<span>  <span class="o">)</span></span><span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 36 × 4</span></span></span>
<span><span class="c">#&gt;    lga           lower.age.limit  year population</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>                   <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>      <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span> Melbourne (C)               0  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">4</span>882</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span> Melbourne (C)               5  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">3</span>450</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span> Melbourne (C)              10  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">2</span>675</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span> Melbourne (C)              15  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">9</span>396</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span> Melbourne (C)              20  <span style="text-decoration: underline;">2</span>020      <span style="text-decoration: underline;">38</span>434</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span> Melbourne (C)              25  <span style="text-decoration: underline;">2</span>020      <span style="text-decoration: underline;">38</span>546</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span> Melbourne (C)              30  <span style="text-decoration: underline;">2</span>020      <span style="text-decoration: underline;">25</span>834</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span> Melbourne (C)              35  <span style="text-decoration: underline;">2</span>020      <span style="text-decoration: underline;">15</span>072</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span> Melbourne (C)              40  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">8</span>554</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span> Melbourne (C)              45  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">6</span>753</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># … with 26 more rows</span></span></span></code></pre>
</div>
<p>But this will not generalise to <em>any</em> two LGA names. So instead we can assign one of the LGAs to a number, which we can do by first grouping by lga, then using <a href="https://dplyr.tidyverse.org/reference/context.html"><code>cur_group_id()</code></a>, to label the groups as a number.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">melb_syd</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/group_by.html">group_by</a></span><span class="o">(</span><span class="nv">lga</span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span></span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>      age_multiplier <span class="o">=</span> <span class="nf"><a href="https://dplyr.tidyverse.org/reference/context.html">cur_group_id</a></span><span class="o">(</span><span class="o">)</span>,</span>
<span>      .after <span class="o">=</span> <span class="nv">lga</span></span>
<span>    <span class="o">)</span></span><span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 36 × 5</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># Groups:   lga [2]</span></span></span>
<span><span class="c">#&gt;    lga           age_multiplier lower.age.limit  year population</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>                  <span style="color: #555555; font-style: italic;">&lt;int&gt;</span>           <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>      <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span> Melbourne (C)              1               0  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">4</span>882</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span> Melbourne (C)              1               5  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">3</span>450</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span> Melbourne (C)              1              10  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">2</span>675</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span> Melbourne (C)              1              15  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">9</span>396</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span> Melbourne (C)              1              20  <span style="text-decoration: underline;">2</span>020      <span style="text-decoration: underline;">38</span>434</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span> Melbourne (C)              1              25  <span style="text-decoration: underline;">2</span>020      <span style="text-decoration: underline;">38</span>546</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span> Melbourne (C)              1              30  <span style="text-decoration: underline;">2</span>020      <span style="text-decoration: underline;">25</span>834</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span> Melbourne (C)              1              35  <span style="text-decoration: underline;">2</span>020      <span style="text-decoration: underline;">15</span>072</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span> Melbourne (C)              1              40  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">8</span>554</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span> Melbourne (C)              1              45  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">6</span>753</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># … with 26 more rows</span></span></span></code></pre>
</div>
<p>This then gives us a 1 or a 2. We can then set this to be negative if it is the second group.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">melb_syd</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/group_by.html">group_by</a></span><span class="o">(</span><span class="nv">lga</span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span></span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>      age_multiplier <span class="o">=</span> <span class="nf"><a href="https://dplyr.tidyverse.org/reference/context.html">cur_group_id</a></span><span class="o">(</span><span class="o">)</span>,</span>
<span>      age_multiplier <span class="o">=</span> <span class="nf"><a href="https://dplyr.tidyverse.org/reference/case_when.html">case_when</a></span><span class="o">(</span><span class="nv">age_multiplier</span> <span class="o">==</span> <span class="m">2</span> <span class="o">~</span> <span class="m">1</span>,</span>
<span>                                 <span class="kc">TRUE</span> <span class="o">~</span> <span class="o">-</span><span class="m">1</span><span class="o">)</span>,</span>
<span>      .after <span class="o">=</span> <span class="nv">lga</span></span>
<span>    <span class="o">)</span> </span><span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 36 × 5</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># Groups:   lga [2]</span></span></span>
<span><span class="c">#&gt;    lga           age_multiplier lower.age.limit  year population</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>                  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>           <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>      <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>               0  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">4</span>882</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>               5  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">3</span>450</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>              10  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">2</span>675</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>              15  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">9</span>396</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>              20  <span style="text-decoration: underline;">2</span>020      <span style="text-decoration: underline;">38</span>434</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>              25  <span style="text-decoration: underline;">2</span>020      <span style="text-decoration: underline;">38</span>546</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>              30  <span style="text-decoration: underline;">2</span>020      <span style="text-decoration: underline;">25</span>834</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>              35  <span style="text-decoration: underline;">2</span>020      <span style="text-decoration: underline;">15</span>072</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>              40  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">8</span>554</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>              45  <span style="text-decoration: underline;">2</span>020       <span style="text-decoration: underline;">6</span>753</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># … with 26 more rows</span></span></span></code></pre>
</div>
<p>Then, we have something that we can use to multiply the population by -1 ! Let’s also take this chance to turn age into a factor.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">melb_syd</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/group_by.html">group_by</a></span><span class="o">(</span><span class="nv">lga</span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span></span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>      age_multiplier <span class="o">=</span> <span class="nf"><a href="https://dplyr.tidyverse.org/reference/context.html">cur_group_id</a></span><span class="o">(</span><span class="o">)</span>,</span>
<span>      age_multiplier <span class="o">=</span> <span class="nf"><a href="https://dplyr.tidyverse.org/reference/case_when.html">case_when</a></span><span class="o">(</span><span class="nv">age_multiplier</span> <span class="o">==</span> <span class="m">2</span> <span class="o">~</span> <span class="m">1</span>,</span>
<span>                                 <span class="kc">TRUE</span> <span class="o">~</span> <span class="o">-</span><span class="m">1</span><span class="o">)</span>,</span>
<span>      .after <span class="o">=</span> <span class="nv">lga</span></span>
<span>    <span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span></span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/group_by.html">ungroup</a></span><span class="o">(</span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span></span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span>age <span class="o">=</span> <span class="nf"><a href="https://forcats.tidyverse.org/reference/as_factor.html">as_factor</a></span><span class="o">(</span><span class="nv">lower.age.limit</span><span class="o">)</span>,</span>
<span>           population <span class="o">=</span> <span class="nv">population</span> <span class="o">*</span> <span class="nv">age_multiplier</span><span class="o">)</span></span><span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 36 × 6</span></span></span>
<span><span class="c">#&gt;    lga           age_multiplier lower.age.limit  year population age  </span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>                  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>           <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>      <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;fct&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>               0  <span style="text-decoration: underline;">2</span>020      -<span style="color: #BB0000; text-decoration: underline;">4</span><span style="color: #BB0000;">882</span> 0    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>               5  <span style="text-decoration: underline;">2</span>020      -<span style="color: #BB0000; text-decoration: underline;">3</span><span style="color: #BB0000;">450</span> 5    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>              10  <span style="text-decoration: underline;">2</span>020      -<span style="color: #BB0000; text-decoration: underline;">2</span><span style="color: #BB0000;">675</span> 10   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>              15  <span style="text-decoration: underline;">2</span>020      -<span style="color: #BB0000; text-decoration: underline;">9</span><span style="color: #BB0000;">396</span> 15   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>              20  <span style="text-decoration: underline;">2</span>020     -<span style="color: #BB0000; text-decoration: underline;">38</span><span style="color: #BB0000;">434</span> 20   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>              25  <span style="text-decoration: underline;">2</span>020     -<span style="color: #BB0000; text-decoration: underline;">38</span><span style="color: #BB0000;">546</span> 25   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>              30  <span style="text-decoration: underline;">2</span>020     -<span style="color: #BB0000; text-decoration: underline;">25</span><span style="color: #BB0000;">834</span> 30   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>              35  <span style="text-decoration: underline;">2</span>020     -<span style="color: #BB0000; text-decoration: underline;">15</span><span style="color: #BB0000;">072</span> 35   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>              40  <span style="text-decoration: underline;">2</span>020      -<span style="color: #BB0000; text-decoration: underline;">8</span><span style="color: #BB0000;">554</span> 40   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>              45  <span style="text-decoration: underline;">2</span>020      -<span style="color: #BB0000; text-decoration: underline;">6</span><span style="color: #BB0000;">753</span> 45   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># … with 26 more rows</span></span></span></code></pre>
</div>
<p>And then let’s wrap this into a function:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">prep_pop_pyramid</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">data</span><span class="o">)</span><span class="o">{</span></span>
<span>  <span class="nv">data</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/group_by.html">group_by</a></span><span class="o">(</span><span class="nv">lga</span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span></span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>      age_multiplier <span class="o">=</span> <span class="nf"><a href="https://dplyr.tidyverse.org/reference/context.html">cur_group_id</a></span><span class="o">(</span><span class="o">)</span>,</span>
<span>      age_multiplier <span class="o">=</span> <span class="nf"><a href="https://dplyr.tidyverse.org/reference/case_when.html">case_when</a></span><span class="o">(</span><span class="nv">age_multiplier</span> <span class="o">==</span> <span class="m">2</span> <span class="o">~</span> <span class="m">1</span>,</span>
<span>                                 <span class="kc">TRUE</span> <span class="o">~</span> <span class="o">-</span><span class="m">1</span><span class="o">)</span>,</span>
<span>      .after <span class="o">=</span> <span class="nv">lga</span></span>
<span>    <span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span></span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/group_by.html">ungroup</a></span><span class="o">(</span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span></span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span>age <span class="o">=</span> <span class="nf"><a href="https://forcats.tidyverse.org/reference/as_factor.html">as_factor</a></span><span class="o">(</span><span class="nv">lower.age.limit</span><span class="o">)</span>,</span>
<span>           population <span class="o">=</span> <span class="nv">population</span> <span class="o">*</span> <span class="nv">age_multiplier</span><span class="o">)</span></span>
<span><span class="o">}</span></span></code></pre>
</div>
<p>OK so now let’s put those two parts together:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">melb_syd</span> <span class="o">&lt;-</span> <span class="nf">two_abs_age_lga</span><span class="o">(</span></span>
<span>  <span class="s">"Melbourne (C)"</span>,</span>
<span>  <span class="s">"Sydney (C)"</span></span>
<span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf">prep_pop_pyramid</span><span class="o">(</span><span class="o">)</span></span>
<span></span>
<span><span class="nv">melb_syd</span></span><span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 36 × 6</span></span></span>
<span><span class="c">#&gt;    lga           age_multiplier lower.age.limit  year population age  </span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>                  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>           <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>      <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;fct&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>               0  <span style="text-decoration: underline;">2</span>020      -<span style="color: #BB0000; text-decoration: underline;">4</span><span style="color: #BB0000;">882</span> 0    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>               5  <span style="text-decoration: underline;">2</span>020      -<span style="color: #BB0000; text-decoration: underline;">3</span><span style="color: #BB0000;">450</span> 5    </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>              10  <span style="text-decoration: underline;">2</span>020      -<span style="color: #BB0000; text-decoration: underline;">2</span><span style="color: #BB0000;">675</span> 10   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>              15  <span style="text-decoration: underline;">2</span>020      -<span style="color: #BB0000; text-decoration: underline;">9</span><span style="color: #BB0000;">396</span> 15   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>              20  <span style="text-decoration: underline;">2</span>020     -<span style="color: #BB0000; text-decoration: underline;">38</span><span style="color: #BB0000;">434</span> 20   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>              25  <span style="text-decoration: underline;">2</span>020     -<span style="color: #BB0000; text-decoration: underline;">38</span><span style="color: #BB0000;">546</span> 25   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>              30  <span style="text-decoration: underline;">2</span>020     -<span style="color: #BB0000; text-decoration: underline;">25</span><span style="color: #BB0000;">834</span> 30   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>              35  <span style="text-decoration: underline;">2</span>020     -<span style="color: #BB0000; text-decoration: underline;">15</span><span style="color: #BB0000;">072</span> 35   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>              40  <span style="text-decoration: underline;">2</span>020      -<span style="color: #BB0000; text-decoration: underline;">8</span><span style="color: #BB0000;">554</span> 40   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span> Melbourne (C)             -<span style="color: #BB0000;">1</span>              45  <span style="text-decoration: underline;">2</span>020      -<span style="color: #BB0000; text-decoration: underline;">6</span><span style="color: #BB0000;">753</span> 45   </span></span>
<span><span class="c">#&gt; <span style="color: #555555;"># … with 26 more rows</span></span></span></code></pre>
</div>
<p>And now let’s wrap the plotting code into a function:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">plot_pop_pyramid</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">data</span><span class="o">)</span><span class="o">{</span></span>
<span>  <span class="nv">pop_range</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/range.html">range</a></span><span class="o">(</span><span class="nv">data</span><span class="o">$</span><span class="nv">population</span><span class="o">)</span></span>
<span>  </span>
<span>  <span class="nv">age_range_seq</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/pretty.html">pretty</a></span><span class="o">(</span><span class="nv">pop_range</span>, n <span class="o">=</span> <span class="m">10</span><span class="o">)</span></span>
<span>  </span>
<span>  <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggplot.html">ggplot</a></span><span class="o">(</span><span class="nv">data</span>,</span>
<span>         <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/aes.html">aes</a></span><span class="o">(</span>x <span class="o">=</span> <span class="nv">population</span>,</span>
<span>             y <span class="o">=</span> <span class="nv">age</span>,</span>
<span>             fill <span class="o">=</span> <span class="nv">lga</span><span class="o">)</span><span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/geom_bar.html">geom_col</a></span><span class="o">(</span><span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/scale_continuous.html">scale_x_continuous</a></span><span class="o">(</span>breaks  <span class="o">=</span> <span class="nv">age_range_seq</span>,</span>
<span>                       labels <span class="o">=</span> <span class="nf">scales</span><span class="nf">::</span><span class="nf"><a href="https://scales.r-lib.org/reference/comma.html">comma</a></span><span class="o">(</span><span class="nf"><a href="https://rdrr.io/r/base/MathFun.html">abs</a></span><span class="o">(</span><span class="nv">age_range_seq</span><span class="o">)</span><span class="o">)</span><span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/scale_brewer.html">scale_fill_brewer</a></span><span class="o">(</span>palette <span class="o">=</span> <span class="s">"Dark2"</span>,</span>
<span>                      guide <span class="o">=</span> <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/guide_legend.html">guide_legend</a></span><span class="o">(</span></span>
<span>                        title <span class="o">=</span> <span class="s">""</span></span>
<span>                      <span class="o">)</span><span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggtheme.html">theme_minimal</a></span><span class="o">(</span><span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/theme.html">theme</a></span><span class="o">(</span>legend.position <span class="o">=</span> <span class="s">"top"</span><span class="o">)</span></span>
<span><span class="o">}</span></span></code></pre>
</div>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf">plot_pop_pyramid</span><span class="o">(</span><span class="nv">melb_syd</span><span class="o">)</span></span></code></pre>
<p><img src="https://www.njtierney.com/posts/2022-08-09-pyramid-plots-in-ggplot2/figs/show-pop-pyramid-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
</section>
<section id="end" class="level1">
<h1>End</h1>
<p>And that was the end of this blog post. But something about the plots kind of bothered me…</p>
</section>
<section id="bonus---centering" class="level1">
<h1>Bonus - centering</h1>
<p>Well, there’s actually one final step here that you might be interested in - which is centering the “0” of the population. Perhaps there is another way around this, but the approach that I ended up doing was the following:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">pretty_symmetric</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">range</span>, <span class="nv">n</span> <span class="o">=</span> <span class="m">5</span><span class="o">)</span><span class="o">{</span></span>
<span>  <span class="nv">range_1</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span><span class="o">-</span><span class="nv">range</span><span class="o">[</span><span class="m">1</span><span class="o">]</span>, <span class="nv">range</span><span class="o">[</span><span class="m">2</span><span class="o">]</span><span class="o">)</span></span>
<span>  <span class="nv">range_2</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span><span class="nv">range</span><span class="o">[</span><span class="m">1</span><span class="o">]</span>, <span class="o">-</span><span class="nv">range</span><span class="o">[</span><span class="m">2</span><span class="o">]</span><span class="o">)</span></span>
<span>  </span>
<span>  <span class="nv">pretty_vec_1</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/pretty.html">pretty</a></span><span class="o">(</span><span class="nv">range_1</span><span class="o">)</span></span>
<span>  <span class="nv">pretty_vec_2</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/pretty.html">pretty</a></span><span class="o">(</span><span class="nv">range_2</span><span class="o">)</span></span>
<span>  </span>
<span>  <span class="nf"><a href="https://rdrr.io/r/base/pretty.html">pretty</a></span><span class="o">(</span></span>
<span>    <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span><span class="nv">pretty_vec_1</span>, <span class="nv">pretty_vec_2</span><span class="o">)</span>, </span>
<span>    n <span class="o">=</span> <span class="nv">n</span></span>
<span>  <span class="o">)</span></span>
<span>  </span>
<span><span class="o">}</span></span>
<span></span>
<span><span class="nf">pretty_symmetric</span><span class="o">(</span><span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span><span class="o">-</span><span class="m">5000</span>, <span class="m">10000</span><span class="o">)</span><span class="o">)</span></span><span><span class="c">#&gt; [1] -10000  -5000      0   5000  10000</span></span></code></pre>
</div>
<p>So then we replace <code>pretty</code>, with <code>pretty_symmetric</code> , and then need to add this other bit, <code>expand_limits</code> which ensures the limits are kept</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">plot_pop_pyramid</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">data</span><span class="o">)</span><span class="o">{</span></span>
<span>  <span class="nv">pop_range</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/range.html">range</a></span><span class="o">(</span><span class="nv">data</span><span class="o">$</span><span class="nv">population</span><span class="o">)</span></span>
<span>  </span>
<span>  <span class="nv">age_range_seq</span> <span class="o">&lt;-</span> <span class="nf">pretty_symmetric</span><span class="o">(</span><span class="nv">pop_range</span>, n <span class="o">=</span> <span class="m">5</span><span class="o">)</span></span>
<span>  </span>
<span>  <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggplot.html">ggplot</a></span><span class="o">(</span><span class="nv">data</span>,</span>
<span>         <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/aes.html">aes</a></span><span class="o">(</span>x <span class="o">=</span> <span class="nv">population</span>,</span>
<span>             y <span class="o">=</span> <span class="nv">age</span>,</span>
<span>             fill <span class="o">=</span> <span class="nv">lga</span><span class="o">)</span><span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/geom_bar.html">geom_col</a></span><span class="o">(</span><span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/scale_continuous.html">scale_x_continuous</a></span><span class="o">(</span>breaks  <span class="o">=</span> <span class="nv">age_range_seq</span>,</span>
<span>                       labels <span class="o">=</span> <span class="nf">scales</span><span class="nf">::</span><span class="nf"><a href="https://scales.r-lib.org/reference/comma.html">comma</a></span><span class="o">(</span><span class="nf"><a href="https://rdrr.io/r/base/MathFun.html">abs</a></span><span class="o">(</span><span class="nv">age_range_seq</span><span class="o">)</span><span class="o">)</span><span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/expand_limits.html">expand_limits</a></span><span class="o">(</span>x <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/range.html">range</a></span><span class="o">(</span><span class="nv">age_range_seq</span><span class="o">)</span><span class="o">)</span> <span class="o">+</span> </span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/scale_brewer.html">scale_fill_brewer</a></span><span class="o">(</span>palette <span class="o">=</span> <span class="s">"Dark2"</span>,</span>
<span>                      guide <span class="o">=</span> <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/guide_legend.html">guide_legend</a></span><span class="o">(</span></span>
<span>                        title <span class="o">=</span> <span class="s">""</span></span>
<span>                      <span class="o">)</span><span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggtheme.html">theme_minimal</a></span><span class="o">(</span><span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/theme.html">theme</a></span><span class="o">(</span>legend.position <span class="o">=</span> <span class="s">"top"</span><span class="o">)</span></span>
<span><span class="o">}</span></span></code></pre>
</div>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nf">plot_pop_pyramid</span><span class="o">(</span><span class="nv">melb_syd</span><span class="o">)</span></span></code></pre>
<p><img src="https://www.njtierney.com/posts/2022-08-09-pyramid-plots-in-ggplot2/figs/init-pyramid-demo-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>This has a nice benefit of facilitating stacking the plots with something like <code>patchwork</code> and the 0s will be aligned.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">melb_syd</span> <span class="o">&lt;-</span> <span class="nf">two_abs_age_lga</span><span class="o">(</span></span>
<span>  <span class="s">"Melbourne (C)"</span>,</span>
<span>  <span class="s">"Sydney (C)"</span></span>
<span><span class="o">)</span> </span>
<span></span>
<span><span class="nv">bris_hobart</span> <span class="o">&lt;-</span> <span class="nf">two_abs_age_lga</span><span class="o">(</span></span>
<span>  <span class="s">"Brisbane (C)"</span>,</span>
<span>  <span class="s">"Hobart (C)"</span></span>
<span><span class="o">)</span></span>
<span><span class="nv">alice_perth</span> <span class="o">&lt;-</span> <span class="nf">two_abs_age_lga</span><span class="o">(</span></span>
<span>  <span class="s">"Alice Springs (T)"</span>,</span>
<span>  <span class="s">"Perth (C)"</span></span>
<span><span class="o">)</span> </span></code></pre>
</div>
<p>Then we can stack them together with patchwork</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://patchwork.data-imaginist.com">patchwork</a></span><span class="o">)</span></span>
<span><span class="nv">melb_syd</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> <span class="nf">prep_pop_pyramid</span><span class="o">(</span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> <span class="nf">plot_pop_pyramid</span><span class="o">(</span><span class="o">)</span> <span class="o">/</span></span>
<span><span class="nv">bris_hobart</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> <span class="nf">prep_pop_pyramid</span><span class="o">(</span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> <span class="nf">plot_pop_pyramid</span><span class="o">(</span><span class="o">)</span> <span class="o">/</span></span>
<span><span class="nv">alice_perth</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> <span class="nf">prep_pop_pyramid</span><span class="o">(</span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> <span class="nf">plot_pop_pyramid</span><span class="o">(</span><span class="o">)</span></span></code></pre>
<p><img src="https://www.njtierney.com/posts/2022-08-09-pyramid-plots-in-ggplot2/figs/patchwork-plot-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
</section>
<section id="bonus-bonus---per-capita" class="level1">
<h1>Bonus Bonus - per capita</h1>
<p>Ugh. OK. These plots are nice, but really, these should be normalised by the total population.</p>
<p>What does that mean? Why would we want to do that? Well, if you have two cities, one with HEAPS of people, and other with 1000 times less people - the numbers are going to be harder to compare. And if the point you are trying to convey is:</p>
<blockquote class="blockquote">
<p>Hey, these two cities have very different population <em>sizes</em></p>
</blockquote>
<p>Then we’ve done that above.</p>
<p>But what we actually kind of care about the most is:</p>
<blockquote class="blockquote">
<p>Hey, do these two cities have similar age distributions?</p>
</blockquote>
<p>So like, do they have the same proportion of 20-somethings in both cities? Regardless of the fact that one city has like 100 or 1000 times more people?</p>
<p>So, we should fix it.</p>
<p>Where do we fix it? We need to change the data creation function. Adding a new column, <code>population_per_capita</code>, with something like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" 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;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">population_per_capita =</span> population <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;">sum</span>(population))</span></code></pre></div></div>
<p>Which divides the population by the total population. This is sometimes called “normalising”. Effectively, we are comparing each age population to the total population.</p>
<p>Also importantly, we need to do this still in the <code>group_by(lga)</code> below</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">prep_pop_pyramid</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">data</span><span class="o">)</span> <span class="o">{</span></span>
<span>  <span class="nv">data</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span></span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/group_by.html">group_by</a></span><span class="o">(</span><span class="nv">lga</span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span></span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>      age_multiplier <span class="o">=</span> <span class="nf"><a href="https://dplyr.tidyverse.org/reference/context.html">cur_group_id</a></span><span class="o">(</span><span class="o">)</span>,</span>
<span>      age_multiplier <span class="o">=</span> <span class="nf"><a href="https://dplyr.tidyverse.org/reference/case_when.html">case_when</a></span><span class="o">(</span></span>
<span>        <span class="nv">age_multiplier</span> <span class="o">==</span> <span class="m">2</span> <span class="o">~</span> <span class="m">1</span>,</span>
<span>        <span class="kc">TRUE</span> <span class="o">~</span> <span class="o">-</span><span class="m">1</span></span>
<span>      <span class="o">)</span>,</span>
<span>      .after <span class="o">=</span> <span class="nv">lga</span></span>
<span>    <span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span></span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span>population_per_capita <span class="o">=</span> <span class="nv">population</span> <span class="o">/</span> <span class="nf"><a href="https://rdrr.io/r/base/sum.html">sum</a></span><span class="o">(</span><span class="nv">population</span><span class="o">)</span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span></span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/group_by.html">ungroup</a></span><span class="o">(</span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span></span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>      age <span class="o">=</span> <span class="nf"><a href="https://forcats.tidyverse.org/reference/as_factor.html">as_factor</a></span><span class="o">(</span><span class="nv">lower.age.limit</span><span class="o">)</span>,</span>
<span>      population <span class="o">=</span> <span class="nv">population</span> <span class="o">*</span> <span class="nv">age_multiplier</span>,</span>
<span>      population_per_capita <span class="o">=</span> <span class="nv">population_per_capita</span> <span class="o">*</span> <span class="nv">age_multiplier</span></span>
<span>    <span class="o">)</span></span>
<span><span class="o">}</span></span></code></pre>
</div>
<p>And since we’ve changed the data that we are using now - we aren’t using <code>population</code> anymore, and I hard coded the plotting code, we need to re-write the function. Perhaps with the benefit of hindsight it would have been better to not hard code variables in the plotting function, but here we are.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">plot_pop_pyramid_per_capita</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">data</span><span class="o">)</span> <span class="o">{</span></span>
<span>  <span class="nv">pop_range</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/range.html">range</a></span><span class="o">(</span><span class="nv">data</span><span class="o">$</span><span class="nv">population_per_capita</span><span class="o">)</span></span>
<span></span>
<span>  <span class="nv">age_range_seq</span> <span class="o">&lt;-</span> <span class="nf">pretty_symmetric</span><span class="o">(</span><span class="nv">pop_range</span>, n <span class="o">=</span> <span class="m">5</span><span class="o">)</span></span>
<span></span>
<span>  <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggplot.html">ggplot</a></span><span class="o">(</span></span>
<span>    <span class="nv">data</span>,</span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/aes.html">aes</a></span><span class="o">(</span></span>
<span>      x <span class="o">=</span> <span class="nv">population_per_capita</span>,</span>
<span>      y <span class="o">=</span> <span class="nv">age</span>,</span>
<span>      fill <span class="o">=</span> <span class="nv">lga</span></span>
<span>    <span class="o">)</span></span>
<span>  <span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/geom_bar.html">geom_col</a></span><span class="o">(</span><span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/scale_continuous.html">scale_x_continuous</a></span><span class="o">(</span></span>
<span>      breaks <span class="o">=</span> <span class="nv">age_range_seq</span>,</span>
<span>      labels <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/MathFun.html">abs</a></span><span class="o">(</span><span class="nv">age_range_seq</span><span class="o">)</span></span>
<span>    <span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/expand_limits.html">expand_limits</a></span><span class="o">(</span>x <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/range.html">range</a></span><span class="o">(</span><span class="nv">age_range_seq</span><span class="o">)</span><span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/scale_brewer.html">scale_fill_brewer</a></span><span class="o">(</span></span>
<span>      palette <span class="o">=</span> <span class="s">"Dark2"</span>,</span>
<span>      guide <span class="o">=</span> <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/guide_legend.html">guide_legend</a></span><span class="o">(</span></span>
<span>        title <span class="o">=</span> <span class="s">""</span></span>
<span>      <span class="o">)</span></span>
<span>    <span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggtheme.html">theme_minimal</a></span><span class="o">(</span><span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/theme.html">theme</a></span><span class="o">(</span>legend.position <span class="o">=</span> <span class="s">"top"</span><span class="o">)</span></span>
<span><span class="o">}</span></span></code></pre>
</div>
<p>All together now</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">melb_syd</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> <span class="nf">prep_pop_pyramid</span><span class="o">(</span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> <span class="nf">plot_pop_pyramid_per_capita</span><span class="o">(</span><span class="o">)</span> <span class="o">/</span></span>
<span><span class="nv">bris_hobart</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> <span class="nf">prep_pop_pyramid</span><span class="o">(</span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> <span class="nf">plot_pop_pyramid_per_capita</span><span class="o">(</span><span class="o">)</span> <span class="o">/</span></span>
<span><span class="nv">alice_perth</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> <span class="nf">prep_pop_pyramid</span><span class="o">(</span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> <span class="nf">plot_pop_pyramid_per_capita</span><span class="o">(</span><span class="o">)</span></span></code></pre>
<p><img src="https://www.njtierney.com/posts/2022-08-09-pyramid-plots-in-ggplot2/figs/patchwork-plot-per-capita-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>And now for comparison to drive home the difference between the per capita pyramid and the raw population pyramid - most notably, there is a huge difference between brisbane and hobart - previously the population numbers in Brisbane drowned out the differnces in Hobart</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">bris_hobart_pyramid</span> <span class="o">&lt;-</span> <span class="nv">bris_hobart</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> <span class="nf">prep_pop_pyramid</span><span class="o">(</span><span class="o">)</span></span>
<span><span class="nf">plot_pop_pyramid</span><span class="o">(</span><span class="nv">bris_hobart_pyramid</span><span class="o">)</span> <span class="o">/</span></span>
<span>  <span class="nf">plot_pop_pyramid_per_capita</span><span class="o">(</span><span class="nv">bris_hobart_pyramid</span><span class="o">)</span></span></code></pre>
<p><img src="https://www.njtierney.com/posts/2022-08-09-pyramid-plots-in-ggplot2/figs/patchwork-plot-per-capita-brisbane-hobart-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>Another way to present this is as a regular bar graph, which more strongly places our focus on comparison between age groups.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">bris_hobart_pyramid</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>    <span class="c"># reverse age_multiplier</span></span>
<span>    population <span class="o">=</span> <span class="nf"><a href="https://dplyr.tidyverse.org/reference/case_when.html">case_when</a></span><span class="o">(</span></span>
<span>      <span class="nv">age_multiplier</span> <span class="o">==</span> <span class="o">-</span><span class="m">1</span> <span class="o">~</span> <span class="nv">population</span> <span class="o">*</span> <span class="o">-</span><span class="m">1</span>,</span>
<span>      <span class="kc">TRUE</span> <span class="o">~</span> <span class="nv">population</span></span>
<span>    <span class="o">)</span>,</span>
<span>    population_per_capita <span class="o">=</span> <span class="nf"><a href="https://dplyr.tidyverse.org/reference/case_when.html">case_when</a></span><span class="o">(</span></span>
<span>      <span class="nv">age_multiplier</span> <span class="o">==</span> <span class="o">-</span><span class="m">1</span> <span class="o">~</span> <span class="nv">population_per_capita</span> <span class="o">*</span> <span class="o">-</span><span class="m">1</span>,</span>
<span>      <span class="kc">TRUE</span> <span class="o">~</span> <span class="nv">population_per_capita</span></span>
<span>    <span class="o">)</span></span>
<span>  <span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://tidyr.tidyverse.org/reference/pivot_longer.html">pivot_longer</a></span><span class="o">(</span></span>
<span>    cols <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span><span class="nv">population</span>,</span>
<span>             <span class="nv">population_per_capita</span><span class="o">)</span>,</span>
<span>    names_to <span class="o">=</span> <span class="s">"pop_type"</span>,</span>
<span>    values_to <span class="o">=</span> <span class="s">"pop_value"</span></span>
<span>  <span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggplot.html">ggplot</a></span><span class="o">(</span><span class="nf"><a href="https://ggplot2.tidyverse.org/reference/aes.html">aes</a></span><span class="o">(</span>x <span class="o">=</span> <span class="nv">age</span>,</span>
<span>             y <span class="o">=</span> <span class="nv">pop_value</span>,</span>
<span>             fill <span class="o">=</span> <span class="nv">lga</span><span class="o">)</span><span class="o">)</span> <span class="o">+</span> </span>
<span>  <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/geom_bar.html">geom_col</a></span><span class="o">(</span>position <span class="o">=</span> <span class="s">"dodge"</span><span class="o">)</span> <span class="o">+</span></span>
<span>  <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/facet_wrap.html">facet_wrap</a></span><span class="o">(</span><span class="o">~</span><span class="nv">pop_type</span>,</span>
<span>             scales <span class="o">=</span> <span class="s">"free_y"</span>,</span>
<span>             ncol <span class="o">=</span> <span class="m">1</span><span class="o">)</span> <span class="o">+</span> </span>
<span>  <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/scale_brewer.html">scale_fill_brewer</a></span><span class="o">(</span></span>
<span>      palette <span class="o">=</span> <span class="s">"Dark2"</span>,</span>
<span>      guide <span class="o">=</span> <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/guide_legend.html">guide_legend</a></span><span class="o">(</span></span>
<span>        title <span class="o">=</span> <span class="s">""</span></span>
<span>      <span class="o">)</span></span>
<span>    <span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggtheme.html">theme_minimal</a></span><span class="o">(</span><span class="o">)</span> <span class="o">+</span></span>
<span>    <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/theme.html">theme</a></span><span class="o">(</span>legend.position <span class="o">=</span> <span class="s">"top"</span><span class="o">)</span></span></code></pre>
<p><img src="https://www.njtierney.com/posts/2022-08-09-pyramid-plots-in-ggplot2/figs/plot-per-capita-brisbane-hobart-bar-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>In some ways, I think I prefer this graph - there are many ways to present information, and in this case it helps us more clearly compare the differences between two places. It also strongly highlights the difference between using per capita and raw population values.</p>
</section>
<section id="ps" class="level1">
<h1>PS</h1>
<p>I actually wrote this up initially to make a figure for a grant. Then, unhappy with the fact that I had to alter the code 2 times to make the figure, I converted it into a targets pipeline, which you can see here on github: <a href="https://github.com/njtierney/target-pop-pyramid" class="uri">https://github.com/njtierney/target-pop-pyramid</a></p>
<p>Also fun fact, the figure didn’t make it into the grant. But now you’ve got this blog post, so that’s pretty neat, I guess?</p>


</section>

 ]]></description>
  <category>data visualisation</category>
  <category>covid19</category>
  <category>ggplot2</category>
  <category>colour palette</category>
  <category>rstats</category>
  <guid>https://www.njtierney.com/posts/2022-08-09-pyramid-plots-in-ggplot2/</guid>
  <pubDate>Tue, 09 Aug 2022 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Using across() to create multiple columns</title>
  <link>https://www.njtierney.com/posts/2022-08-08-fun-across/</link>
  <description><![CDATA[ 
<header class="site-header">
  <h1 class="site-title">
    <a href="../../">
      <img class="hvr-grow site-logo" src="https://www.njtierney.com/assets/njt-logo-small.png" alt="Nick logo">
    </a>
    <span class="hvr-bob site-title-credibly">Credibly</span>
    <span class="hvr-hang site-title-curious">Curious</span>
  </h1>
  <p class="site-subtitle">
    Nick Tierney's (mostly) rstats blog
  </p>
  
</header>




<div class="highlight">
<p><img src="https://www.njtierney.com/posts/2022-08-08-fun-across/imgs/across-birds-small.jpg" width="700px" style="display: block; margin: auto;"></p>
</div>
<p><em>pigeons across the drain, Nick Tierney, film, olympus XA</em></p>
<p>A colleague of mine the other day had a question along the lines of:</p>
<blockquote class="blockquote">
<p>How do I add multiple columns that give the ranks of values in corresponding columns</p>
</blockquote>
<p>And I ended up cooking up a really fun example of using <code>across</code> from <code>dplyr</code>. I thought it would be fun to share!</p>
<p>Let’s give a little more detail.</p>
<p>Load up the tidyverse.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://tidyverse.tidyverse.org">tidyverse</a></span><span class="o">)</span></span><span><span class="c">#&gt; ── <span style="font-weight: bold;">Attaching packages</span> ───────────────────────────── tidyverse 1.3.1 ──</span></span><span><span class="c">#&gt; <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">ggplot2</span> 3.3.6     <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">purrr  </span> 0.3.4</span></span>
<span><span class="c">#&gt; <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">tibble </span> 3.1.7     <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">dplyr  </span> 1.0.9</span></span>
<span><span class="c">#&gt; <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">tidyr  </span> 1.2.0     <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">stringr</span> 1.4.0</span></span>
<span><span class="c">#&gt; <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">readr  </span> 2.1.2     <span style="color: #00BB00;">✔</span> <span style="color: #0000BB;">forcats</span> 0.5.1</span></span><span><span class="c">#&gt; ── <span style="font-weight: bold;">Conflicts</span> ──────────────────────────────── tidyverse_conflicts() ──</span></span>
<span><span class="c">#&gt; <span style="color: #BB0000;">✖</span> <span style="color: #0000BB;">dplyr</span>::<span style="color: #00BB00;">filter()</span> masks <span style="color: #0000BB;">stats</span>::filter()</span></span>
<span><span class="c">#&gt; <span style="color: #BB0000;">✖</span> <span style="color: #0000BB;">dplyr</span>::<span style="color: #00BB00;">lag()</span>    masks <span style="color: #0000BB;">stats</span>::lag()</span></span></code></pre>
</div>
<p>The data they had referred to concentrations of a quantity, that they wanted to rank. We can create these like so:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">dat</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://tibble.tidyverse.org/reference/tibble.html">tibble</a></span><span class="o">(</span></span>
<span>  x_1 <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/stats/Uniform.html">runif</a></span><span class="o">(</span><span class="m">10</span><span class="o">)</span>,</span>
<span>  x_2 <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/stats/Uniform.html">runif</a></span><span class="o">(</span><span class="m">10</span><span class="o">)</span>,</span>
<span>  x_3 <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/stats/Uniform.html">runif</a></span><span class="o">(</span><span class="m">10</span><span class="o">)</span></span>
<span><span class="o">)</span></span>
<span></span>
<span><span class="nv">dat</span></span><span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 10 × 3</span></span></span>
<span><span class="c">#&gt;       x_1   x_2   x_3</span></span>
<span><span class="c">#&gt;     <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span> 0.071<span style="text-decoration: underline;">2</span> 0.784 0.875</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span> 0.295  0.734 0.185</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span> 0.385  0.844 0.690</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span> 0.648  0.480 0.807</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span> 0.272  0.323 0.868</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span> 0.554  0.590 0.859</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span> 0.421  0.270 0.433</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span> 0.724  0.732 0.870</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span> 0.654  0.973 0.606</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span> 0.159  0.782 0.720</span></span></code></pre>
</div>
<p>Or for fun, I did this:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">vals</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/stats/Uniform.html">runif</a></span><span class="o">(</span><span class="m">30</span><span class="o">)</span></span>
<span></span>
<span><span class="nv">dat</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://tibble.tidyverse.org/reference/as_tibble.html">as_tibble</a></span><span class="o">(</span></span>
<span>  x <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/matrix.html">matrix</a></span><span class="o">(</span><span class="nv">vals</span>, nrow <span class="o">=</span> <span class="m">10</span><span class="o">)</span>,</span>
<span>  .name_repair <span class="o">=</span> <span class="nf">janitor</span><span class="nf">::</span><span class="nv"><a href="https://rdrr.io/pkg/janitor/man/make_clean_names.html">make_clean_names</a></span></span>
<span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span></span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/rename.html">rename</a></span><span class="o">(</span></span>
<span>    x_1 <span class="o">=</span> <span class="nv">x</span></span>
<span>  <span class="o">)</span></span>
<span></span>
<span><span class="nv">dat</span></span><span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 10 × 3</span></span></span>
<span><span class="c">#&gt;       x_1    x_2   x_3</span></span>
<span><span class="c">#&gt;     <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span> 0.927  0.661  0.454</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span> 0.792  0.098<span style="text-decoration: underline;">9</span> 0.970</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span> 0.346  0.054<span style="text-decoration: underline;">4</span> 0.278</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span> 0.634  0.989  0.360</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span> 0.060<span style="text-decoration: underline;">5</span> 0.741  0.675</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span> 0.373  0.729  0.581</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span> 0.035<span style="text-decoration: underline;">9</span> 0.429  0.151</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span> 0.819  0.277  0.436</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span> 0.242  0.308  0.452</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span> 0.065<span style="text-decoration: underline;">4</span> 0.292  0.620</span></span></code></pre>
</div>
<blockquote class="blockquote">
<p>An aside: prefer <code>dat</code> over <code>df</code>. I’ve been burned recently by using <code>df</code> as my go-to name for data frames, but it turns out that <code>df</code> is actually a function in R, for calculating the density of an F distribution. Which is awesome, but sometimes leads to funny errors that you might not expect.</p>
</blockquote>
<p>OK, so what my friend wanted was something like this:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">dat</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span>  </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>    x_1_rank <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/rank.html">rank</a></span><span class="o">(</span><span class="nv">x_1</span><span class="o">)</span>,</span>
<span>    x_2_rank <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/rank.html">rank</a></span><span class="o">(</span><span class="nv">x_2</span><span class="o">)</span>,</span>
<span>    x_3_rank <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/rank.html">rank</a></span><span class="o">(</span><span class="nv">x_3</span><span class="o">)</span></span>
<span>  <span class="o">)</span></span><span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 10 × 6</span></span></span>
<span><span class="c">#&gt;       x_1    x_2   x_3 x_1_rank x_2_rank x_3_rank</span></span>
<span><span class="c">#&gt;     <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span> 0.927  0.661  0.454       10        7        6</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span> 0.792  0.098<span style="text-decoration: underline;">9</span> 0.970        8        2       10</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span> 0.346  0.054<span style="text-decoration: underline;">4</span> 0.278        5        1        2</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span> 0.634  0.989  0.360        7       10        3</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span> 0.060<span style="text-decoration: underline;">5</span> 0.741  0.675        2        9        9</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span> 0.373  0.729  0.581        6        8        7</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span> 0.035<span style="text-decoration: underline;">9</span> 0.429  0.151        1        6        1</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span> 0.819  0.277  0.436        9        3        4</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span> 0.242  0.308  0.452        4        5        5</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span> 0.065<span style="text-decoration: underline;">4</span> 0.292  0.620        3        4        8</span></span></code></pre>
</div>
<p>Now, that’s relatively easy. But they actually have a lot of these concentration columns - sometimes just 10, other times many times that number.</p>
<p>The reason you might want to avoid writing this out each time is because it will involve a lot of reptition, where you might accidentally copy something twice or not increment the numbers. E.g.,</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">dat</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span>  </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>    x_1_rank <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/rank.html">rank</a></span><span class="o">(</span><span class="nv">x_1</span><span class="o">)</span>,</span>
<span>    x_2_rank <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/rank.html">rank</a></span><span class="o">(</span><span class="nv">x_2</span><span class="o">)</span>,</span>
<span>    x_3_rank <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/rank.html">rank</a></span><span class="o">(</span><span class="nv">x_2</span><span class="o">)</span></span>
<span>  <span class="o">)</span></span><span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 10 × 6</span></span></span>
<span><span class="c">#&gt;       x_1    x_2   x_3 x_1_rank x_2_rank x_3_rank</span></span>
<span><span class="c">#&gt;     <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span> 0.927  0.661  0.454       10        7        7</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span> 0.792  0.098<span style="text-decoration: underline;">9</span> 0.970        8        2        2</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span> 0.346  0.054<span style="text-decoration: underline;">4</span> 0.278        5        1        1</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span> 0.634  0.989  0.360        7       10       10</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span> 0.060<span style="text-decoration: underline;">5</span> 0.741  0.675        2        9        9</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span> 0.373  0.729  0.581        6        8        8</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span> 0.035<span style="text-decoration: underline;">9</span> 0.429  0.151        1        6        6</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span> 0.819  0.277  0.436        9        3        3</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span> 0.242  0.308  0.452        4        5        5</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span> 0.065<span style="text-decoration: underline;">4</span> 0.292  0.620        3        4        4</span></span></code></pre>
</div>
<p>See the error? <code>x_3_rank</code> is actually from <code>rank(x_2)</code></p>
<p>So the question is, can you generalise this type of column creation?</p>
<p>Yes! Yes we can. With <code>across</code>. It looks like this.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">dat</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/across.html">across</a></span><span class="o">(</span></span>
<span>      .cols <span class="o">=</span> <span class="nf"><a href="https://tidyselect.r-lib.org/reference/everything.html">everything</a></span><span class="o">(</span><span class="o">)</span>,</span>
<span>      .fns <span class="o">=</span> <span class="nv">rank</span></span>
<span>    <span class="o">)</span></span>
<span>  <span class="o">)</span></span><span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 10 × 3</span></span></span>
<span><span class="c">#&gt;      x_1   x_2   x_3</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>    10     7     6</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>     8     2    10</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>     5     1     2</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>     7    10     3</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>     2     9     9</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>     6     8     7</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>     1     6     1</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>     9     3     4</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>     4     5     5</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>     3     4     8</span></span></code></pre>
</div>
<p>This says:</p>
<blockquote class="blockquote">
<p>mutate across all columns, and use the function, <code>rank</code>, on each one.</p>
</blockquote>
<p>Uh, but we want the other columns preserved…how do we do that?</p>
<p>With <code>.names</code> - we specify a special pattern on how we want to name the columns with <code>.names = "{.col}_rank"</code>, which says: “call it the name of the column, and then add”_rank” to it.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">dat</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/across.html">across</a></span><span class="o">(</span></span>
<span>      .cols <span class="o">=</span> <span class="nf"><a href="https://tidyselect.r-lib.org/reference/everything.html">everything</a></span><span class="o">(</span><span class="o">)</span>,</span>
<span>      .fns <span class="o">=</span> <span class="nv">rank</span>,</span>
<span>      .names <span class="o">=</span> <span class="s">"{.col}_rank"</span></span>
<span>    <span class="o">)</span></span>
<span>  <span class="o">)</span></span><span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 10 × 6</span></span></span>
<span><span class="c">#&gt;       x_1    x_2   x_3 x_1_rank x_2_rank x_3_rank</span></span>
<span><span class="c">#&gt;     <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span> 0.927  0.661  0.454       10        7        6</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span> 0.792  0.098<span style="text-decoration: underline;">9</span> 0.970        8        2       10</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span> 0.346  0.054<span style="text-decoration: underline;">4</span> 0.278        5        1        2</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span> 0.634  0.989  0.360        7       10        3</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span> 0.060<span style="text-decoration: underline;">5</span> 0.741  0.675        2        9        9</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span> 0.373  0.729  0.581        6        8        7</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span> 0.035<span style="text-decoration: underline;">9</span> 0.429  0.151        1        6        1</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span> 0.819  0.277  0.436        9        3        4</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span> 0.242  0.308  0.452        4        5        5</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span> 0.065<span style="text-decoration: underline;">4</span> 0.292  0.620        3        4        8</span></span></code></pre>
</div>
<p>OK, but what if we’ve got data that contains other columns we don’t want to apply <code>rank</code> to - say, some data that looks like this:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">dat_more</span> <span class="o">&lt;-</span> <span class="nv">dat</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://tibble.tidyverse.org/reference/rownames.html">rowid_to_column</a></span><span class="o">(</span>var <span class="o">=</span> <span class="s">"id"</span><span class="o">)</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span>code <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/sample.html">sample</a></span><span class="o">(</span><span class="nv">LETTERS</span>, <span class="nf"><a href="https://dplyr.tidyverse.org/reference/context.html">n</a></span><span class="o">(</span><span class="o">)</span><span class="o">)</span>,</span>
<span>         .after <span class="o">=</span> <span class="nv">id</span><span class="o">)</span></span>
<span></span>
<span><span class="nv">dat_more</span></span><span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 10 × 5</span></span></span>
<span><span class="c">#&gt;       id code     x_1    x_2   x_3</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>     1 Q     0.927  0.661  0.454</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>     2 R     0.792  0.098<span style="text-decoration: underline;">9</span> 0.970</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>     3 Y     0.346  0.054<span style="text-decoration: underline;">4</span> 0.278</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>     4 B     0.634  0.989  0.360</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>     5 T     0.060<span style="text-decoration: underline;">5</span> 0.741  0.675</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>     6 A     0.373  0.729  0.581</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>     7 M     0.035<span style="text-decoration: underline;">9</span> 0.429  0.151</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>     8 K     0.819  0.277  0.436</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>     9 C     0.242  0.308  0.452</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>    10 G     0.065<span style="text-decoration: underline;">4</span> 0.292  0.620</span></span></code></pre>
</div>
<p>We can tell it which columns to pay attention to, or even avoid, like so:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="c"># pay attention to "x_"</span></span>
<span><span class="nv">dat_more_rank</span> <span class="o">&lt;-</span> <span class="nv">dat_more</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/across.html">across</a></span><span class="o">(</span></span>
<span>      .cols <span class="o">=</span> <span class="nf"><a href="https://tidyselect.r-lib.org/reference/starts_with.html">starts_with</a></span><span class="o">(</span><span class="s">"x_"</span><span class="o">)</span>,</span>
<span>      .fns <span class="o">=</span> <span class="nv">rank</span>,</span>
<span>      .names <span class="o">=</span> <span class="s">"{.col}_rank"</span></span>
<span>    <span class="o">)</span></span>
<span>  <span class="o">)</span></span>
<span></span>
<span><span class="nv">dat_more_rank</span></span><span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 10 × 8</span></span></span>
<span><span class="c">#&gt;       id code     x_1    x_2   x_3 x_1_rank x_2_rank x_3_rank</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>     1 Q     0.927  0.661  0.454       10        7        6</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>     2 R     0.792  0.098<span style="text-decoration: underline;">9</span> 0.970        8        2       10</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>     3 Y     0.346  0.054<span style="text-decoration: underline;">4</span> 0.278        5        1        2</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>     4 B     0.634  0.989  0.360        7       10        3</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>     5 T     0.060<span style="text-decoration: underline;">5</span> 0.741  0.675        2        9        9</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>     6 A     0.373  0.729  0.581        6        8        7</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>     7 M     0.035<span style="text-decoration: underline;">9</span> 0.429  0.151        1        6        1</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>     8 K     0.819  0.277  0.436        9        3        4</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>     9 C     0.242  0.308  0.452        4        5        5</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>    10 G     0.065<span style="text-decoration: underline;">4</span> 0.292  0.620        3        4        8</span></span><span></span>
<span><span class="c"># do it to everything EXCEPT</span></span>
<span><span class="nv">dat_more</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span></span>
<span>    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/across.html">across</a></span><span class="o">(</span></span>
<span>      .cols <span class="o">=</span> <span class="o">-</span><span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span><span class="nv">id</span>, <span class="nv">code</span><span class="o">)</span>,</span>
<span>      .fns <span class="o">=</span> <span class="nv">rank</span>,</span>
<span>      .names <span class="o">=</span> <span class="s">"{.col}_rank"</span></span>
<span>    <span class="o">)</span></span>
<span>  <span class="o">)</span></span><span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 10 × 8</span></span></span>
<span><span class="c">#&gt;       id code     x_1    x_2   x_3 x_1_rank x_2_rank x_3_rank</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>     1 Q     0.927  0.661  0.454       10        7        6</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>     2 R     0.792  0.098<span style="text-decoration: underline;">9</span> 0.970        8        2       10</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>     3 Y     0.346  0.054<span style="text-decoration: underline;">4</span> 0.278        5        1        2</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>     4 B     0.634  0.989  0.360        7       10        3</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>     5 T     0.060<span style="text-decoration: underline;">5</span> 0.741  0.675        2        9        9</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>     6 A     0.373  0.729  0.581        6        8        7</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>     7 M     0.035<span style="text-decoration: underline;">9</span> 0.429  0.151        1        6        1</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>     8 K     0.819  0.277  0.436        9        3        4</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>     9 C     0.242  0.308  0.452        4        5        5</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>    10 G     0.065<span style="text-decoration: underline;">4</span> 0.292  0.620        3        4        8</span></span></code></pre>
</div>
<p>OK, but can we make this look a little bit nicer by having the columns be like <code>x_1</code>, then <code>x_1_rank</code> and so on?</p>
<p>Sure! We can take advantage of the fact that we’ve got a pretty systematic naming scheme in this case.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">new_col_order</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/sort.html">sort</a></span><span class="o">(</span><span class="nf"><a href="https://rdrr.io/r/base/names.html">names</a></span><span class="o">(</span><span class="nv">dat_more_rank</span><span class="o">)</span><span class="o">)</span></span>
<span></span>
<span><span class="nv">new_col_order</span></span><span><span class="c">#&gt; [1] "code"     "id"       "x_1"      "x_1_rank" "x_2"      "x_2_rank" "x_3"     </span></span>
<span><span class="c">#&gt; [8] "x_3_rank"</span></span></code></pre>
</div>
<p>We can use <code>relocate</code> to specify a new column order:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">dat_more_rank</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/relocate.html">relocate</a></span><span class="o">(</span></span>
<span>    <span class="nv">id</span>,</span>
<span>    <span class="nv">code</span>,</span>
<span>    <span class="nv">new_col_order</span></span>
<span>  <span class="o">)</span></span><span><span class="c">#&gt; Note: Using an external vector in selections is ambiguous.</span></span>
<span><span class="c">#&gt; <span style="color: #0000BB;">ℹ</span> Use `all_of(new_col_order)` instead of `new_col_order` to silence this message.</span></span>
<span><span class="c">#&gt; <span style="color: #0000BB;">ℹ</span> See &lt;https://tidyselect.r-lib.org/reference/faq-external-vector.html&gt;.</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">This message is displayed once per session.</span></span></span><span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 10 × 8</span></span></span>
<span><span class="c">#&gt;       id code     x_1 x_1_rank    x_2 x_2_rank   x_3 x_3_rank</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>     1 Q     0.927        10 0.661         7 0.454        6</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>     2 R     0.792         8 0.098<span style="text-decoration: underline;">9</span>        2 0.970       10</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>     3 Y     0.346         5 0.054<span style="text-decoration: underline;">4</span>        1 0.278        2</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>     4 B     0.634         7 0.989        10 0.360        3</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>     5 T     0.060<span style="text-decoration: underline;">5</span>        2 0.741         9 0.675        9</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>     6 A     0.373         6 0.729         8 0.581        7</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>     7 M     0.035<span style="text-decoration: underline;">9</span>        1 0.429         6 0.151        1</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>     8 K     0.819         9 0.277         3 0.436        4</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>     9 C     0.242         4 0.308         5 0.452        5</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>    10 G     0.065<span style="text-decoration: underline;">4</span>        3 0.292         4 0.620        8</span></span></code></pre>
</div>
<p>Huh, apparently we need to use <code>all_of</code>, since using an external vector is ambiguous! Right you are, tidyverse team.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">dat_more_rank</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/relocate.html">relocate</a></span><span class="o">(</span></span>
<span>    <span class="nv">id</span>,</span>
<span>    <span class="nv">code</span>,</span>
<span>    <span class="nf"><a href="https://tidyselect.r-lib.org/reference/all_of.html">all_of</a></span><span class="o">(</span><span class="nv">new_col_order</span><span class="o">)</span></span>
<span>  <span class="o">)</span></span><span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 10 × 8</span></span></span>
<span><span class="c">#&gt;       id code     x_1 x_1_rank    x_2 x_2_rank   x_3 x_3_rank</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>     1 Q     0.927        10 0.661         7 0.454        6</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>     2 R     0.792         8 0.098<span style="text-decoration: underline;">9</span>        2 0.970       10</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>     3 Y     0.346         5 0.054<span style="text-decoration: underline;">4</span>        1 0.278        2</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>     4 B     0.634         7 0.989        10 0.360        3</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>     5 T     0.060<span style="text-decoration: underline;">5</span>        2 0.741         9 0.675        9</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>     6 A     0.373         6 0.729         8 0.581        7</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>     7 M     0.035<span style="text-decoration: underline;">9</span>        1 0.429         6 0.151        1</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>     8 K     0.819         9 0.277         3 0.436        4</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>     9 C     0.242         4 0.308         5 0.452        5</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>    10 G     0.065<span style="text-decoration: underline;">4</span>        3 0.292         4 0.620        8</span></span></code></pre>
</div>
<p>Or alternatively:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">dat_more_rank</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/relocate.html">relocate</a></span><span class="o">(</span></span>
<span>    <span class="nv">id</span>,</span>
<span>    <span class="nv">code</span>,</span>
<span>    <span class="nf"><a href="https://rdrr.io/r/base/sort.html">sort</a></span><span class="o">(</span><span class="nf"><a href="https://rdrr.io/r/base/names.html">names</a></span><span class="o">(</span><span class="nv">.</span><span class="o">)</span><span class="o">)</span></span>
<span>  <span class="o">)</span></span><span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 10 × 8</span></span></span>
<span><span class="c">#&gt;       id code     x_1 x_1_rank    x_2 x_2_rank   x_3 x_3_rank</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>     1 Q     0.927        10 0.661         7 0.454        6</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>     2 R     0.792         8 0.098<span style="text-decoration: underline;">9</span>        2 0.970       10</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>     3 Y     0.346         5 0.054<span style="text-decoration: underline;">4</span>        1 0.278        2</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>     4 B     0.634         7 0.989        10 0.360        3</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>     5 T     0.060<span style="text-decoration: underline;">5</span>        2 0.741         9 0.675        9</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>     6 A     0.373         6 0.729         8 0.581        7</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>     7 M     0.035<span style="text-decoration: underline;">9</span>        1 0.429         6 0.151        1</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>     8 K     0.819         9 0.277         3 0.436        4</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>     9 C     0.242         4 0.308         5 0.452        5</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>    10 G     0.065<span style="text-decoration: underline;">4</span>        3 0.292         4 0.620        8</span></span></code></pre>
</div>
<p><code>relocate</code> is a relatively new operation, it just exists to relocate existing columns, and won’t remove other columns. In the past I would have done something like:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span><span class="nv">dat_more_rank</span> <span class="o"><a href="https://magrittr.tidyverse.org/reference/pipe.html">%&gt;%</a></span> </span>
<span>  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/select.html">select</a></span><span class="o">(</span></span>
<span>    <span class="nv">id</span>,</span>
<span>    <span class="nv">code</span>,</span>
<span>    <span class="nf"><a href="https://tidyselect.r-lib.org/reference/all_of.html">all_of</a></span><span class="o">(</span><span class="nv">new_col_order</span><span class="o">)</span>,</span>
<span>    <span class="nf"><a href="https://tidyselect.r-lib.org/reference/everything.html">everything</a></span><span class="o">(</span><span class="o">)</span></span>
<span>  <span class="o">)</span></span><span><span class="c">#&gt; <span style="color: #555555;"># A tibble: 10 × 8</span></span></span>
<span><span class="c">#&gt;       id code     x_1 x_1_rank    x_2 x_2_rank   x_3 x_3_rank</span></span>
<span><span class="c">#&gt;    <span style="color: #555555; font-style: italic;">&lt;int&gt;</span> <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>  <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span>    <span style="color: #555555; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 1</span>     1 Q     0.927        10 0.661         7 0.454        6</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 2</span>     2 R     0.792         8 0.098<span style="text-decoration: underline;">9</span>        2 0.970       10</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 3</span>     3 Y     0.346         5 0.054<span style="text-decoration: underline;">4</span>        1 0.278        2</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 4</span>     4 B     0.634         7 0.989        10 0.360        3</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 5</span>     5 T     0.060<span style="text-decoration: underline;">5</span>        2 0.741         9 0.675        9</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 6</span>     6 A     0.373         6 0.729         8 0.581        7</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 7</span>     7 M     0.035<span style="text-decoration: underline;">9</span>        1 0.429         6 0.151        1</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 8</span>     8 K     0.819         9 0.277         3 0.436        4</span></span>
<span><span class="c">#&gt; <span style="color: #555555;"> 9</span>     9 C     0.242         4 0.308         5 0.452        5</span></span>
<span><span class="c">#&gt; <span style="color: #555555;">10</span>    10 G     0.065<span style="text-decoration: underline;">4</span>        3 0.292         4 0.620        8</span></span></code></pre>
</div>
<p>With that <code>everything</code> part there being to capture any columns I forgot about, because <code>select</code> will only keep the specified columns.</p>
<p>There are many ways we can do these kinds of things, but to me this felt like a nice fun example.</p>
<section id="end" class="level1">
<h1>End</h1>
<p>Anywho, that’s a bit of tidyverse magic, maybe it’ll be useful for you!</p>


</section>

 ]]></description>
  <category>rstats</category>
  <category>functions</category>
  <guid>https://www.njtierney.com/posts/2022-08-08-fun-across/</guid>
  <pubDate>Mon, 08 Aug 2022 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Notes on Changing from Rmarkdown/Bookdown to Quarto</title>
  <link>https://www.njtierney.com/posts/2022-04-08-rmd-to-qmd/</link>
  <description><![CDATA[ 
<header class="site-header">
  <h1 class="site-title">
    <a href="../../">
      <img class="hvr-grow site-logo" src="https://www.njtierney.com/assets/njt-logo-small.png" alt="Nick logo">
    </a>
    <span class="hvr-bob site-title-credibly">Credibly</span>
    <span class="hvr-hang site-title-curious">Curious</span>
  </h1>
  <p class="site-subtitle">
    Nick Tierney's (mostly) rstats blog
  </p>
  
</header>




<p>I’ve recently started transitioning my online book, <a href="https://rmd4sci.njtierney.com/">rmarkdown for scientists</a> from <a href="https://github.com/rstudio/rmarkdown">rmarkdown</a>/<a href="https://github.com/rstudio/bookdown">bookdown</a> to the new <a href="https://quarto.org/">quarto</a>. This will be a new book, called (perhaps not the most original name), <a href="https://github.com/njtierney/qmd4sci">“quarto for scientists”</a>. <a href="https://www.apreshill.com/about/">Alison Hill</a> recently wrote a great post, <a href="https://www.apreshill.com/blog/2022-04-we-dont-talk-about-quarto/">“We don’t talk about quarto”</a> that led me to see the benefits, and also that this will be the new thing we will be using in the future.</p>
<section id="what-is-quarto-why-should-i-care" class="level1">
<h1>What is quarto? Why should I care?</h1>
<p>Alison already covers this well in her post, and you should read that instead. But, somewhat briefly, here is my summary of quarto, and why you might care about it.</p>
<p>Quarto is a way to write literate programming documents. These are where you combine text and code together into a single document. Sound familiar? Well, yes, it is indeed like rmarkdown. Perhaps it might be easiest to look for comparisons with how they advertise themselves.</p>
<p>The <a href="https://github.com/rstudio/rmarkdown#rmarkdown-">README for rmarkdown</a> states:</p>
<blockquote class="blockquote">
<p>The rmarkdown package helps you create dynamic analysis documents that combine code, rendered output (such as figures), and prose. You bring your data, code, and ideas, and R Markdown renders your content into a polished document that can be used to:</p>
<ul>
<li>Do data science interactively within the RStudio IDE,</li>
<li>Reproduce your analyses,</li>
<li>Collaborate and share code with others, and</li>
<li>Communicate your results with others.</li>
</ul>
<p>R Markdown documents can be rendered to many output formats including HTML documents, PDFs, Word files, slideshows, and more, allowing you to focus on the content while R Markdown takes care of your presentation.</p>
</blockquote>
<p>How is this different to quarto? Well, <a href="https://github.com/quarto-dev/quarto-cli#quarto">the README for quarto</a> says:</p>
<blockquote class="blockquote">
<p>Quarto is an open-source scientific and technical publishing system built on <a href="https://pandoc.org/">Pandoc</a>. Quarto documents are authored using <a href="https://en.wikipedia.org/wiki/Markdown">markdown</a>, an easy to write plain text format.</p>
<p>In addition to the core capabilities of Pandoc, Quarto includes:</p>
<ol type="1">
<li><p>Embedding code and output from Python, R, and JavaScript via integration with <a href="https://jupyter.org/">Jupyter</a>, <a href="https://yihui.org/knitr/">Knitr</a>, and <a href="https://github.com/observablehq/">Observable</a>.</p></li>
<li><p>A variety of extensions to Pandoc markdown useful for technical writing including cross-references, sub-figures, layout panels, hoverable citations and footnotes, callouts, and more.</p></li>
<li><p>A project system for rendering groups of documents at once, sharing options across documents, and producing aggregate output like <a href="https://quarto.org/docs/websites/">websites</a> and <a href="https://quarto.org/docs/books/">books</a>.</p></li>
<li><p>Authoring using a wide variety of editors and notebooks including <a href="https://quarto.org/docs/tools/jupyter-lab.html">JupyterLab</a>, <a href="https://quarto.org/docs/tools/rstudio.html">RStudio</a>, and <a href="https://quarto.org/docs/tools/vscode.html">VS Code</a>.</p></li>
<li><p>A <a href="https://quarto.org/docs/visual-editor/">visual markdown editor</a> that provides a productive writing interface for composing long-form documents.</p></li>
</ol>
<p>Learn more about Quarto at <a href="https://quarto.org" class="uri">https://quarto.org</a>.</p>
</blockquote>
<section id="ok-but-what-does-that-mean" class="level2">
<h2 class="anchored" data-anchor-id="ok-but-what-does-that-mean">OK, but what does that mean?</h2>
<p>Here’s the way I see it. rmarkdown is awesome, and it isn’t going anywhere. rmarkdown has been able to produce documents that use other software, such as python, bash, stan and many more. However, there are a few points of friction:</p>
<ol type="1">
<li>You need to call it from R to use it. No problem for R users, but what if you use python? Or javascript? If you are a python user, using R to use python just might not be in your workflow.</li>
<li>There are great packages that provide extensions, such as <code>blogdown</code> for blogs, <code>bookdown</code> for books, and <code>xaringan</code> for slides. However, there are differences between these systems that might cause stumbles. Each of these systems is an iteration towards something awesome, and it’s only natural they might be a little bit different.</li>
</ol>
<p>quarto, instead of being an R package, is a separate piece of software, that you can call from the command line (terminal). This means other pieces of software can use it to create their own literate programming documents. Well, that’s my understanding.</p>
<p>Here are some not-particularly-well-drawn diagrams to illustrate this point.</p>
<p>In rmarkdown, we are working in rmarkdown, and that uses knitr to talk to R and handle the document generation:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="imgs/r-knitr-rmd.jpeg" class="lightbox" data-gallery="quarto-lightbox-gallery-1" title="Diagram showing the relationship between R, knitr, and rmarkdown, blogdown, and bookdown"><img src="https://www.njtierney.com/posts/2022-04-08-rmd-to-qmd/imgs/r-knitr-rmd.jpeg" class="img-fluid figure-img" alt="Diagram showing the relationship between R, knitr, and rmarkdown, blogdown, and bookdown"></a></p>
<figcaption>Diagram showing the relationship between R, knitr, and rmarkdown, blogdown, and bookdown</figcaption>
</figure>
</div>
<p>But with quarto, we have this general interface, where quarto can talk to different programming languages. Not pictured, but the “R engine” is in fact, <code>knitr</code>:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="imgs/quarto-all.jpeg" class="lightbox" data-gallery="quarto-lightbox-gallery-2" title="Diagram showing quarto links strongly to all languages"><img src="https://www.njtierney.com/posts/2022-04-08-rmd-to-qmd/imgs/quarto-all.jpeg" class="img-fluid figure-img" alt="Diagram showing quarto links strongly to all languages"></a></p>
<figcaption>Diagram showing quarto links strongly to all languages</figcaption>
</figure>
</div>
</section>
</section>
<section id="ok-but-why-should-i-care" class="level1">
<h1>OK, but why should I care?</h1>
<p>Well, you might not need to! I cannot imagine rmarkdown going away any time soon. So, you definitely don’t <em>need</em> to change.</p>
<p>That being said. From what I can tell, quarto appears to be a lot more consistent. For example, instead of having a special <a href="https://github.com/njtierney/rmd4sci/blob/master/_bookdown.yml"><code>_bookdown.yml</code> file</a> for your bookdown, which also needs a special <a href="https://github.com/njtierney/rmd4sci/blob/master/_output.yml">_output.yml</a> file, there is just now one single <a href="https://github.com/njtierney/qmd4sci/blob/master/_quarto.yml">_quarto.yml</a> file. It also means that there will likely be less pain if you need to change from a book to a website, to slides, to something else. So, I care because I like using the latest technology, and this seems like it will in the long run, be something that will be widely used. But I also work as a research software engineer, and caring about the latest and greatest tech is something that is on brand with the job. You don’t need to change to quarto. But it looks pretty cool.</p>
</section>
<section id="moving-from-rmarkdown-to-quarto" class="level1">
<h1>Moving from rmarkdown to quarto</h1>
<p>Here are the rough steps I went through for going from rmarkdown to quarto</p>
<section id="installing-quarto-latest-rstudio" class="level3">
<h3 class="anchored" data-anchor-id="installing-quarto-latest-rstudio">installing quarto + latest rstudio</h3>
<p>I followed the instructions here to install quarto: <a href="https://quarto.org/docs/get-started/" class="uri">https://quarto.org/docs/get-started/</a></p>
<p>As of 2022-04-08, it seems best to install the daily build of RStudio, which I did here: <a href="https://dailies.rstudio.com/" class="uri">https://dailies.rstudio.com/</a></p>
</section>
<section id="change-filenames-filename.rmd-filename.qmd" class="level3">
<h3 class="anchored" data-anchor-id="change-filenames-filename.rmd-filename.qmd">change filenames: filename.Rmd —&gt; filename.qmd</h3>
<p>I used this code to identify the files that ended with “.Rmd” and then renamed them to end with “.qmd”, which is the quarto extension.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://fs.r-lib.org">fs</a></span><span class="o">)</span>
<span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="http://stringr.tidyverse.org">stringr</a></span><span class="o">)</span>
<span class="nv">rmd_names</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://fs.r-lib.org/reference/dir_ls.html">dir_ls</a></span><span class="o">(</span>path <span class="o">=</span> <span class="s">"."</span>, glob <span class="o">=</span> <span class="s">"*.Rmd"</span><span class="o">)</span>
<span class="nv">qmd_names</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://stringr.tidyverse.org/reference/str_replace.html">str_replace</a></span><span class="o">(</span>string <span class="o">=</span> <span class="nv">rmd_names</span>,
                         pattern <span class="o">=</span> <span class="s">"Rmd"</span>,
                         replacement <span class="o">=</span> <span class="s">"qmd"</span><span class="o">)</span>
<span class="nf"><a href="https://fs.r-lib.org/reference/file_move.html">file_move</a></span><span class="o">(</span>path <span class="o">=</span> <span class="nv">rmd_names</span>,
          new_path <span class="o">=</span> <span class="nv">qmd_names</span><span class="o">)</span>

<span class="nf"><a href="https://fs.r-lib.org/reference/file_move.html">file_move</a></span><span class="o">(</span>path <span class="o">=</span> <span class="s">"_bookdown.yml"</span>,
          new_path <span class="o">=</span> <span class="s">"_quarto.yml"</span><span class="o">)</span>
</code></pre>
</div>
<p>You can see this change in <a href="https://github.com/njtierney/qmd4sci/commit/46da24051b42c092963c19c718a34596ba58e769">this commit of qmd4sci</a>.</p>
</section>
<section id="change-_bookdown.yml-to-_quarto.yml-and-remove-_output.yml" class="level3">
<h3 class="anchored" data-anchor-id="change-_bookdown.yml-to-_quarto.yml-and-remove-_output.yml">Change <code>_bookdown.yml</code> to <code>_quarto.yml</code> and remove <code>_output.yml</code></h3>
<p>I also needed to change most of the structure of <code>_bookdown.yml</code>, and to do so I followed the guidance of the <a href="https://quarto.org/docs/books/">book</a> guide in quarto, as well as looking at two quarto books they have provided, <a href="https://github.com/jjallaire/hopr">“Hands on Programming with R”</a>, and <a href="https://github.com/uwdata/visualization-curriculum">“Data Visualization Curriculum”</a>.</p>
<p>One thing I also needed to do was to replace the chapter names I had listed in the chapter as :</p>
<ul>
<li><p>“index.Rmd” –&gt; “index.qmd”</p></li>
<li><p>“license.Rmd” -&gt; “license.qmd”</p></li>
</ul>
<p>et cetera.</p>
<p>I used this code to do that:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://readr.tidyverse.org">readr</a></span><span class="o">)</span>
<span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="http://stringr.tidyverse.org">stringr</a></span><span class="o">)</span>
<span class="nv">quarto_yaml_rmd</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://readr.tidyverse.org/reference/read_lines.html">read_lines</a></span><span class="o">(</span><span class="s">"_quarto.yml"</span><span class="o">)</span>

<span class="nv">quarto_yaml_qmd</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://stringr.tidyverse.org/reference/str_replace.html">str_replace_all</a></span><span class="o">(</span>string <span class="o">=</span> <span class="nv">quarto_yaml_rmd</span>,
                                   pattern <span class="o">=</span> <span class="s">"Rmd"</span>,
                                   replacement <span class="o">=</span> <span class="s">"qmd"</span><span class="o">)</span>

<span class="nf"><a href="https://readr.tidyverse.org/reference/read_lines.html">write_lines</a></span><span class="o">(</span>
  x <span class="o">=</span> <span class="nv">quarto_yaml_qmd</span>,
  file <span class="o">=</span> <span class="s">"_quarto.yml"</span>
<span class="o">)</span>
</code></pre>
</div>
<p>Which you can see in <a href="https://github.com/njtierney/qmd4sci/commit/aa9f1e8df8795776d9a055c663ff332f24c5f069">this commit</a>.</p>
</section>
<section id="build-preview" class="level3">
<h3 class="anchored" data-anchor-id="build-preview">build? preview?</h3>
<p>I then tried to click the nifty, “build” tab that appears in the environment pane in RStudio. But this didn’t work. So I turned to the terminal and typed:</p>
<pre><code>quarto preview</code></pre>
<p>And then I got some errors.</p>
<p>Specifically,</p>
<pre><code>qmd4sci nick$ quarto preview
Preparing to preview
[ 1/23] index.qmd
ERROR: Validation of YAML front matter failed.
ERROR: In file index.qmd
(line 11, columns 13--15) Key colorlinks has value yes, which must be `true` or `false`

✖ The value yes is a string.
ℹ The error happened in location colorlinks.
ℹ Quarto uses YAML 1.2, which interprets booleans strictly.
ℹ Try using true instead.</code></pre>
<p>Which is actually quite helpful!</p>
<p>This tells me that I need to look at the <code>index.qmd</code> file, which had a bunch of YAML metadata in it like so:</p>
<pre><code>--- 
title: "RMarkdown for Scientists"
author: "Nicholas Tierney"
date: "2022-04-11"
knit: "bookdown::render_book"
description: "A book created for a 3 hour workshop on rmarkdown"
documentclass: krantz
site: bookdown::bookdown_site
bibliography: [book.bib, packages.bib]
biblio-style: apalike
colorlinks: yes
fontsize: 12pt
monofont: "Source Code Pro"
monofontoptions: "Scale=0.7"
link-citations: yes
url: 'https\://rmd4sci.njtierney.com/'
---</code></pre>
<p>It turns out I could remove this, and put most of it into the <code>_quarto.yml</code> file. I think this is a nice example of how quarto can help simplify things. It used to be a thing that you had to have some file that gave some extra metadata, or at least, it seemed like the best thing to do at the time that I wrote that book. But now all of that stuff goes into <code>_quarto.yml</code>.</p>
<p>(Also, really cool thing about using the latest RStudio daily build that I noticed, is that you get tab-completion when you are inside the YAML. So you can start exploring options for things to add! Neat. But perhaps that was already a feature in regular-rstudio and I didn’t notice.)</p>
<p>Anyway, these changes are detailed in <a href="this commit">this commit</a>.</p>
</section>
<section id="repeat-build-preview" class="level3">
<h3 class="anchored" data-anchor-id="repeat-build-preview">repeat: build? preview?</h3>
<p>The <code>build</code> tab doesn’t seem to work for me in RStudio, since it seems to call <code>rmarkdown</code> by default and that doesn’t really work.</p>
<p>Typing <code>quarto preview</code> into my terminal I get something like this:</p>
<p><a href="images/paste-44CB621D.png" class="lightbox" data-gallery="quarto-lightbox-gallery-3"><img src="https://www.njtierney.com/posts/2022-04-08-rmd-to-qmd/images/paste-44CB621D.png" class="img-fluid"></a></p>
<p>Rather neatly, quarto appears to re render whenever I save files, which is pretty awesome!</p>
</section>
<section id="what-next" class="level2">
<h2 class="anchored" data-anchor-id="what-next">What next?</h2>
<p>I’ll need to update the book to change references from rmarkdown to quarto, as well as change all the details of rmarkdown to quarto, and all the new quarto features. Which is, well, probably a lot.</p>
</section>
</section>
<section id="learning-more" class="level1">
<h1>Learning more</h1>
<ul>
<li><p><a href="https://quarto.org/">The quarto documentation</a></p></li>
<li><p><a href="https://www.apreshill.com/about/">Alison Hill</a>’s blog post, <a href="https://www.apreshill.com/blog/2022-04-we-dont-talk-about-quarto/">“We don’t talk about quarto”</a></p></li>
<li><p><a href="https://www.youtube.com/watch?v=6p4vOKS6Xls">Mine Çetinkaya-Rundel’s presentation, “Reproducible authoring with Quarto”, at the Toronto R Workshop</a></p></li>
</ul>


</section>

 ]]></description>
  <category>blag</category>
  <category>rstats</category>
  <category>rmarkdown</category>
  <category>bookdown</category>
  <category>quarto</category>
  <guid>https://www.njtierney.com/posts/2022-04-08-rmd-to-qmd/</guid>
  <pubDate>Mon, 11 Apr 2022 00:00:00 GMT</pubDate>
</item>
<item>
  <title>How Much One Shapefile Overlaps Another?</title>
  <link>https://www.njtierney.com/posts/2021-08-18-how-do-i-find-out-how-much-a-shapefile-overlaps-another/</link>
  <description><![CDATA[ 
<header class="site-header">
  <h1 class="site-title">
    <a href="../../">
      <img class="hvr-grow site-logo" src="https://www.njtierney.com/assets/njt-logo-small.png" alt="Nick logo">
    </a>
    <span class="hvr-bob site-title-credibly">Credibly</span>
    <span class="hvr-hang site-title-curious">Curious</span>
  </h1>
  <p class="site-subtitle">
    Nick Tierney's (mostly) rstats blog
  </p>
  
</header>




<div class="highlight">
<p><img src="https://www.njtierney.com/posts/2021-08-18-how-do-i-find-out-how-much-a-shapefile-overlaps-another/figs/overlapping-bubbles.jpg" width="100%" style="display: block; margin: auto;"></p>
</div>
<p align="right" font-size="12px">
Photo By <a href="https://www.instagram.com/p/CSrX0-qh1tp/">Nick Tierney</a>
</p>
<p>Last week I needed to understand how to calculate how much two spatial areas overlapped. I found a nice <a href="https://gis.stackexchange.com/questions/362466/calculate-percentage-overlap-of-2-sets-of-polygons-in-r">thread on GIS stack exchange</a> that explained an answer (from user <a href="https://gis.stackexchange.com/users/161806/sandy-ab">Sandy AB</a>). This pretty much gave me what I was looking for - but I was after something with more pictures, so here’s an example of that.</p>
<section id="the-data" class="level2">
<h2 class="anchored" data-anchor-id="the-data">The Data</h2>
<p>I started by getting some spatial areas from the ABS at <a href="https://www.abs.gov.au/statistics/standards/australian-statistical-geography-standard-asgs-edition-3/jul2021-jun2026/access-and-downloads/digital-boundary-files">this link</a>, selecting, “statistical local areas level 4 2021”:</p>
<div class="highlight">
<p><img src="https://www.njtierney.com/posts/2021-08-18-how-do-i-find-out-how-much-a-shapefile-overlaps-another/figs/shapefile-choose.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>I then did a bit of processing to shrink the data down to just my hometown, Brisbane.</p>
<p>Let’s read this in with <a href="https://r-spatial.github.io/sf/index.html"><code>sf</code></a>:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://r-spatial.github.io/sf/">sf</a></span><span class="o">)</span>
<span class="c">#&gt; Linking to GEOS 3.8.1, GDAL 3.2.1, PROJ 7.2.1</span>
<span class="nv">brisbane_sf</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://r-spatial.github.io/sf/reference/st_read.html">read_sf</a></span><span class="o">(</span><span class="nf">here</span><span class="nf">::</span><span class="nf"><a href="https://here.r-lib.org//reference/here.html">here</a></span><span class="o">(</span><span class="s">"content/post/2021-08-18-how-do-i-find-out-how-much-a-shapefile-overlaps-another/data/brisbane-sla4.shp"</span><span class="o">)</span><span class="o">)</span></code></pre>
</div>
</section>
<section id="the-data-vis" class="level2">
<h2 class="anchored" data-anchor-id="the-data-vis">The Data Vis</h2>
<p>Let’s plot my hometown, Brisbane with <a href="https://ggplot2.tidyverse.org/index.html"><code>ggplot2</code></a> and <code>geom_sf()</code>.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://ggplot2.tidyverse.org">ggplot2</a></span><span class="o">)</span>
<span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggplot.html">ggplot</a></span><span class="o">(</span><span class="o">)</span> <span class="o">+</span> 
  <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggsf.html">geom_sf</a></span><span class="o">(</span>data <span class="o">=</span> <span class="nv">brisbane_sf</span>,
          fill <span class="o">=</span> <span class="s">"forestgreen"</span><span class="o">)</span> 
</code></pre>
<p><img src="https://www.njtierney.com/posts/2021-08-18-how-do-i-find-out-how-much-a-shapefile-overlaps-another/figs/gg-full-brisbane-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>Let’s say we have a simpler shape file that we want to compare to this - which we create by simplifying the shapefile with <a href="https://github.com/ateucher/rmapshaper"><code>rmapshaper</code></a>.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://github.com/ateucher/rmapshaper">rmapshaper</a></span><span class="o">)</span>
<span class="c">#&gt; Registered S3 method overwritten by 'geojsonlint':</span>
<span class="c">#&gt;   method         from </span>
<span class="c">#&gt;   print.location dplyr</span>
<span class="nv">brisbane_simpler_sf</span> <span class="o">&lt;-</span> <span class="nv">brisbane_sf</span> <span class="o">%&gt;%</span> <span class="nf"><a href="https://rdrr.io/pkg/rmapshaper/man/ms_simplify.html">ms_simplify</a></span><span class="o">(</span>keep <span class="o">=</span> <span class="m">0.01</span><span class="o">)</span></code></pre>
</div>
<p>With this simpler file, we want to know how much area we are losing. Here’s the “simpler” Brisbane in red.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggplot.html">ggplot</a></span><span class="o">(</span><span class="o">)</span> <span class="o">+</span> 
  <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggsf.html">geom_sf</a></span><span class="o">(</span>data <span class="o">=</span> <span class="nv">brisbane_simpler_sf</span>, 
          fill <span class="o">=</span> <span class="s">"firebrick"</span><span class="o">)</span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2021-08-18-how-do-i-find-out-how-much-a-shapefile-overlaps-another/figs/gg-simple-brisbane-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>We can overlay them to see how similar they are, full Brisbane in green, and new Brisbane in red:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggplot.html">ggplot</a></span><span class="o">(</span><span class="o">)</span> <span class="o">+</span> 
  <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggsf.html">geom_sf</a></span><span class="o">(</span>data <span class="o">=</span> <span class="nv">brisbane_sf</span>,
          fill <span class="o">=</span> <span class="s">"forestgreen"</span>, alpha <span class="o">=</span> <span class="m">0.5</span><span class="o">)</span> <span class="o">+</span> 
  <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggsf.html">geom_sf</a></span><span class="o">(</span>data <span class="o">=</span> <span class="nv">brisbane_simpler_sf</span>, 
          fill <span class="o">=</span> <span class="s">"firebrick"</span>,
          alpha <span class="o">=</span> <span class="m">0.5</span><span class="o">)</span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2021-08-18-how-do-i-find-out-how-much-a-shapefile-overlaps-another/figs/gg-overlap-brisbane-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>So how do we calculate the difference between the two? We can use <code>st_intersection</code> to find where both shapes overlap. Here it is visualised:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nf"><a href="https://r-spatial.github.io/sf/reference/geos_binary_ops.html">st_intersection</a></span><span class="o">(</span><span class="nv">brisbane_sf</span>, <span class="nv">brisbane_simpler_sf</span><span class="o">)</span> <span class="o">%&gt;%</span> 
  <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggplot.html">ggplot</a></span><span class="o">(</span><span class="o">)</span> <span class="o">+</span>
  <span class="nf"><a href="https://ggplot2.tidyverse.org/reference/ggsf.html">geom_sf</a></span><span class="o">(</span>fill <span class="o">=</span> <span class="s">"brown"</span>, alpha <span class="o">=</span> <span class="m">0.5</span><span class="o">)</span>
<span class="c">#&gt; although coordinates are longitude/latitude, st_intersection assumes that they are planar</span>
<span class="c">#&gt; Warning: attribute variables are assumed to be spatially constant throughout all geometries</span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2021-08-18-how-do-i-find-out-how-much-a-shapefile-overlaps-another/figs/gg-only-overlap-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>Compare this again to the previous plot - these are the brown sections.</p>
<div class="highlight">
<p><img src="https://www.njtierney.com/posts/2021-08-18-how-do-i-find-out-how-much-a-shapefile-overlaps-another/figs/gg-overlap-brisbane-2-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>But say we want to calculate the ratio of how similar these two shape files are - how do we do that? Here are the steps:</p>
<ol type="1">
<li>Find the area of the shapefile for the original Brisbane file</li>
<li>Find the area of the overlap between the two files</li>
<li>Calculate the ratio of the area in the original shapefile, and the area of the overlapping area</li>
<li>Calculate the area of the overlap compared to the original Brisbane file, giving us the percentage of overlap!</li>
</ol>
</section>
<section id="the-area-of-the-shapefile-for-the-original-brisbane-file" class="level2">
<h2 class="anchored" data-anchor-id="the-area-of-the-shapefile-for-the-original-brisbane-file">The area of the shapefile for the original Brisbane file</h2>
<p>Here are the steps:</p>
<ol type="1">
<li>Calculate area with <code>st_area</code></li>
<li>Reduce the size of the data - then only keep the relevant data (just keeping the SA4 name (<code>SA4_NAME21</code>), and then area, then drop the geometry column).</li>
</ol>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://dplyr.tidyverse.org">dplyr</a></span><span class="o">)</span>
<span class="c">#&gt; </span>
<span class="c">#&gt; Attaching package: 'dplyr'</span>
<span class="c">#&gt; The following objects are masked from 'package:stats':</span>
<span class="c">#&gt; </span>
<span class="c">#&gt;     filter, lag</span>
<span class="c">#&gt; The following objects are masked from 'package:base':</span>
<span class="c">#&gt; </span>
<span class="c">#&gt;     intersect, setdiff, setequal, union</span>
<span class="nv">brisbane_sf_areas</span> <span class="o">&lt;-</span> <span class="nv">brisbane_sf</span> <span class="o">%&gt;%</span> 
  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span>brisbane_original_area <span class="o">=</span> <span class="nf"><a href="https://r-spatial.github.io/sf/reference/geos_measures.html">st_area</a></span><span class="o">(</span><span class="nv">.</span><span class="o">)</span><span class="o">)</span> <span class="o">%&gt;%</span> 
  <span class="nf"><a href="https://dplyr.tidyverse.org/reference/select.html">select</a></span><span class="o">(</span><span class="nv">SA4_NAME21</span>, <span class="nv">brisbane_original_area</span><span class="o">)</span> <span class="o">%&gt;%</span> 
  <span class="nf"><a href="https://r-spatial.github.io/sf/reference/st_geometry.html">st_drop_geometry</a></span><span class="o">(</span><span class="o">)</span>
  
<span class="nv">brisbane_sf_areas</span>
<span class="c">#&gt; <span style="color: #555555;"># A tibble: 1 × 2</span></span>
<span class="c">#&gt;   SA4_NAME21          brisbane_original_area</span>
<span class="c">#&gt; <span style="color: #555555;">*</span> <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>                                <span style="color: #555555;">[m^2]</span></span>
<span class="c">#&gt; <span style="color: #555555;">1</span> Brisbane Inner City               81738079</span></code></pre>
</div>
</section>
<section id="the-area-of-the-overlap-between-the-two-files" class="level2">
<h2 class="anchored" data-anchor-id="the-area-of-the-overlap-between-the-two-files">The area of the overlap between the two files</h2>
<ol type="1">
<li>Calculate the intersection of these two shape files (<code>st_intersection</code>)</li>
<li>Calculate that area (<code>st_area</code>)</li>
<li>Then only keep the relevant data again</li>
</ol>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">intersection_area</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://r-spatial.github.io/sf/reference/geos_binary_ops.html">st_intersection</a></span><span class="o">(</span><span class="nv">brisbane_sf</span>, <span class="nv">brisbane_simpler_sf</span><span class="o">)</span> <span class="o">%&gt;%</span> 
    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span>intersect_area <span class="o">=</span> <span class="nf"><a href="https://r-spatial.github.io/sf/reference/geos_measures.html">st_area</a></span><span class="o">(</span><span class="nv">.</span><span class="o">)</span><span class="o">)</span> <span class="o">%&gt;%</span> 
    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/select.html">select</a></span><span class="o">(</span><span class="nv">SA4_NAME21</span>, <span class="nv">intersect_area</span><span class="o">)</span> <span class="o">%&gt;%</span> 
    <span class="nf"><a href="https://r-spatial.github.io/sf/reference/st_geometry.html">st_drop_geometry</a></span><span class="o">(</span><span class="o">)</span>
<span class="c">#&gt; although coordinates are longitude/latitude, st_intersection assumes that they are planar</span>
<span class="c">#&gt; Warning: attribute variables are assumed to be spatially constant throughout all geometries</span>

<span class="nv">intersection_area</span>
<span class="c">#&gt; <span style="color: #555555;"># A tibble: 1 × 2</span></span>
<span class="c">#&gt;   SA4_NAME21          intersect_area</span>
<span class="c">#&gt; <span style="color: #555555;">*</span> <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>                        <span style="color: #555555;">[m^2]</span></span>
<span class="c">#&gt; <span style="color: #555555;">1</span> Brisbane Inner City       76638525</span></code></pre>
</div>
</section>
<section id="the-ratio-of-the-area-in-the-original-shapefile-and-the-area-of-the-overlapping-areas" class="level2">
<h2 class="anchored" data-anchor-id="the-ratio-of-the-area-in-the-original-shapefile-and-the-area-of-the-overlapping-areas">The ratio of the area in the original shapefile, and the area of the overlapping areas</h2>
<p>Now we have our pieces, now let us add these columns of the other data back to it:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">intersection_area</span> <span class="o">%&gt;%</span> 
    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate-joins.html">left_join</a></span><span class="o">(</span><span class="nv">brisbane_sf_areas</span>, 
              by <span class="o">=</span> <span class="s">"SA4_NAME21"</span><span class="o">)</span> 
<span class="c">#&gt; <span style="color: #555555;"># A tibble: 1 × 3</span></span>
<span class="c">#&gt;   SA4_NAME21          intersect_area brisbane_original_area</span>
<span class="c">#&gt;   <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>                        <span style="color: #555555;">[m^2]</span>                  <span style="color: #555555;">[m^2]</span></span>
<span class="c">#&gt; <span style="color: #555555;">1</span> Brisbane Inner City       76638525               81738079</span></code></pre>
</div>
<p>And then calculate the ratio - which will tell us how much the simpler shape file overlaps the original ratio.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">intersection_area</span> <span class="o">%&gt;%</span> 
    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate-joins.html">left_join</a></span><span class="o">(</span><span class="nv">brisbane_sf_areas</span>, 
              by <span class="o">=</span> <span class="s">"SA4_NAME21"</span><span class="o">)</span> <span class="o">%&gt;%</span> 
    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span>weight <span class="o">=</span> <span class="nv">intersect_area</span> <span class="o">/</span> <span class="nv">brisbane_original_area</span><span class="o">)</span>
<span class="c">#&gt; <span style="color: #555555;"># A tibble: 1 × 4</span></span>
<span class="c">#&gt;   SA4_NAME21          intersect_area brisbane_original_area   weight</span>
<span class="c">#&gt;   <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>                        <span style="color: #555555;">[m^2]</span>                  <span style="color: #555555;">[m^2]</span>      <span style="color: #555555;">[1]</span></span>
<span class="c">#&gt; <span style="color: #555555;">1</span> Brisbane Inner City       76638525               81738079 0.937611</span></code></pre>
</div>
<p>And, because I think it’s good practice, all together as a function:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">calculate_spatial_overlap</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">shape_new</span>,
                                      <span class="nv">shape_old</span><span class="o">)</span> <span class="o">{</span>
  
  
  <span class="nv">intersection_area</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://r-spatial.github.io/sf/reference/geos_binary_ops.html">st_intersection</a></span><span class="o">(</span><span class="nv">shape_new</span>, <span class="nv">shape_old</span><span class="o">)</span> <span class="o">%&gt;%</span> 
    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span>intersect_area <span class="o">=</span> <span class="nf"><a href="https://r-spatial.github.io/sf/reference/geos_measures.html">st_area</a></span><span class="o">(</span><span class="nv">.</span><span class="o">)</span><span class="o">)</span> <span class="o">%&gt;%</span> 
    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/select.html">select</a></span><span class="o">(</span><span class="nv">SA4_NAME21</span>, <span class="nv">intersect_area</span><span class="o">)</span> <span class="o">%&gt;%</span> 
    <span class="nf"><a href="https://r-spatial.github.io/sf/reference/st_geometry.html">st_drop_geometry</a></span><span class="o">(</span><span class="o">)</span>
  
  <span class="c"># Create a fresh area variable for counties</span>
  <span class="nv">shape_old_areas</span> <span class="o">&lt;-</span> <span class="nv">shape_old</span> <span class="o">%&gt;%</span> 
    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span>original_area <span class="o">=</span> <span class="nf"><a href="https://r-spatial.github.io/sf/reference/geos_measures.html">st_area</a></span><span class="o">(</span><span class="nv">.</span><span class="o">)</span><span class="o">)</span> <span class="o">%&gt;%</span> 
    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/select.html">select</a></span><span class="o">(</span><span class="nv">original_area</span>, <span class="nv">SA4_NAME21</span><span class="o">)</span> <span class="o">%&gt;%</span> 
    <span class="nf"><a href="https://r-spatial.github.io/sf/reference/st_geometry.html">st_drop_geometry</a></span><span class="o">(</span><span class="o">)</span>
  
  <span class="nv">intersection_area</span> <span class="o">%&gt;%</span> 
    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate-joins.html">left_join</a></span><span class="o">(</span><span class="nv">shape_old_areas</span>, 
              by <span class="o">=</span> <span class="s">"SA4_NAME21"</span><span class="o">)</span> <span class="o">%&gt;%</span> 
    <span class="nf"><a href="https://dplyr.tidyverse.org/reference/mutate.html">mutate</a></span><span class="o">(</span>weight <span class="o">=</span> <span class="nv">intersect_area</span> <span class="o">/</span> <span class="nv">original_area</span><span class="o">)</span>
  
<span class="o">}</span></code></pre>
</div>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nf">calculate_spatial_overlap</span><span class="o">(</span>
    <span class="nv">brisbane_simpler_sf</span>, <span class="nv">brisbane_sf</span>
  <span class="o">)</span>
<span class="c">#&gt; although coordinates are longitude/latitude, st_intersection assumes that they are planar</span>
<span class="c">#&gt; Warning: attribute variables are assumed to be spatially constant throughout all geometries</span>
<span class="c">#&gt; <span style="color: #555555;"># A tibble: 1 × 4</span></span>
<span class="c">#&gt;   SA4_NAME21          intersect_area original_area   weight</span>
<span class="c">#&gt;   <span style="color: #555555; font-style: italic;">&lt;chr&gt;</span>                        <span style="color: #555555;">[m^2]</span>         <span style="color: #555555;">[m^2]</span>      <span style="color: #555555;">[1]</span></span>
<span class="c">#&gt; <span style="color: #555555;">1</span> Brisbane Inner City       76638525      81738079 0.937611</span></code></pre>
</div>
<p>So this tells us:</p>
<blockquote class="blockquote">
<p>The new shapefile covers about 93% of the old shape file.</p>
</blockquote>
<p>That is, the red areas cover 93% of the green area:</p>
<div class="highlight">
<p><img src="https://www.njtierney.com/posts/2021-08-18-how-do-i-find-out-how-much-a-shapefile-overlaps-another/figs/show-gg-brisbane-overlap-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
</section>
<section id="why-do-this" class="level1">
<h1>Why do this?</h1>
<p>Our use case in this example was to calculate the difference between shapefiles so we could then use this overalapping difference as a weight in subsequent measurements.</p>
<p>But you can do more with this - the example from <a href="https://gis.stackexchange.com/questions/362466/calculate-percentage-overlap-of-2-sets-of-polygons-in-r">the GIS stack exchange thread</a> was trying to calculate the amount of overlap of a lot of smaller shape files on another shapefile - a measurement often referred to as “coverage”.</p>
<p>And that’s it - hope that helps someone!</p>
</section>
<section id="thanks" class="level1">
<h1>Thanks</h1>
<p>Thank you again to user <a href="https://gis.stackexchange.com/users/161806/sandy-ab">Sandy AB</a> from Stack Exchange, who posted the answer!</p>


</section>

 ]]></description>
  <category>rstats</category>
  <category>spatial</category>
  <category>gis</category>
  <category>sf</category>
  <guid>https://www.njtierney.com/posts/2021-08-18-how-do-i-find-out-how-much-a-shapefile-overlaps-another/</guid>
  <pubDate>Sat, 21 Aug 2021 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Some Unexpected Things About Subsetting</title>
  <link>https://www.njtierney.com/posts/2021-06-30-subsetting/</link>
  <description><![CDATA[ 
<header class="site-header">
  <h1 class="site-title">
    <a href="../../">
      <img class="hvr-grow site-logo" src="https://www.njtierney.com/assets/njt-logo-small.png" alt="Nick logo">
    </a>
    <span class="hvr-bob site-title-credibly">Credibly</span>
    <span class="hvr-hang site-title-curious">Curious</span>
  </h1>
  <p class="site-subtitle">
    Nick Tierney's (mostly) rstats blog
  </p>
  
</header>




<p>The other day a colleague of mine ran into an issue where NA values were appearing in their dataset that weren’t there before - it was strange stuff!</p>
<p>A close look revealed some interesting things, that I thought might be worthwhile briefly going into. It is to do with the use of <code>[]</code> when subsetting, and how this is different to <a href="https://rdrr.io/r/base/subset.html"><code>base::subset</code></a> and <a href="https://dplyr.tidyverse.org/reference/filter.html"><code>dplyr::filter</code></a>.</p>
<p>Let’s start by creating a dataset, <code>df</code>. This contains countries and an airport</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">df</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/data.frame.html">data.frame</a></span><span class="o">(</span>
  country <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span><span class="kc">NA</span>, <span class="s">"AUS"</span>, <span class="s">"NZL"</span>, <span class="s">"USA "</span><span class="o">)</span>,
  airport <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span><span class="kc">NA</span>, <span class="s">"BNE"</span>, <span class="s">"CHC"</span>, <span class="s">" SFO"</span><span class="o">)</span>
<span class="o">)</span>

<span class="nv">df</span>
<span class="c">#&gt;   country airport</span>
<span class="c">#&gt; 1    &lt;NA&gt;    &lt;NA&gt;</span>
<span class="c">#&gt; 2     AUS     BNE</span>
<span class="c">#&gt; 3     NZL     CHC</span>
<span class="c">#&gt; 4    USA      SFO</span></code></pre>
</div>
<p>If we want to just look at rows that contain “AUS”, we can do the following:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1">df[df<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>country <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;">"AUS"</span>, ]</span></code></pre></div></div>
<p>Which is asking to only choose rows where country is “AUS”.</p>
<p>However, when we run this, we get something unexpected</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">df</span><span class="o">[</span><span class="nv">df</span><span class="o">$</span><span class="nv">country</span> <span class="o">==</span> <span class="s">"AUS"</span>, <span class="o">]</span>
<span class="c">#&gt;    country airport</span>
<span class="c">#&gt; NA    &lt;NA&gt;    &lt;NA&gt;</span>
<span class="c">#&gt; 2      AUS     BNE</span></code></pre>
</div>
<p>We get an NA row?</p>
<section id="what-weird" class="level1">
<h1>What? Weird?</h1>
<p>Under the hood, <a href="https://rdrr.io/r/base/Comparison.html"><code>==</code></a> is identifying rows that match this statement.</p>
<p>You could also do this:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">df</span><span class="o">[</span><span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span><span class="kc">FALSE</span>, <span class="kc">TRUE</span>, <span class="kc">FALSE</span>, <span class="kc">FALSE</span><span class="o">)</span>, <span class="o">]</span>
<span class="c">#&gt;   country airport</span>
<span class="c">#&gt; 2     AUS     BNE</span></code></pre>
</div>
<p>But that’s too hard to manually create those vectors for datasets - we instead get that result out by running it inside the <code>[]</code>:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">df</span><span class="o">[</span><span class="nv">df</span><span class="o">$</span><span class="nv">country</span> <span class="o">==</span> <span class="s">"AUS"</span>, <span class="o">]</span>
<span class="c">#&gt;    country airport</span>
<span class="c">#&gt; NA    &lt;NA&gt;    &lt;NA&gt;</span>
<span class="c">#&gt; 2      AUS     BNE</span></code></pre>
</div>
<p>So why the NA row?</p>
<p>Well, we do have an NA row in the dataset:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">df</span>
<span class="c">#&gt;   country airport</span>
<span class="c">#&gt; 1    &lt;NA&gt;    &lt;NA&gt;</span>
<span class="c">#&gt; 2     AUS     BNE</span>
<span class="c">#&gt; 3     NZL     CHC</span>
<span class="c">#&gt; 4    USA      SFO</span></code></pre>
</div>
<p>And we can check what the output of <code>df$country == "AUS"</code> is:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">where_match_aus</span> <span class="o">&lt;-</span> <span class="nv">df</span><span class="o">$</span><span class="nv">country</span> <span class="o">==</span> <span class="s">"AUS"</span>
<span class="nv">where_match_aus</span>
<span class="c">#&gt; [1]    NA  TRUE FALSE FALSE</span></code></pre>
</div>
<p>This shows us the same as what we saw above</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">df</span><span class="o">[</span><span class="nv">where_match_aus</span>, <span class="o">]</span>
<span class="c">#&gt;    country airport</span>
<span class="c">#&gt; NA    &lt;NA&gt;    &lt;NA&gt;</span>
<span class="c">#&gt; 2      AUS     BNE</span>
<span class="nv">df</span><span class="o">[</span><span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span><span class="kc">NA</span>, <span class="kc">TRUE</span>, <span class="kc">FALSE</span>, <span class="kc">FALSE</span><span class="o">)</span>, <span class="o">]</span>
<span class="c">#&gt;    country airport</span>
<span class="c">#&gt; NA    &lt;NA&gt;    &lt;NA&gt;</span>
<span class="c">#&gt; 2      AUS     BNE</span></code></pre>
</div>
<p>But what is weird about this is that you can use <code>NA</code> inside <code>[]</code> when subsetting:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">df</span><span class="o">[</span><span class="kc">NA</span>, <span class="o">]</span>
<span class="c">#&gt;      country airport</span>
<span class="c">#&gt; NA      &lt;NA&gt;    &lt;NA&gt;</span>
<span class="c">#&gt; NA.1    &lt;NA&gt;    &lt;NA&gt;</span>
<span class="c">#&gt; NA.2    &lt;NA&gt;    &lt;NA&gt;</span>
<span class="c">#&gt; NA.3    &lt;NA&gt;    &lt;NA&gt;</span></code></pre>
</div>
<p>And you get a whole lot of weird rows now? Strange, right?</p>
<p>And what happens when our filter is wrong? Remember, “USA” has a trailing space in it, so if we write out “USA”, we get:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">df</span><span class="o">[</span><span class="nv">df</span><span class="o">$</span><span class="nv">country</span> <span class="o">==</span> <span class="s">"USA"</span>, <span class="o">]</span>
<span class="c">#&gt;    country airport</span>
<span class="c">#&gt; NA    &lt;NA&gt;    &lt;NA&gt;</span></code></pre>
</div>
<p>Since we get <code>NA</code> when we do:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">df</span><span class="o">$</span><span class="nv">country</span> <span class="o">==</span> <span class="s">"USA"</span>
<span class="c">#&gt; [1]    NA FALSE FALSE FALSE</span></code></pre>
</div>
</section>
<section id="what-about-basesubset-or-dplyrfilter" class="level1">
<h1>What about base::subset or dplyr::filter</h1>
<p>For what it’s worth, this issue doesn’t appear inside <a href="https://rdrr.io/r/base/subset.html"><code>base::subset</code></a> or <a href="https://dplyr.tidyverse.org/reference/filter.html"><code>dplyr::filter</code></a> - I guess this means the turn <code>NA</code> into FALSE?</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="c"># vs subset</span>
<span class="nf"><a href="https://rdrr.io/r/base/subset.html">subset</a></span><span class="o">(</span><span class="nv">df</span>, <span class="nv">country</span> <span class="o">==</span> <span class="s">"AUS"</span><span class="o">)</span>
<span class="c">#&gt;   country airport</span>
<span class="c">#&gt; 2     AUS     BNE</span>
<span class="nf"><a href="https://rdrr.io/r/base/subset.html">subset</a></span><span class="o">(</span><span class="nv">df</span>, <span class="nv">country</span> <span class="o">==</span> <span class="s">"USA"</span><span class="o">)</span>
<span class="c">#&gt; [1] country airport</span>
<span class="c">#&gt; &lt;0 rows&gt; (or 0-length row.names)</span>
<span class="nf"><a href="https://rdrr.io/r/base/subset.html">subset</a></span><span class="o">(</span><span class="nv">df</span>, <span class="kc">NA</span><span class="o">)</span>
<span class="c">#&gt; [1] country airport</span>
<span class="c">#&gt; &lt;0 rows&gt; (or 0-length row.names)</span></code></pre>
</div>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="c"># vs filter</span>
<span class="nf">dplyr</span><span class="nf">::</span><span class="nf"><a href="https://dplyr.tidyverse.org/reference/filter.html">filter</a></span><span class="o">(</span><span class="nv">df</span>, <span class="nv">country</span> <span class="o">==</span> <span class="s">"AUS"</span><span class="o">)</span>
<span class="c">#&gt;   country airport</span>
<span class="c">#&gt; 1     AUS     BNE</span>
<span class="nf">dplyr</span><span class="nf">::</span><span class="nf"><a href="https://dplyr.tidyverse.org/reference/filter.html">filter</a></span><span class="o">(</span><span class="nv">df</span>, <span class="nv">country</span> <span class="o">==</span> <span class="s">"USA"</span><span class="o">)</span>
<span class="c">#&gt; [1] country airport</span>
<span class="c">#&gt; &lt;0 rows&gt; (or 0-length row.names)</span>
<span class="nf">dplyr</span><span class="nf">::</span><span class="nf"><a href="https://dplyr.tidyverse.org/reference/filter.html">filter</a></span><span class="o">(</span><span class="nv">df</span>, <span class="kc">NA</span><span class="o">)</span>
<span class="c">#&gt; [1] country airport</span>
<span class="c">#&gt; &lt;0 rows&gt; (or 0-length row.names)</span></code></pre>
</div>
</section>
<section id="i-have-more-questions-but-i-have-to-go" class="level1">
<h1>I have more questions, but I have to go</h1>
<p>I feel like there are more questions I have about this, and I am probably missing some important details, but I just thought this was interesting!</p>


</section>

 ]]></description>
  <category>rstats</category>
  <guid>https://www.njtierney.com/posts/2021-06-30-subsetting/</guid>
  <pubDate>Wed, 30 Jun 2021 00:00:00 GMT</pubDate>
</item>
<item>
  <title>What if Australia’s vaccination rate is similar to our testing?</title>
  <link>https://www.njtierney.com/posts/2021-02-27-oz-covid-vacc/</link>
  <description><![CDATA[ 
<header class="site-header">
  <h1 class="site-title">
    <a href="../../">
      <img class="hvr-grow site-logo" src="https://www.njtierney.com/assets/njt-logo-small.png" alt="Nick logo">
    </a>
    <span class="hvr-bob site-title-credibly">Credibly</span>
    <span class="hvr-hang site-title-curious">Curious</span>
  </h1>
  <p class="site-subtitle">
    Nick Tierney's (mostly) rstats blog
  </p>
  
</header>




<p>The COVID19 vaccines (plural!) are rolling out around the world, and about 4 weeks ago in late Feb, <a href="https://www.abc.net.au/news/2021-02-21/australias-first-coronavirus-vaccine-recipient-jane-malysiak/13176274">Australians got their first vaccine jab</a>. It’s a pretty massive relief that these vaccines (plural!!!) are rolling out so soon.</p>
<p>The ABC helps answer, <a href="https://www.abc.net.au/news/2021-02-05/when-will-you-get-the-covid-19-vaccine/13112610">“When will you get the COVID-19 vaccine?”</a>, which is super cool! The Australian government reckons we’ll be vaccinated at a good percentage (80%?) by sometime later in the year - I forget exactly when they said, but let’s say about October.</p>
<p>Now, I’m not sure how to imagine how this all takes place, but one thing I thought might be an interesting proxy is using the number of COVID19 tests that we can conduct in a day in Australia to proxy in for the number of vaccinations we can do.</p>
<p>Now, sure, getting a test isn’t the same as getting a vaccine, but there are similar PPE controls in place, waiting in queue, and getting swabbed takes about as long as a jab, and I figured it might tell us something.</p>
<p>Fortunately the data is very accessible so it’s a question that we can answer with R, some web scraping, some data wrangling, and some graphs.</p>
<p>So the question I’m focusing on in this blog post is:</p>
<blockquote class="blockquote">
<p>“Based on the COVID19 tests that Australia can perform each day, how long will it take to get to 80% of Australians vaccinated?”.</p>
</blockquote>
<p>To do this we’ll recycle some of the code from my previous blog post on <a href="https://www.njtierney.com/post/2020/10/20/roll-avg-covid/">exploring covid numbers in Australia</a> - I skim over some of the repeated parts of code in this post, but I do provide a full explanation at the previously linked blog post. The data is kindly sourced from <a href="https://covidlive.com.au/">covidliveau</a>.</p>
<p>First, we load up the packages we need:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="http://tidyverse.tidyverse.org">tidyverse</a></span><span class="o">)</span>
<span class="c">#&gt; ── <span style="font-weight: bold;">Attaching packages</span><span> ───────────────────────────── tidyverse 1.3.0 ──</span></span>
<span class="c">#&gt; <span style="color: #00BB00;">✔</span><span> </span><span style="color: #0000BB;">ggplot2</span><span> 3.3.3     </span><span style="color: #00BB00;">✔</span><span> </span><span style="color: #0000BB;">purrr  </span><span> 0.3.4</span></span>
<span class="c">#&gt; <span style="color: #00BB00;">✔</span><span> </span><span style="color: #0000BB;">tibble </span><span> 3.1.0     </span><span style="color: #00BB00;">✔</span><span> </span><span style="color: #0000BB;">dplyr  </span><span> 1.0.5</span></span>
<span class="c">#&gt; <span style="color: #00BB00;">✔</span><span> </span><span style="color: #0000BB;">tidyr  </span><span> 1.1.3     </span><span style="color: #00BB00;">✔</span><span> </span><span style="color: #0000BB;">stringr</span><span> 1.4.0</span></span>
<span class="c">#&gt; <span style="color: #00BB00;">✔</span><span> </span><span style="color: #0000BB;">readr  </span><span> 1.4.0     </span><span style="color: #00BB00;">✔</span><span> </span><span style="color: #0000BB;">forcats</span><span> 0.5.1</span></span>
<span class="c">#&gt; ── <span style="font-weight: bold;">Conflicts</span><span> ──────────────────────────────── tidyverse_conflicts() ──</span></span>
<span class="c">#&gt; <span style="color: #BB0000;">✖</span><span> </span><span style="color: #0000BB;">dplyr</span><span>::</span><span style="color: #00BB00;">filter()</span><span> masks </span><span style="color: #0000BB;">stats</span><span>::filter()</span></span>
<span class="c">#&gt; <span style="color: #BB0000;">✖</span><span> </span><span style="color: #0000BB;">dplyr</span><span>::</span><span style="color: #00BB00;">lag()</span><span>    masks </span><span style="color: #0000BB;">stats</span><span>::lag()</span></span>
<span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://github.com/dmi3kno/polite">polite</a></span><span class="o">)</span>
<span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://rvest.tidyverse.org/">rvest</a></span><span class="o">)</span>
<span class="c">#&gt; </span>
<span class="c">#&gt; Attaching package: 'rvest'</span>
<span class="c">#&gt; The following object is masked from 'package:readr':</span>
<span class="c">#&gt; </span>
<span class="c">#&gt;     guess_encoding</span>
<span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://github.com/rstudio/htmltools">htmltools</a></span><span class="o">)</span>
<span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://scales.r-lib.org">scales</a></span><span class="o">)</span>
<span class="c">#&gt; </span>
<span class="c">#&gt; Attaching package: 'scales'</span>
<span class="c">#&gt; The following object is masked from 'package:purrr':</span>
<span class="c">#&gt; </span>
<span class="c">#&gt;     discard</span>
<span class="c">#&gt; The following object is masked from 'package:readr':</span>
<span class="c">#&gt; </span>
<span class="c">#&gt;     col_factor</span></code></pre>
</div>
<ul>
<li><code>tidyverse</code> for data wrangling and plotting and magic</li>
<li><code>polite</code>, <code>rvest</code>, <code>htmltools</code> for web scraping</li>
<li><code>scales</code> for making nicer plot scales and stuff</li>
</ul>
<p>We scrape the data for tests in Australia, and extract the table</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">aus_test_url</span> <span class="o">&lt;-</span> <span class="s">"https://covidlive.com.au/report/daily-tests/aus"</span>

<span class="nv">aus_test_data_raw</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/pkg/polite/man/bow.html">bow</a></span><span class="o">(</span><span class="nv">aus_test_url</span><span class="o">)</span> <span class="o">%&gt;%</span> 
  <span class="nf"><a href="https://rdrr.io/pkg/polite/man/scrape.html">scrape</a></span><span class="o">(</span><span class="o">)</span> <span class="o">%&gt;%</span> 
  <span class="nf"><a href="https://rvest.tidyverse.org/reference/html_table.html">html_table</a></span><span class="o">(</span><span class="o">)</span> <span class="o">%&gt;%</span> 
  <span class="nf">purrr</span><span class="nf">::</span><span class="nf"><a href="https://purrr.tidyverse.org/reference/pluck.html">pluck</a></span><span class="o">(</span><span class="m">2</span><span class="o">)</span> <span class="o">%&gt;%</span> 
  <span class="nf">as_tibble</span><span class="o">(</span><span class="o">)</span>

<span class="nv">aus_test_data_raw</span>
<span class="c">#&gt; <span style="color: #555555;"># A tibble: 386 x 4</span></span>
<span class="c">#&gt;    DATE      TESTS      VAR   NET   </span>
<span class="c">#&gt;    <span style="color: #555555;font-style: italic;">&lt;chr&gt;</span><span>     </span><span style="color: #555555;font-style: italic;">&lt;chr&gt;</span><span>      </span><span style="color: #555555;font-style: italic;">&lt;lgl&gt;</span><span> </span><span style="color: #555555;font-style: italic;">&lt;chr&gt;</span><span> </span></span>
<span class="c">#&gt; <span style="color: #555555;"> 1</span><span> 21 Mar 21 15,186,991 </span><span style="color: #BB0000;">NA</span><span>    34,669</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 2</span><span> 20 Mar 21 15,152,322 </span><span style="color: #BB0000;">NA</span><span>    36,037</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 3</span><span> 19 Mar 21 15,116,285 </span><span style="color: #BB0000;">NA</span><span>    44,082</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 4</span><span> 18 Mar 21 15,072,203 </span><span style="color: #BB0000;">NA</span><span>    50,496</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 5</span><span> 17 Mar 21 15,021,707 </span><span style="color: #BB0000;">NA</span><span>    54,260</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 6</span><span> 16 Mar 21 14,967,447 </span><span style="color: #BB0000;">NA</span><span>    33,843</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 7</span><span> 15 Mar 21 14,933,604 </span><span style="color: #BB0000;">NA</span><span>    32,312</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 8</span><span> 14 Mar 21 14,901,292 </span><span style="color: #BB0000;">NA</span><span>    29,392</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 9</span><span> 13 Mar 21 14,871,900 </span><span style="color: #BB0000;">NA</span><span>    36,989</span></span>
<span class="c">#&gt; <span style="color: #555555;">10</span><span> 12 Mar 21 14,834,911 </span><span style="color: #BB0000;">NA</span><span>    45,015</span></span>
<span class="c">#&gt; <span style="color: #555555;"># … with 376 more rows</span></span></code></pre>
</div>
<p>We then clean up the dates and numbers, defining a little function, <code>strp_date</code>, to present the dates nicely.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">strp_date</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="o">(</span><span class="nv">x</span><span class="o">)</span> <span class="nf"><a href="https://rdrr.io/r/base/as.Date.html">as.Date</a></span><span class="o">(</span><span class="nf"><a href="https://rdrr.io/r/base/strptime.html">strptime</a></span><span class="o">(</span><span class="nv">x</span>, format <span class="o">=</span> <span class="s">"%d %b"</span><span class="o">)</span><span class="o">)</span>

<span class="nv">aus_tests</span> <span class="o">&lt;-</span> <span class="nv">aus_test_data_raw</span> <span class="o">%&gt;%</span> 
  <span class="nf">mutate</span><span class="o">(</span>DATE <span class="o">=</span> <span class="nf">strp_date</span><span class="o">(</span><span class="nv">DATE</span><span class="o">)</span>,
         TESTS <span class="o">=</span> <span class="nf">parse_number</span><span class="o">(</span><span class="nv">TESTS</span><span class="o">)</span>,
         NET <span class="o">=</span> <span class="nf">parse_number</span><span class="o">(</span><span class="nv">NET</span><span class="o">)</span><span class="o">)</span> <span class="o">%&gt;%</span> 
  <span class="nf">janitor</span><span class="nf">::</span><span class="nf"><a href="https://rdrr.io/pkg/janitor/man/clean_names.html">clean_names</a></span><span class="o">(</span><span class="o">)</span> <span class="o">%&gt;%</span> 
  <span class="nf">rename</span><span class="o">(</span>daily_tests <span class="o">=</span> <span class="nv">net</span><span class="o">)</span>
<span class="c">#&gt; Warning: 29 parsing failures.</span>
<span class="c">#&gt; row col expected actual</span>
<span class="c">#&gt; 358  -- a number      -</span>
<span class="c">#&gt; 359  -- a number      -</span>
<span class="c">#&gt; 360  -- a number      -</span>
<span class="c">#&gt; 361  -- a number      -</span>
<span class="c">#&gt; 362  -- a number      -</span>
<span class="c">#&gt; ... ... ........ ......</span>
<span class="c">#&gt; See problems(...) for more details.</span>

<span class="nv">aus_tests</span>
<span class="c">#&gt; <span style="color: #555555;"># A tibble: 386 x 4</span></span>
<span class="c">#&gt;    date          tests var   daily_tests</span>
<span class="c">#&gt;    <span style="color: #555555;font-style: italic;">&lt;date&gt;</span><span>        </span><span style="color: #555555;font-style: italic;">&lt;dbl&gt;</span><span> </span><span style="color: #555555;font-style: italic;">&lt;lgl&gt;</span><span>       </span><span style="color: #555555;font-style: italic;">&lt;dbl&gt;</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 1</span><span> 2021-03-21 15</span><span style="text-decoration: underline;">186</span><span>991 </span><span style="color: #BB0000;">NA</span><span>          </span><span style="text-decoration: underline;">34</span><span>669</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 2</span><span> 2021-03-20 15</span><span style="text-decoration: underline;">152</span><span>322 </span><span style="color: #BB0000;">NA</span><span>          </span><span style="text-decoration: underline;">36</span><span>037</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 3</span><span> 2021-03-19 15</span><span style="text-decoration: underline;">116</span><span>285 </span><span style="color: #BB0000;">NA</span><span>          </span><span style="text-decoration: underline;">44</span><span>082</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 4</span><span> 2021-03-18 15</span><span style="text-decoration: underline;">072</span><span>203 </span><span style="color: #BB0000;">NA</span><span>          </span><span style="text-decoration: underline;">50</span><span>496</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 5</span><span> 2021-03-17 15</span><span style="text-decoration: underline;">021</span><span>707 </span><span style="color: #BB0000;">NA</span><span>          </span><span style="text-decoration: underline;">54</span><span>260</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 6</span><span> 2021-03-16 14</span><span style="text-decoration: underline;">967</span><span>447 </span><span style="color: #BB0000;">NA</span><span>          </span><span style="text-decoration: underline;">33</span><span>843</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 7</span><span> 2021-03-15 14</span><span style="text-decoration: underline;">933</span><span>604 </span><span style="color: #BB0000;">NA</span><span>          </span><span style="text-decoration: underline;">32</span><span>312</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 8</span><span> 2021-03-14 14</span><span style="text-decoration: underline;">901</span><span>292 </span><span style="color: #BB0000;">NA</span><span>          </span><span style="text-decoration: underline;">29</span><span>392</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 9</span><span> 2021-03-13 14</span><span style="text-decoration: underline;">871</span><span>900 </span><span style="color: #BB0000;">NA</span><span>          </span><span style="text-decoration: underline;">36</span><span>989</span></span>
<span class="c">#&gt; <span style="color: #555555;">10</span><span> 2021-03-12 14</span><span style="text-decoration: underline;">834</span><span>911 </span><span style="color: #BB0000;">NA</span><span>          </span><span style="text-decoration: underline;">45</span><span>015</span></span>
<span class="c">#&gt; <span style="color: #555555;"># … with 376 more rows</span></span></code></pre>
</div>
<p>We get a sense of the distribution of tests by ploting the number of daily tests in Australia as a boxplot.</p>
<p>This extra line of code improves how big numbers are presented: <code>scale_x_continuous(labels = label_number(big.mark = ","))</code>, turning 100000 into 100,000. Perhaps not a big deal, but I think it helps.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nf">ggplot</span><span class="o">(</span><span class="nv">aus_tests</span>,
       <span class="nf">aes</span><span class="o">(</span>x <span class="o">=</span> <span class="nv">daily_tests</span><span class="o">)</span><span class="o">)</span> <span class="o">+</span> 
  <span class="nf">geom_boxplot</span><span class="o">(</span><span class="o">)</span> <span class="o">+</span> 
  <span class="nf">scale_x_continuous</span><span class="o">(</span>labels <span class="o">=</span> <span class="nf"><a href="https://scales.r-lib.org//reference/label_number.html">label_number</a></span><span class="o">(</span>big.mark <span class="o">=</span> <span class="s">","</span><span class="o">)</span><span class="o">)</span>
<span class="c">#&gt; Warning: Removed 29 rows containing non-finite values (stat_boxplot).</span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2021-02-27-oz-covid-vacc/figs/plot-tests-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>We learn most of the data is around 25-55K tests per day, give or take, and there were some extreme days where we tested over 150K! Not bad, not bad.</p>
<p>Another way to present the same data is to plot is as a density, along with a rug plot to show the data frequency.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">gg_cov_dens</span> <span class="o">&lt;-</span> <span class="nf">ggplot</span><span class="o">(</span><span class="nv">aus_tests</span>,
       <span class="nf">aes</span><span class="o">(</span>x <span class="o">=</span> <span class="nv">daily_tests</span><span class="o">)</span><span class="o">)</span> <span class="o">+</span> 
  <span class="nf">geom_density</span><span class="o">(</span><span class="o">)</span> <span class="o">+</span>
  <span class="nf">geom_rug</span><span class="o">(</span>alpha <span class="o">=</span> <span class="m">0.2</span><span class="o">)</span> <span class="o">+</span>
  <span class="nf">scale_x_continuous</span><span class="o">(</span>labels <span class="o">=</span> <span class="nf"><a href="https://scales.r-lib.org//reference/label_number.html">label_number</a></span><span class="o">(</span>big.mark <span class="o">=</span> <span class="s">","</span><span class="o">)</span><span class="o">)</span>

<span class="nv">gg_cov_dens</span>
<span class="c">#&gt; Warning: Removed 29 rows containing non-finite values (stat_density).</span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2021-02-27-oz-covid-vacc/figs/tests-rug-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>This is pretty much a similar presentation of the previous plot, it’s fun to look at, plus rug plots are great. If we’re interested in what kind of distribution this follows, we can overlay a normal curve over the top with <code>geom_function</code>, adding in the estimated mean and standard deviation</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">tests_mean</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/mean.html">mean</a></span><span class="o">(</span><span class="nv">aus_tests</span><span class="o">$</span><span class="nv">daily_tests</span>, na.rm <span class="o">=</span> <span class="kc">TRUE</span><span class="o">)</span>
<span class="nv">tests_sd</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/stats/sd.html">sd</a></span><span class="o">(</span><span class="nv">aus_tests</span><span class="o">$</span><span class="nv">daily_tests</span>, na.rm <span class="o">=</span> <span class="kc">TRUE</span><span class="o">)</span>

<span class="nv">gg_cov_dens</span> <span class="o">+</span> 
  <span class="nf">geom_function</span><span class="o">(</span>fun <span class="o">=</span> <span class="nv">dnorm</span>, 
                args <span class="o">=</span> <span class="nf"><a href="https://rdrr.io/r/base/list.html">list</a></span><span class="o">(</span>mean <span class="o">=</span> <span class="nv">tests_mean</span>, sd <span class="o">=</span> <span class="nv">tests_sd</span><span class="o">)</span>,
                colour <span class="o">=</span> <span class="s">"orange"</span><span class="o">)</span>
<span class="c">#&gt; Warning: Removed 29 rows containing non-finite values (stat_density).</span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2021-02-27-oz-covid-vacc/figs/geom-fun-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>It looks somewhat normal, but it’s a bit more peaky to the left. So, if you needed to assign this a distribution, maybe representing this as a normal isn’t the best, or at least we could understand where it isn’t representing the data.</p>
<section id="back-on-task" class="level1">
<h1>Back on task</h1>
<p>OK so what were we doing? Back to the question:</p>
<blockquote class="blockquote">
<p>“Based on the COVID19 tests that Australia can perform each day, how long will it take to get to 80% of Australians vaccinated?”.</p>
</blockquote>
<p>Let’s calculate the maximum number of tests, and define 80% of <a href="https://www.abs.gov.au/statistics/people/population">Australia’s population</a>.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">max_tests</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/r/base/Extremes.html">max</a></span><span class="o">(</span><span class="nv">aus_tests</span><span class="o">$</span><span class="nv">daily_tests</span>, na.rm <span class="o">=</span> <span class="kc">TRUE</span><span class="o">)</span>
<span class="nv">oz_pop_80_pct</span> <span class="o">&lt;-</span> <span class="m">0.8</span> <span class="o">*</span> <span class="m">25693059</span></code></pre>
</div>
<p>With this new information we then create a new table with a column of the percentage of maximum tests. We want to create a 100 row table, where each row is a percentage of the maximum tests. We can then calculate the number of days until Australia reaches 80% vaccination by dividing the number of 80% of the population bt the propotion of max tests.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">covid_days_until_vac</span> <span class="o">&lt;-</span> <span class="nf">tibble</span><span class="o">(</span>pct_of_max_tests <span class="o">=</span> <span class="o">(</span><span class="m">1</span><span class="o">:</span><span class="m">100</span><span class="o">)</span><span class="o">/</span><span class="m">100</span>,
       max_tests <span class="o">=</span> <span class="nv">max_tests</span>,
       prop_of_max_tests <span class="o">=</span> <span class="nv">max_tests</span> <span class="o">*</span> <span class="nv">pct_of_max_tests</span>,
       days_until_80_pct_aus_pop_vac <span class="o">=</span> <span class="nv">oz_pop_80_pct</span> <span class="o">/</span> <span class="nv">prop_of_max_tests</span><span class="o">)</span>

<span class="nv">covid_days_until_vac</span>
<span class="c">#&gt; <span style="color: #555555;"># A tibble: 100 x 4</span></span>
<span class="c">#&gt;    pct_of_max_tests max_tests prop_of_max_tests days_until_80_pct_aus_pop_vac</span>
<span class="c">#&gt;               <span style="color: #555555;font-style: italic;">&lt;dbl&gt;</span><span>     </span><span style="color: #555555;font-style: italic;">&lt;dbl&gt;</span><span>             </span><span style="color: #555555;font-style: italic;">&lt;dbl&gt;</span><span>                         </span><span style="color: #555555;font-style: italic;">&lt;dbl&gt;</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 1</span><span>             0.01    </span><span style="text-decoration: underline;">136</span><span>194             </span><span style="text-decoration: underline;">1</span><span>362.                        </span><span style="text-decoration: underline;">15</span><span>092.</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 2</span><span>             0.02    </span><span style="text-decoration: underline;">136</span><span>194             </span><span style="text-decoration: underline;">2</span><span>724.                         </span><span style="text-decoration: underline;">7</span><span>546.</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 3</span><span>             0.03    </span><span style="text-decoration: underline;">136</span><span>194             </span><span style="text-decoration: underline;">4</span><span>086.                         </span><span style="text-decoration: underline;">5</span><span>031.</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 4</span><span>             0.04    </span><span style="text-decoration: underline;">136</span><span>194             </span><span style="text-decoration: underline;">5</span><span>448.                         </span><span style="text-decoration: underline;">3</span><span>773.</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 5</span><span>             0.05    </span><span style="text-decoration: underline;">136</span><span>194             </span><span style="text-decoration: underline;">6</span><span>810.                         </span><span style="text-decoration: underline;">3</span><span>018.</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 6</span><span>             0.06    </span><span style="text-decoration: underline;">136</span><span>194             </span><span style="text-decoration: underline;">8</span><span>172.                         </span><span style="text-decoration: underline;">2</span><span>515.</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 7</span><span>             0.07    </span><span style="text-decoration: underline;">136</span><span>194             </span><span style="text-decoration: underline;">9</span><span>534.                         </span><span style="text-decoration: underline;">2</span><span>156.</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 8</span><span>             0.08    </span><span style="text-decoration: underline;">136</span><span>194            </span><span style="text-decoration: underline;">10</span><span>896.                         </span><span style="text-decoration: underline;">1</span><span>887.</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 9</span><span>             0.09    </span><span style="text-decoration: underline;">136</span><span>194            </span><span style="text-decoration: underline;">12</span><span>257.                         </span><span style="text-decoration: underline;">1</span><span>677.</span></span>
<span class="c">#&gt; <span style="color: #555555;">10</span><span>             0.1     </span><span style="text-decoration: underline;">136</span><span>194            </span><span style="text-decoration: underline;">13</span><span>619.                         </span><span style="text-decoration: underline;">1</span><span>509.</span></span>
<span class="c">#&gt; <span style="color: #555555;"># … with 90 more rows</span></span></code></pre>
</div>
<p>Then we can plot this!</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nf">ggplot</span><span class="o">(</span><span class="nv">covid_days_until_vac</span>,
         <span class="nf">aes</span><span class="o">(</span>x <span class="o">=</span> <span class="nv">days_until_80_pct_aus_pop_vac</span>,
             y <span class="o">=</span> <span class="nv">pct_of_max_tests</span><span class="o">)</span><span class="o">)</span> <span class="o">+</span> 
  <span class="nf">geom_line</span><span class="o">(</span><span class="o">)</span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2021-02-27-oz-covid-vacc/figs/gg-prop-tests-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>Ooof. Ok, so let’s assume that we will do better than 25% of our maximum tests by filtering that out:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">covid_days_until_vac</span> <span class="o">%&gt;%</span> 
<span class="nf"><a href="https://rdrr.io/r/stats/filter.html">filter</a></span><span class="o">(</span><span class="nv">pct_of_max_tests</span> <span class="o">&gt;=</span> <span class="m">0.25</span><span class="o">)</span> <span class="o">%&gt;%</span> 
  <span class="nf">ggplot</span><span class="o">(</span><span class="nf">aes</span><span class="o">(</span>x <span class="o">=</span> <span class="nv">days_until_80_pct_aus_pop_vac</span>,
             y <span class="o">=</span> <span class="nv">pct_of_max_tests</span><span class="o">)</span><span class="o">)</span> <span class="o">+</span> 
  <span class="nf">geom_line</span><span class="o">(</span><span class="o">)</span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2021-02-27-oz-covid-vacc/figs/prop-tests-25-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>Hmmm, OK so if we want to do it within 1 year from now, looks like we’d need to do over 50% of our tests per day?</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">covid_days_until_vac</span> <span class="o">%&gt;%</span> 
<span class="nf"><a href="https://rdrr.io/r/stats/filter.html">filter</a></span><span class="o">(</span><span class="nv">pct_of_max_tests</span> <span class="o">&gt;=</span> <span class="m">0.50</span><span class="o">)</span> <span class="o">%&gt;%</span> 
  <span class="nf">ggplot</span><span class="o">(</span><span class="nf">aes</span><span class="o">(</span>x <span class="o">=</span> <span class="nv">days_until_80_pct_aus_pop_vac</span>,
             y <span class="o">=</span> <span class="nv">pct_of_max_tests</span><span class="o">)</span><span class="o">)</span> <span class="o">+</span> 
  <span class="nf">geom_line</span><span class="o">(</span><span class="o">)</span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2021-02-27-oz-covid-vacc/figs/prop-tests-50-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>And how many tests is that now? We can change the y axis to proportion of max tests.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">gg_covid_50pct_days</span> <span class="o">&lt;-</span> 
<span class="nv">covid_days_until_vac</span> <span class="o">%&gt;%</span> 
  <span class="nf"><a href="https://rdrr.io/r/stats/filter.html">filter</a></span><span class="o">(</span><span class="nv">pct_of_max_tests</span> <span class="o">&gt;=</span> <span class="m">0.50</span><span class="o">)</span> <span class="o">%&gt;%</span> 
  <span class="nf">ggplot</span><span class="o">(</span><span class="nf">aes</span><span class="o">(</span>x <span class="o">=</span> <span class="nv">days_until_80_pct_aus_pop_vac</span>,
             y <span class="o">=</span> <span class="nv">prop_of_max_tests</span><span class="o">)</span><span class="o">)</span> <span class="o">+</span> 
  <span class="nf">geom_line</span><span class="o">(</span><span class="o">)</span> <span class="o">+</span>
  <span class="nf">scale_y_continuous</span><span class="o">(</span>labels <span class="o">=</span> <span class="nf"><a href="https://scales.r-lib.org//reference/label_number.html">label_number</a></span><span class="o">(</span>big.mark <span class="o">=</span> <span class="s">","</span><span class="o">)</span><span class="o">)</span>
  
<span class="nv">gg_covid_50pct_days</span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2021-02-27-oz-covid-vacc/figs/prop-max-tests-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>Let’s say we want to be done by October 31, that is currently how many days away? We can use lubridate to work that out:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="kr"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="o">(</span><span class="nv"><a href="https://lubridate.tidyverse.org">lubridate</a></span><span class="o">)</span>
<span class="c">#&gt; </span>
<span class="c">#&gt; Attaching package: 'lubridate'</span>
<span class="c">#&gt; The following objects are masked from 'package:base':</span>
<span class="c">#&gt; </span>
<span class="c">#&gt;     date, intersect, setdiff, union</span>
<span class="nv">n_days_until_vac</span> <span class="o">&lt;-</span> <span class="nf"><a href="http://lubridate.tidyverse.org/reference/ymd.html">ymd</a></span><span class="o">(</span><span class="s">"2021-10-31"</span><span class="o">)</span> <span class="o">-</span> <span class="nf"><a href="http://lubridate.tidyverse.org/reference/now.html">today</a></span><span class="o">(</span><span class="o">)</span>
<span class="nv">n_days_until_vac</span>
<span class="c">#&gt; Time difference of 224 days</span></code></pre>
</div>
<p>So that’s 224 days.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">gg_covid_50pct_days</span> <span class="o">+</span> 
  <span class="nf">geom_vline</span><span class="o">(</span>xintercept <span class="o">=</span> <span class="nv">n_days_until_vac</span>,
             colour <span class="o">=</span> <span class="s">"red"</span>,
             lty <span class="o">=</span> <span class="m">2</span><span class="o">)</span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2021-02-27-oz-covid-vacc/figs/unnamed-chunk-1-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>And that means we need about this many tests per day:</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">n_tests_per_day_needed</span> <span class="o">&lt;-</span> 
<span class="nv">covid_days_until_vac</span> <span class="o">%&gt;%</span> 
  <span class="c"># there is no 224 days</span>
  <span class="nf"><a href="https://rdrr.io/r/stats/filter.html">filter</a></span><span class="o">(</span><span class="nv">days_until_80_pct_aus_pop_vac</span> <span class="o">&lt;=</span> <span class="m">225</span><span class="o">)</span> <span class="o">%&gt;%</span> 
  <span class="nf">slice_head</span><span class="o">(</span>n <span class="o">=</span> <span class="m">1</span><span class="o">)</span> <span class="o">%&gt;%</span> 
  <span class="nf">pull</span><span class="o">(</span><span class="nv">max_tests</span><span class="o">)</span>

<span class="nv">n_tests_per_day_needed</span>
<span class="c">#&gt; [1] 136194</span></code></pre>
</div>
<p>So we need doses per day to get there by October.</p>
</section>
<section id="what-are-covid-vaccinations-like-currently-in-australia" class="level1">
<h1>What are COVID vaccinations like currently in Australia?</h1>
<p>And because why not, let’s look at what COVID vaccinations are currently like in Australia.</p>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nv">aus_vac_url</span> <span class="o">&lt;-</span> <span class="s">"https://covidlive.com.au/report/daily-vaccinations/aus"</span>

<span class="nv">aus_test_data_raw</span> <span class="o">&lt;-</span> <span class="nf"><a href="https://rdrr.io/pkg/polite/man/bow.html">bow</a></span><span class="o">(</span><span class="nv">aus_vac_url</span><span class="o">)</span> <span class="o">%&gt;%</span> 
  <span class="nf"><a href="https://rdrr.io/pkg/polite/man/scrape.html">scrape</a></span><span class="o">(</span><span class="o">)</span> <span class="o">%&gt;%</span> 
  <span class="nf"><a href="https://rvest.tidyverse.org/reference/html_table.html">html_table</a></span><span class="o">(</span><span class="o">)</span> <span class="o">%&gt;%</span> 
  <span class="nf">purrr</span><span class="nf">::</span><span class="nf"><a href="https://purrr.tidyverse.org/reference/pluck.html">pluck</a></span><span class="o">(</span><span class="m">2</span><span class="o">)</span> <span class="o">%&gt;%</span> 
  <span class="nf">as_tibble</span><span class="o">(</span><span class="o">)</span> <span class="o">%&gt;%</span> 
  <span class="nf">janitor</span><span class="nf">::</span><span class="nf"><a href="https://rdrr.io/pkg/janitor/man/clean_names.html">clean_names</a></span><span class="o">(</span><span class="o">)</span> <span class="o">%&gt;%</span> 
  <span class="nf">mutate</span><span class="o">(</span>date <span class="o">=</span> <span class="nf">strp_date</span><span class="o">(</span><span class="nv">date</span><span class="o">)</span><span class="o">)</span> <span class="o">%&gt;%</span> 
  <span class="nf">mutate</span><span class="o">(</span>net <span class="o">=</span> <span class="nf">stringr</span><span class="nf">::</span><span class="nf"><a href="https://stringr.tidyverse.org/reference/str_replace.html">str_replace_all</a></span><span class="o">(</span>string <span class="o">=</span> <span class="nv">net</span>, 
                                        pattern <span class="o">=</span> <span class="s">"-"</span>, 
                                        replacement <span class="o">=</span> <span class="s">"0"</span><span class="o">)</span><span class="o">)</span> <span class="o">%&gt;%</span> 
  <span class="nf">mutate</span><span class="o">(</span><span class="nf">across</span><span class="o">(</span><span class="nf"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="o">(</span><span class="s">"cwealth"</span>, <span class="s">"doses"</span>, <span class="s">"net"</span><span class="o">)</span>, <span class="nv">parse_number</span><span class="o">)</span><span class="o">)</span> <span class="o">%&gt;%</span> 
  <span class="nf">rename</span><span class="o">(</span>daily_vacc <span class="o">=</span> <span class="nv">net</span><span class="o">)</span>

<span class="nv">aus_test_data_raw</span> 
<span class="c">#&gt; <span style="color: #555555;"># A tibble: 35 x 5</span></span>
<span class="c">#&gt;    date       cwealth  doses var   daily_vacc</span>
<span class="c">#&gt;    <span style="color: #555555;font-style: italic;">&lt;date&gt;</span><span>       </span><span style="color: #555555;font-style: italic;">&lt;dbl&gt;</span><span>  </span><span style="color: #555555;font-style: italic;">&lt;dbl&gt;</span><span> </span><span style="color: #555555;font-style: italic;">&lt;lgl&gt;</span><span>      </span><span style="color: #555555;font-style: italic;">&lt;dbl&gt;</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 1</span><span> 2021-03-21   </span><span style="text-decoration: underline;">50</span><span>000 </span><span style="text-decoration: underline;">256</span><span>782 </span><span style="color: #BB0000;">NA</span><span>          </span><span style="text-decoration: underline;">2</span><span>951</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 2</span><span> 2021-03-20   </span><span style="text-decoration: underline;">50</span><span>000 </span><span style="text-decoration: underline;">253</span><span>831 </span><span style="color: #BB0000;">NA</span><span>         </span><span style="text-decoration: underline;">13</span><span>077</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 3</span><span> 2021-03-19   </span><span style="text-decoration: underline;">50</span><span>000 </span><span style="text-decoration: underline;">240</span><span>754 </span><span style="color: #BB0000;">NA</span><span>         </span><span style="text-decoration: underline;">14</span><span>697</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 4</span><span> 2021-03-18   </span><span style="text-decoration: underline;">50</span><span>000 </span><span style="text-decoration: underline;">226</span><span>057 </span><span style="color: #BB0000;">NA</span><span>         </span><span style="text-decoration: underline;">22</span><span>500</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 5</span><span> 2021-03-17   </span><span style="text-decoration: underline;">45</span><span>607 </span><span style="text-decoration: underline;">203</span><span>557 </span><span style="color: #BB0000;">NA</span><span>         </span><span style="text-decoration: underline;">21</span><span>120</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 6</span><span> 2021-03-16   </span><span style="text-decoration: underline;">42</span><span>800 </span><span style="text-decoration: underline;">182</span><span>437 </span><span style="color: #BB0000;">NA</span><span>         </span><span style="text-decoration: underline;">17</span><span>656</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 7</span><span> 2021-03-15   </span><span style="text-decoration: underline;">39</span><span>760 </span><span style="text-decoration: underline;">164</span><span>781 </span><span style="color: #BB0000;">NA</span><span>          </span><span style="text-decoration: underline;">2</span><span>230</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 8</span><span> 2021-03-14   </span><span style="text-decoration: underline;">39</span><span>760 </span><span style="text-decoration: underline;">162</span><span>551 </span><span style="color: #BB0000;">NA</span><span>          </span><span style="text-decoration: underline;">3</span><span>257</span></span>
<span class="c">#&gt; <span style="color: #555555;"> 9</span><span> 2021-03-13   </span><span style="text-decoration: underline;">38</span><span>934 </span><span style="text-decoration: underline;">159</span><span>294 </span><span style="color: #BB0000;">NA</span><span>         </span><span style="text-decoration: underline;">24</span><span>191</span></span>
<span class="c">#&gt; <span style="color: #555555;">10</span><span> 2021-03-12   </span><span style="text-decoration: underline;">30</span><span>000 </span><span style="text-decoration: underline;">135</span><span>103 </span><span style="color: #BB0000;">NA</span><span>         </span><span style="text-decoration: underline;">10</span><span>103</span></span>
<span class="c">#&gt; <span style="color: #555555;"># … with 25 more rows</span></span></code></pre>
</div>
<div class="highlight">
<pre class="chroma"><code class="language-r" data-lang="r"><span class="nf">ggplot</span><span class="o">(</span><span class="nv">aus_test_data_raw</span>,
       <span class="nf">aes</span><span class="o">(</span>x <span class="o">=</span> <span class="nv">date</span>,
           y <span class="o">=</span> <span class="nv">doses</span><span class="o">)</span><span class="o">)</span> <span class="o">+</span> 
  <span class="nf">geom_line</span><span class="o">(</span><span class="o">)</span> <span class="o">+</span>
  <span class="nf">scale_y_continuous</span><span class="o">(</span>labels <span class="o">=</span> <span class="nf"><a href="https://scales.r-lib.org//reference/label_number.html">label_number</a></span><span class="o">(</span>big.mark <span class="o">=</span> <span class="s">","</span><span class="o">)</span><span class="o">)</span>
</code></pre>
<p><img src="https://www.njtierney.com/posts/2021-02-27-oz-covid-vacc/figs/show-current-vac-1.png" width="700px" style="display: block; margin: auto;"></p>
</div>
<p>Things are just starting out here in Australia with the vaccine, but we’re doing to need to see some pretty substantial ramp ups in the future to meet a goal date of the end of October.</p>


</section>

 ]]></description>
  <category>rstats</category>
  <category>covid19</category>
  <category>data visualisation</category>
  <category>ggplot2</category>
  <category>time series</category>
  <guid>https://www.njtierney.com/posts/2021-02-27-oz-covid-vacc/</guid>
  <pubDate>Sun, 21 Mar 2021 00:00:00 GMT</pubDate>
</item>
</channel>
</rss>
