<?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>Travis Hinkelman</title>
<link>https://www.travishinkelman.com/</link>
<atom:link href="https://www.travishinkelman.com/index.xml" rel="self" type="application/rss+xml"/>
<description>Personal website for Travis Hinkelman</description>
<generator>quarto-1.9.37</generator>
<lastBuildDate>Sun, 05 Apr 2026 00:00:00 GMT</lastBuildDate>
<item>
  <title>Join dataframes in Scheme</title>
  <link>https://www.travishinkelman.com/posts/join-dataframes-in-scheme.html</link>
  <description><![CDATA[ 




<p>This post is part of a series on the <a href="https://hinkelman.github.io/dataframe/"><code>dataframe</code> library</a> for Scheme (R6RS). In this post, I will contrast functions for joining dataframes from the <code>dataframe</code> library with the <a href="https://dplyr.tidyverse.org"><code>dplyr</code> package</a> for R.</p>
<section id="set-up" class="level3">
<h3 class="anchored" data-anchor-id="set-up">Set up</h3>
<p>First, let’s create a couple of dataframes in both languages.</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;">library</span>(dplyr)</span>
<span id="cb1-2"></span>
<span id="cb1-3">df1 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">data.frame</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Alice"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Bob"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Carol"</span>),</span>
<span id="cb1-4">                  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">age =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">25</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">35</span>))</span>
<span id="cb1-5"></span>
<span id="cb1-6">df2 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">data.frame</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Bob"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Carol"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Dave"</span>),</span>
<span id="cb1-7">                  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dept =</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;">"Sales"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Engineering"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Marketing"</span>))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb2-1">(import (dataframe))</span>
<span id="cb2-2"></span>
<span id="cb2-3">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> df1</span></span>
<span id="cb2-4">  (make-df* (name <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Alice"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Bob"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Carol"</span>)</span>
<span id="cb2-5">            (age <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">25</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">35</span>)))</span>
<span id="cb2-6"></span>
<span id="cb2-7">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> df2</span></span>
<span id="cb2-8">  (make-df* (name <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Bob"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Carol"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Dave"</span>)</span>
<span id="cb2-9">            (dept <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Sales"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Engineering"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Marketing"</span>)))</span></code></pre></div></div>
</section>
<section id="left-join" class="level3">
<h3 class="anchored" data-anchor-id="left-join">Left join</h3>
<p>In R, <code>left_join</code> keeps all rows from the left dataframe and adds matching columns from the right dataframe, filling <code>NA</code> for non-matches.</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="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">left_join</span>(df1, df2)</span>
<span id="cb3-2">   name age        dept</span>
<span id="cb3-3"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> Alice  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30</span>        <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NA</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb3-4"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>   Bob  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">25</span>       Sales</span>
<span id="cb3-5"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> Carol  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">35</span> Engineering</span></code></pre></div></div>
<p><code>dataframe-left-join</code> works similarly. When <code>join-names</code> is <code>#f</code> or omitted, the join columns are auto-detected from the common column names. Because Scheme doesn’t have explicit missing values, <code>'na</code> is used by default, but a different fill value can be specified.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb4-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (dataframe-display (dataframe-left-join df1 df2))</span>
<span id="cb4-2"></span>
<span id="cb4-3"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> cols</span>
<span id="cb4-4">    name     age        dept </span>
<span id="cb4-5">   &lt;str&gt;   &lt;num&gt;       &lt;str&gt; </span>
<span id="cb4-6">   Alice      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30</span>.         na </span>
<span id="cb4-7">     Bob      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">25</span>.      Sales </span>
<span id="cb4-8">   Carol      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">35</span>. Engineering </span></code></pre></div></div>
</section>
<section id="inner-join" class="level3">
<h3 class="anchored" data-anchor-id="inner-join">Inner join</h3>
<p><code>inner_join</code> keeps only rows that have matches in both dataframes.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb5-1"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">inner_join</span>(df1, df2)</span>
<span id="cb5-2">   name age        dept</span>
<span id="cb5-3"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>   Bob  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">25</span>       Sales</span>
<span id="cb5-4"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> Carol  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">35</span> Engineering</span></code></pre></div></div>
<p><code>dataframe-inner-join</code> works the same way.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb6-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (dataframe-display (dataframe-inner-join df1 df2))</span>
<span id="cb6-2"></span>
<span id="cb6-3"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> cols</span>
<span id="cb6-4">    name     age        dept </span>
<span id="cb6-5">   &lt;str&gt;   &lt;num&gt;       &lt;str&gt; </span>
<span id="cb6-6">     Bob      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">25</span>.      Sales </span>
<span id="cb6-7">   Carol      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">35</span>. Engineering </span></code></pre></div></div>
</section>
<section id="full-join" class="level3">
<h3 class="anchored" data-anchor-id="full-join">Full join</h3>
<p><code>full_join</code> keeps all rows from both dataframes, filling missing values where there is no match.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb7-1"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">full_join</span>(df1, df2)</span>
<span id="cb7-2">   name age        dept</span>
<span id="cb7-3"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> Alice  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30</span>        <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NA</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb7-4"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>   Bob  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">25</span>       Sales</span>
<span id="cb7-5"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> Carol  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">35</span> Engineering</span>
<span id="cb7-6"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>  Dave  <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NA</span>   Marketing</span></code></pre></div></div>
<p><code>dataframe-full-join</code> fills missing values with <code>'na</code> by default.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb8-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (dataframe-display (dataframe-full-join df1 df2))</span>
<span id="cb8-2"></span>
<span id="cb8-3"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> cols</span>
<span id="cb8-4">    name     age        dept </span>
<span id="cb8-5">   &lt;str&gt;   &lt;num&gt;       &lt;str&gt; </span>
<span id="cb8-6">   Alice      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30</span>.         na </span>
<span id="cb8-7">     Bob      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">25</span>.      Sales </span>
<span id="cb8-8">   Carol      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">35</span>. Engineering </span>
<span id="cb8-9">    Dave       na   Marketing </span></code></pre></div></div>
</section>
<section id="joining-on-different-column-names" class="level3">
<h3 class="anchored" data-anchor-id="joining-on-different-column-names">Joining on different column names</h3>
<p>In <code>dplyr</code>, when the join columns have different names in each dataframe, you specify the mapping with a named vector.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb9-1"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> df3 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">data.frame</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">person =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Bob"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Carol"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Dave"</span>),</span>
<span id="cb9-2">                    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dept =</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;">"Sales"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Engineering"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Marketing"</span>))</span>
<span id="cb9-3"></span>
<span id="cb9-4"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">left_join</span>(df1, df3, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">by =</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;">"name"</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"person"</span>))</span>
<span id="cb9-5">   name age        dept</span>
<span id="cb9-6"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> Alice  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30</span>        <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NA</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb9-7"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>   Bob  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">25</span>       Sales</span>
<span id="cb9-8"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> Carol  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">35</span> Engineering</span></code></pre></div></div>
<p>In the <code>dataframe</code> library, the <code>join-names</code> argument accepts a list of pairs mapping column names from <code>df1</code> to <code>df3</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb10-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> df3</span></span>
<span id="cb10-2">    (make-df* (person <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Bob"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Carol"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Dave"</span>)</span>
<span id="cb10-3">              (dept <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Sales"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Engineering"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Marketing"</span>)))</span>
<span id="cb10-4"></span>
<span id="cb10-5"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (dataframe-display</span>
<span id="cb10-6">   (dataframe-left-join df1 df3 '((name <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span> person))))</span>
<span id="cb10-7"></span>
<span id="cb10-8"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> cols</span>
<span id="cb10-9">    name     age        dept </span>
<span id="cb10-10">   &lt;str&gt;   &lt;num&gt;       &lt;str&gt; </span>
<span id="cb10-11">   Alice      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30</span>.         na </span>
<span id="cb10-12">     Bob      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">25</span>.      Sales </span>
<span id="cb10-13">   Carol      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">35</span>. Engineering </span></code></pre></div></div>
<p>The <code>join-names</code> argument supports three forms: <code>#f</code> (or omitted) for auto-detecting common names, a list of symbols for same-named columns (e.g., <code>'(name dept)</code>), and a list of pairs for differently-named columns (e.g., <code>'((name . person))</code>).</p>
</section>
<section id="left-join-all" class="level3">
<h3 class="anchored" data-anchor-id="left-join-all">Left join all</h3>
<p><code>left_join</code> only takes two dataframes at a time. To left join a list of dataframes, you could use <code>purrr::reduce</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb11-1">purrr<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;">reduce</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">list</span>(df1, df2), left_join)</span></code></pre></div></div>
<p><code>dataframe-left-join-all</code> takes a list of dataframes and sequentially left joins them.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb12-1">(dataframe-display (dataframe-left-join-all (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">list</span> df1 df2)))</span></code></pre></div></div>
</section>
<section id="implementation" class="level3">
<h3 class="anchored" data-anchor-id="implementation">Implementation</h3>
<p>All four join procedures follow the same overall strategy: split both dataframes by the join columns, match groups between the two sets of splits, and then bind the results back together.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb13-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> dataframe-left-join</span></span>
<span id="cb13-2">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case-lambda</span></span>
<span id="cb13-3">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(df1 df2)</span>
<span id="cb13-4">     (dataframe-left-join df1 df2 <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#f</span> 'na)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb13-5">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(df1 df2 join-names)</span>
<span id="cb13-6">     (dataframe-left-join df1 df2 join-names 'na)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb13-7">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(df1 df2 join-names fill-value)</span>
<span id="cb13-8">     (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let*</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>who <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(dataframe-left-join df1 df2 join-names fill-value)"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb13-9">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>names-pair (parse-join-names df1 df2 join-names)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb13-10">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>names1 (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> names-pair)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb13-11">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>names2 (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cadr</span> names-pair)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb13-12">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>df2-aligned (align-df2 df2 names2 names1 who)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb13-13">       (check-join df1 df2-aligned names1 who)</span>
<span id="cb13-14">       (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>slists1 (dataframe-split-helper df1 names1 who)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb13-15">             <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>slists2 (dataframe-split-helper df2-aligned names1 who)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb13-16">         (dataframe-bind-all</span>
<span id="cb13-17">          (df-left-join-helper slists1 slists2 names1 fill-value))))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>))</span></code></pre></div></div>
<p>First, <code>parse-join-names</code> resolves the three supported forms of <code>join-names</code> into a pair of name lists, one for each dataframe. When <code>join-names</code> is <code>#f</code>, it finds the column names common to both dataframes. If the join columns have different names, <code>align-df2</code> renames the columns in <code>df2</code> to match <code>df1</code> so the rest of the join machinery can work with a single set of names.</p>
<p>Both dataframes are then split into groups by the join columns using <code>dataframe-split-helper</code>. The split produces a list of slists (lists of series), one per unique combination of join-column values.</p>
<section id="matching-groups" class="level4">
<h4 class="anchored" data-anchor-id="matching-groups">Matching groups</h4>
<p>The core of each join variant is a helper that iterates over the groups from <code>df1</code> and looks for matching groups in <code>df2</code>. A group’s identity is determined by <code>get-join-group</code>, which extracts the values from the first row of the join columns (all rows have the same values because the slist was split on those columns).</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb14-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">get-join-group </span>slist join-names)</span>
<span id="cb14-2">  (apply <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">append</span> (map series-lst (slist-ref slist '(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) join-names))))</span></code></pre></div></div>
<p>For the left join, each group from <code>df1</code> is checked against an association list built from <code>df2</code>’s groups. If a match is found, the two groups are combined with <code>join-match</code>. If not, the non-join columns from <code>df2</code> are filled with <code>fill-value</code> via <code>join-no-match</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb15-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">df-left-join-helper </span>slists1 slists2 join-names fill-value)</span>
<span id="cb15-2">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let*</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>grps2 (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (x) (get-join-group x join-names)) slists2)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb15-3">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>grps2-slists2 (map <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cons</span> grps2 slists2)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb15-4">    (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (slist)</span>
<span id="cb15-5">           (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let*</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>grp (get-join-group slist join-names)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb15-6">                  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>grp-match (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">assoc</span> grp grps2-slists2)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb15-7">             (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> grp-match</span>
<span id="cb15-8">                 (join-match slist (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cdr</span> grp-match) join-names)</span>
<span id="cb15-9">                 (join-no-match slist (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> slists2) join-names fill-value))))</span>
<span id="cb15-10">         slists1)))</span></code></pre></div></div>
<p>The inner join helper is similar but simply drops groups from <code>df1</code> that have no match, using a <code>loop</code> with an accumulator rather than <code>map</code>. The full join helper additionally tracks which <code>df2</code> groups have been matched and appends the unmatched ones at the end, with the <code>df1</code> non-join columns filled.</p>
</section>
<section id="combining-matched-groups" class="level4">
<h4 class="anchored" data-anchor-id="combining-matched-groups">Combining matched groups</h4>
<p>When two groups match, <code>join-match</code> drops the join columns from <code>slist2</code> (to avoid duplication) and appends the remaining columns. If the two groups have different numbers of rows, the shorter one is repeated to match the longer one.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb16-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">join-match </span>slist1 slist2 join-names)</span>
<span id="cb16-2">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let*</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>n1 (series-length (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> slist1))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb16-3">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>n2 (series-length (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> slist2))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb16-4">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>slist2-drop (slist-drop slist2 join-names)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb16-5">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>slist1-new (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> n1 n2)</span>
<span id="cb16-6">                         slist1</span>
<span id="cb16-7">                         (slist-repeat-rows slist1 n2 'times))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb16-8">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>slist2-new (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> n2 n1)</span>
<span id="cb16-9">                         slist2-drop</span>
<span id="cb16-10">                         (slist-repeat-rows slist2-drop n1 'times))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb16-11">    (make-dataframe (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">append</span> slist1-new slist2-new))))</span></code></pre></div></div>
<p>This row-repeating behavior is how the library handles many-to-many relationships within a group. If <code>df1</code> has 2 rows for a given group and <code>df2</code> has 3, the <code>df1</code> rows are repeated to length 3 (and vice versa). This is a simpler approach than producing a full cross product.</p>
<p>When there is no match, <code>join-no-match</code> retains all columns from the unmatched slist and fills the non-join columns from the other dataframe with <code>fill-value</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb17-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">join-no-match </span>slist1 slist2 join-names fill-value)</span>
<span id="cb17-2">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let*</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>n (series-length (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> slist1))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb17-3">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>slist2-names (map series-name slist2)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb17-4">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>slist2-names-sel (not-in slist2-names join-names)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb17-5">    (make-dataframe</span>
<span id="cb17-6">     (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">append</span> slist1 (slist-fill-missing slist2-names-sel n fill-value)))))</span></code></pre></div></div>
</section>
</section>
<section id="conclusions" class="level3">
<h3 class="anchored" data-anchor-id="conclusions">Conclusions</h3>
<p>The join procedures follow the same split-apply-combine pattern used by other procedures in the <code>dataframe</code> library. Splitting both dataframes by join columns reduces the problem to matching and combining small groups, which makes the logic for each join variant straightforward. The <code>parse-join-names</code> and <code>align-df2</code> steps handle the bookkeeping of resolving column name differences before the main join logic runs. The design is inspired by the <code>dplyr</code> family of join functions, though the handling of many-to-many matches uses row repetition rather than a full cross product.</p>


</section>

 ]]></description>
  <category>Scheme</category>
  <category>dataframe</category>
  <category>R</category>
  <category>dplyr</category>
  <guid>https://www.travishinkelman.com/posts/join-dataframes-in-scheme.html</guid>
  <pubDate>Sun, 05 Apr 2026 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Display and glimpse dataframes in Scheme</title>
  <link>https://www.travishinkelman.com/posts/display-and-glimpse-dataframes-scheme.html</link>
  <description><![CDATA[ 




<p>This post is part of a series on the <a href="https://hinkelman.github.io/dataframe/">dataframe library</a> for Scheme (R6RS). In this post, I will describe <code>dataframe-display</code> and <code>dataframe-glimpse</code>, which are inspired by the default print format for <a href="https://tibble.tidyverse.org">tibbles</a> in R and the <a href="https://dplyr.tidyverse.org/reference/glimpse.html"><code>dplyr::glimpse</code></a> function. Both procedures rely heavily on Chez Scheme’s <code>format</code> procedure, so I will first give an overview of the format directives used in the <code>dataframe</code> library before showing how <code>dataframe-display</code> and <code>dataframe-glimpse</code> work.</p>
<section id="format-directives" class="level3">
<h3 class="anchored" data-anchor-id="format-directives">Format directives</h3>
<p>Chez Scheme’s <code>format</code> procedure is modeled on Common Lisp’s <code>format</code> and supports a rich set of directives for controlling output. The first argument to <code>format</code> is the destination: <code>#t</code> sends output to the current output port (i.e., prints to screen), <code>#f</code> returns the result as a string, and a port sends output to that port.</p>
<p>The general form is:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb1-1">(format destination format-string arg <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span>)</span></code></pre></div></div>
<p>Directives are embedded in the format string as <code>~</code> followed by a character, with optional numeric parameters before the character. Here are the directives used in <code>dataframe-display</code> and <code>dataframe-glimpse</code>.</p>
<p><strong><code>~d</code></strong> prints an integer in decimal notation.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb2-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (format <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#t</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"~d rows x ~d cols"</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)</span>
<span id="cb2-2"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> cols</span></code></pre></div></div>
<p><strong><code>~a</code></strong> prints a value in human-readable form, e.g., strings without quotes, characters without the <code>#\</code> prefix.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb3-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (format <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#t</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"~a"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"hello"</span>)</span>
<span id="cb3-2">hello</span>
<span id="cb3-3"></span>
<span id="cb3-4"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (format <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#t</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"~a"</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">#\x)</span></span>
<span id="cb3-5">x</span></code></pre></div></div>
<p><strong><code>~Na</code></strong> adds a minimum field width of <code>N</code>, padding on the right (left-aligning the value). <strong><code>~N@a</code></strong> pads on the left instead, right-aligning the value in a field of width <code>N</code>. The <code>@</code> modifier means “use left padding”, which produces right-alignment. This is used throughout <code>dataframe-display</code> to align columns.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb4-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (format <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#t</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"~10a|"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"hi"</span>)</span>
<span id="cb4-2">hi        |</span>
<span id="cb4-3"></span>
<span id="cb4-4"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (format <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#t</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"~10@a|"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"hi"</span>)</span>
<span id="cb4-5">        hi|</span></code></pre></div></div>
<p><strong><code>~N,Df</code></strong> prints a floating-point number in a field of width <code>N</code> with <code>D</code> digits after the decimal point.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb5-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (format <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#t</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"~10,2f"</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.14159</span>)</span>
<span id="cb5-2">      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.14</span></span></code></pre></div></div>
<p><strong><code>~N,D,Ee</code></strong> prints a number in exponential notation in a field of width <code>N</code>, with <code>D</code> decimal digits and <code>E</code> digits in the exponent.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb6-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (format <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#t</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"~12,3,1e"</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.000012345</span>)</span>
<span id="cb6-2">   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.234e-5</span></span></code></pre></div></div>
<p><strong><code>~&amp;</code></strong> emits a newline only if the output is not already at the start of a line. <strong><code>~%</code></strong> emits an unconditional newline. In practice, <code>~&amp;</code> is used at the start of format strings in this library to ensure each row of the table starts on its own line.</p>
<p><strong><code>~{...~}</code></strong> is the iteration directive. It consumes one argument from the argument list, which must be a flat list, and consumes elements of the list as arguments to the directives in the body.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb7-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (format <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#t</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"~{~a ~}"</span> '(a b c))</span>
<span id="cb7-2">a b c </span></code></pre></div></div>
<p><strong><code>~:{...~}</code></strong> is similar but iterates over a list of sublists. Each sublist provides the arguments for one iteration of the body.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb8-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (format <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#t</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"~:{~&amp; ~a ~a~}"</span> '((a <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) (b <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>) (c <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)))</span>
<span id="cb8-2"> a <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span>
<span id="cb8-3"> b <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span></span>
<span id="cb8-4"> c <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span></span></code></pre></div></div>
<p>This distinction between <code>~{~}</code> and <code>~:{~}</code> is central to how <code>dataframe-display</code> works, as we’ll see below.</p>
</section>
<section id="dataframe-display" class="level3">
<h3 class="anchored" data-anchor-id="dataframe-display">dataframe-display</h3>
<p><code>dataframe-display</code> prints a formatted table showing the dataframe dimensions, column names, column types, and up to <code>n</code> rows of values.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb9-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> dataframe-display</span></span>
<span id="cb9-2">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case-lambda</span></span>
<span id="cb9-3">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(df) (df-display-helper df <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">76</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb9-4">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(df n) (df-display-helper df n <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">76</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb9-5">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(df n total-width) (df-display-helper df n total-width <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb9-6">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(df n total-width min-width) (df-display-helper df n total-width min-width)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>))</span></code></pre></div></div>
<p>The defaults are 10 rows, a total width of 76 characters, and a minimum column width of 7. If a dataframe has more columns than fit in <code>total-width</code>, the extra columns are omitted and listed in a footer.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb10-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> df</span></span>
<span id="cb10-2">    (make-df*</span>
<span id="cb10-3">     (Boolean <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#t</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#f</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#t</span>)</span>
<span id="cb10-4">     (Char <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">#\y</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">#\e</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">#\s</span>)</span>
<span id="cb10-5">     (String <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"these"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"are"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"strings"</span>)</span>
<span id="cb10-6">     (Symbol 'these 'are 'symbols)</span>
<span id="cb10-7">     (Exact <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>/2 <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>/3 <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>/4)</span>
<span id="cb10-8">     (Integer <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> -<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)</span>
<span id="cb10-9">     (Expt <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000000.0</span> -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">123456.0</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.2346e-6</span>)</span>
<span id="cb10-10">     (Dec4 <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">132.1</span> -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">157.0</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">10.234</span>)</span>
<span id="cb10-11">     (Dec2 <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">12.14</span> -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">9.54</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">100.01</span>)</span>
<span id="cb10-12">     (Other '(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>) '#(a b) '#(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>))))</span>
<span id="cb10-13"></span>
<span id="cb10-14"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (dataframe-display df)</span>
<span id="cb10-15"></span>
<span id="cb10-16"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> cols</span>
<span id="cb10-17">  Boolean    Char  String  Symbol   Exact Integer      Expt    Dec4 </span>
<span id="cb10-18">   &lt;bool&gt;    &lt;chr&gt;   &lt;str&gt;   &lt;sym&gt;   &lt;num&gt;   &lt;num&gt;     &lt;num&gt;   &lt;num&gt; </span>
<span id="cb10-19">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#t</span>       y   these   these     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>/2      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.000e6</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">132.1000</span> </span>
<span id="cb10-20">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#f</span>       e     are     are     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>/3     -<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>. -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.235e5</span> -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">157.0000</span> </span>
<span id="cb10-21">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#t</span>       s strings symbols     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>/4      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.235e-6</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">10.2340</span> </span>
<span id="cb10-22"> Columns <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> displayed: Dec2, Other</span></code></pre></div></div>
<p>The output has four components. The first line shows the full dimensions. Then the column names and types, each right-aligned in a field sized to accommodate the widest value in that column. The table rows follow, with numeric columns formatted using <code>~f</code> or <code>~e</code> depending on the magnitude of the values. Any columns that don’t fit within <code>total-width</code> are listed in the footer.</p>
<section id="building-the-format-strings" class="level4">
<h4 class="anchored" data-anchor-id="building-the-format-strings">Building the format strings</h4>
<p>The most intricate part of <code>dataframe-display</code> is <code>build-format-parts</code>, which constructs three separate format strings (header row, the types row, and the table) by iterating over columns left to right and accumulating directives as long as the column fits within <code>total-width</code>.</p>
<p>The header and types rows use <code>~{...~}</code> because they iterate over a flat list of names or type strings. The table uses <code>~:{...~}</code> because it iterates over a list of rows (sublists).</p>
<p>The format strings are built up incrementally. For each column, a width-part is computed (e.g., <code>"~10"</code>) and combined with <code>"@a "</code> for the header and types rows, or with a numeric directive suffix for the table. For example, a floating-point column of width 10 with 4 decimal places contributes <code>"~10,4f "</code> to the table format string and <code>"~10@a "</code> to the header and types format strings.</p>
<p>Here is a simplified illustration of what the final format strings look like for a dataframe with one string column and one numeric column:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb11-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; header:  "~&amp; ~{~8@a ~10@a ~}"  applied to  (Name Score)</span></span>
<span id="cb11-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; types:   "~&amp; ~{~8@a ~10@a ~}"  applied to  ("&lt;str&gt;" "&lt;num&gt;")</span></span>
<span id="cb11-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; table:   "~:{~&amp; ~8@a ~10,4f ~}" applied to  (("Alice" 98.5) ("Bob" 72.1))</span></span></code></pre></div></div>
<p>The <code>~&amp;</code> at the start of each format string ensures each row begins on a new line. The <code>~}</code> or <code>~}</code> closes the iteration. The values are assembled in <code>format-df</code>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb12-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">format-df </span>df-names df-types ls-vals dim total-width min-width)</span>
<span id="cb12-2">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let*</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>prep-vals (map prepare-non-numbers ls-vals)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb12-3">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>parts (build-format-parts df-names df-types prep-vals total-width min-width <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb12-4">    (format <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#t</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">" dim: ~d rows x ~d cols"</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> dim) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cdr</span> dim))</span>
<span id="cb12-5">    (format <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#t</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cadr</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">assoc</span> 'header parts)) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">caddr</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">assoc</span> 'header parts)))</span>
<span id="cb12-6">    (format <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#t</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cadr</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">assoc</span> 'types parts))  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">caddr</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">assoc</span> 'types parts)))</span>
<span id="cb12-7">    (format <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#t</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cadr</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">assoc</span> 'table parts))  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">caddr</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">assoc</span> 'table parts)))</span>
<span id="cb12-8">    (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">newline</span>)</span>
<span id="cb12-9">    (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">display</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cdr</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">assoc</span> 'footer parts)))))</span></code></pre></div></div>
<p>Each call to <code>format</code> here takes the format string (the <code>cadr</code> of the alist entry) and the corresponding list of values (the <code>caddr</code>).</p>
</section>
<section id="numeric-formatting" class="level4">
<h4 class="anchored" data-anchor-id="numeric-formatting">Numeric formatting</h4>
<p>For columns containing only numbers, <code>dataframe-display</code> chooses between floating-point (<code>~f</code>) and exponential (<code>~e</code>) notation based on the magnitude of the values. The logic is in <code>compute-decimal</code>, which returns the number of decimal places to use. If any value in the column is assigned the maximum decimal count (the threshold for “very large or very small”), the whole column is displayed in exponential notation; otherwise floating-point is used.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb13-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">compute-decimal </span>x sigfig e e-dec)</span>
<span id="cb13-2">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>default <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb13-3">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>x (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">abs</span> x)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb13-4">    (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cond</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">or</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> e -<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> e <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>)) e-dec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; exponential notation</span></span>
<span id="cb13-5">          <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">integer?</span> x) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb13-6">          <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> e <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>                    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; fewer decimals for large numbers</span></span>
<span id="cb13-7">          <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> sigfig default)) sigfig<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb13-8">          <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> default<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)))</span></code></pre></div></div>
<p>The <code>e</code> argument is the base-10 exponent (order of magnitude) of the value, computed via <code>compute-expt</code>. So a value like <code>1000000.0</code> has <code>e = 6</code>, which exceeds the threshold of 5 and triggers exponential notation for the entire column.</p>
<p>Column widths for numeric columns are computed separately from non-numeric ones. For a floating-point column, the width is <code>neg + sig + dec + pad</code>, where <code>neg</code> is 1 if any value is negative (to accommodate the minus sign), <code>sig</code> is the number of digits left of the decimal point, <code>dec</code> is the number of decimal places, and <code>pad</code> is spacing between columns.</p>
</section>
<section id="non-numeric-values" class="level4">
<h4 class="anchored" data-anchor-id="non-numeric-values">Non-numeric values</h4>
<p>Columns that are not purely numeric, or that contain exact fractions like <code>1/3</code>, are handled by <code>prepare-non-numbers</code>. Compound objects like lists, vectors, and hashtables are replaced with placeholder strings such as <code>&lt;list&gt;</code> or <code>&lt;vector&gt;</code>. Primitive non-numeric values (booleans, characters, strings, symbols) are displayed with <code>~a</code>.</p>
<p>Exact fractions are routed through <code>compute-object-width</code> rather than <code>compute-num-width</code> because their string representation (e.g., <code>"1/3"</code>) has a width that is easier to measure directly.</p>
</section>
</section>
<section id="dataframe-glimpse" class="level3">
<h3 class="anchored" data-anchor-id="dataframe-glimpse">dataframe-glimpse</h3>
<p><code>dataframe-glimpse</code> provides a transposed summary of the dataframe: one row per column, showing the column name, type, and as many values as fit across the screen. It is inspired by <code>dplyr::glimpse</code> in R, which is useful for dataframes with many columns that don’t fit comfortably in a standard tabular display.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb14-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> dataframe-glimpse</span></span>
<span id="cb14-2">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case-lambda</span></span>
<span id="cb14-3">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(df) (df-glimpse-helper df <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">76</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb14-4">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(df total-width) (df-glimpse-helper df total-width)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb15-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (dataframe-glimpse df)</span>
<span id="cb15-2"></span>
<span id="cb15-3"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> cols</span>
<span id="cb15-4"> Boolean  &lt;bool&gt;  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#t</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#f</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#t</span></span>
<span id="cb15-5"> Char     &lt;chr&gt;   y e s</span>
<span id="cb15-6"> String   &lt;str&gt;   these are strings</span>
<span id="cb15-7"> Symbol   &lt;sym&gt;   these are symbols</span>
<span id="cb15-8"> Exact    &lt;num&gt;   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>/2 <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>/3 <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>/4</span>
<span id="cb15-9"> Integer  &lt;num&gt;   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> -<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span></span>
<span id="cb15-10"> Expt     &lt;num&gt;   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000000.0</span> -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">123456.0</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.2346e-6</span></span>
<span id="cb15-11"> Dec4     &lt;num&gt;   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">132.1</span> -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">157.0</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">10.234</span></span>
<span id="cb15-12"> Dec2     &lt;num&gt;   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">12.14</span> -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">9.54</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">100.01</span></span>
<span id="cb15-13"> Other    &lt;other&gt; &lt;list&gt; &lt;vector&gt; &lt;vector&gt;</span></code></pre></div></div>
<p>Unlike <code>dataframe-display</code>, glimpse shows all columns regardless of width, since each column occupies its own row. The values for each column are rendered as a truncated flat list (without parentheses) by <code>prepare-lst</code>, which appends values separated by spaces until the remaining width is exhausted, then appends <code>", ..."</code> to signal truncation.</p>
<section id="the-glimpse-format-string" class="level4">
<h4 class="anchored" data-anchor-id="the-glimpse-format-string">The glimpse format string</h4>
<p>The glimpse format string is built by <code>glimpse-format-string</code> and uses <code>~:{...~}</code> to iterate over a list of <code>(name type values-string)</code> triples. Each iteration prints one column’s row.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb16-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">glimpse-format-string </span>name-width type-width list-width)</span>
<span id="cb16-2">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let*</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>nw (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">number-&gt;string</span> name-width)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb16-3">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>tw (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">number-&gt;string</span> type-width)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb16-4">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>lw (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">number-&gt;string</span> list-width)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb16-5">    (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string-append</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"~:{~&amp; ~"</span> nw <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"a ~"</span> tw <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"a ~"</span> lw <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"a ~}"</span>)))</span></code></pre></div></div>
<p>Notice that <code>~Na</code> is used here (without <code>@</code>), producing left-aligned output. This gives each column’s name, type, and values left-aligned in their respective fields because it is a row-oriented display where values are a freeform list rather than values in a fixed-width column.</p>
<p>The three field widths are computed from the data: <code>name-width</code> is the width of the longest column name (minimum 7), <code>type-width</code> is the width of the longest type string (minimum 7), and <code>list-width</code> is whatever space remains after subtracting the other two from <code>total-width</code>.</p>
<p>The <code>(name type values-string)</code> triples are assembled by <code>build-format-list</code> and passed as a single argument to the <code>~:{...~}</code> directive:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb17-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">build-format-list </span>df-names df-types list-str)</span>
<span id="cb17-2">  (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (n t ls) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">list</span> n t ls)) df-names df-types list-str))</span></code></pre></div></div>
<p>For example, on a terminal 76 characters wide, <code>glimpse-format-string</code> might produce the string <code>"~:{~&amp; ~9a ~7a ~57a ~}"</code>, which is then applied to the list of triples in a single <code>format</code> call.</p>
</section>
</section>
<section id="conclusions" class="level3">
<h3 class="anchored" data-anchor-id="conclusions">Conclusions</h3>
<p>Implementing <code>dataframe-display</code> and <code>dataframe-glimpse</code> turned out to require the most complex code in the dataframe library. Getting the column widths right across different numeric types, handling exponential versus floating-point notation, and fitting columns within a total width all interact in ways that took considerable trial and error to get right. The design of <code>dataframe-display</code> was directly inspired by the way tibbles print in R. Tibbles show the dimensions, column types below the names, and truncate to a fixed number of rows by default. <code>dataframe-glimpse</code> follows <code>dplyr::glimpse</code> in transposing the view so that every column appears on its own line, making wide dataframes much easier to inspect at a glance.</p>


</section>

 ]]></description>
  <category>Scheme</category>
  <category>dataframe</category>
  <category>R</category>
  <category>dplyr</category>
  <guid>https://www.travishinkelman.com/posts/display-and-glimpse-dataframes-scheme.html</guid>
  <pubDate>Wed, 01 Apr 2026 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Electric vehicles in California</title>
  <link>https://www.travishinkelman.com/posts/electric-vehicles-california.html</link>
  <description><![CDATA[ 




<p>I bought my first electric vehicle (EV) about a month ago and I thought it would be useful to capture my decision making around this purchase and initial impressions of driving an EV. I also thought it would be fun to use my Scheme <a href="https://github.com/hinkelman/dataframe/"><code>dataframe</code></a> library to explore data on EVs in California.</p>
<p>The decision to buy an EV was relatively abrupt. I wanted to replace the 2012 Honda Civic that my son was driving and considered buying an e-bike to fill our transportation needs by sharing my 2017 Toyota Prius, biking, and using public transportation. Our brief experiment with sharing one car left me feeling inconvenienced, though, and I wasn’t convinced that an e-bike would alleviate those feelings.</p>
<p>I had heard that used EVs were reasonably affordable right now and was persuaded by arguments about the practical advantages of used EVs (e.g., <a href="https://youtu.be/wbmCIQHYUCs?si=OUbwxarL1VTi0agj">this video</a>). My initial thinking was that I would take my chances on a relatively cheap used EV ($12-14k), but the caliber of the cars in that price range made me too nervous about battery health. In the $15-18k price range, some of the most commonly available EVs included the 2016-2018 BMW i3 and 2022-2024 Nissan LEAF. It’s easy to find highly favorable reviews of used BMW i3s and my affinity for small cars had me leaning in that direction. Ultimately, though, I couldn’t pass up on the peace of mind associated with buying a newer LEAF with lower specs but more remaining battery warranty. So I bought a 2024 Nissan LEAF S from Carvana for about $17k.</p>
<div class="page-columns page-full"><p>The 1st and 2nd generation LEAFs (which takes you through the 2025 model year) have two fatal flaws.  One is that it uses a DC fast-charging standard (CHAdeMO) that is being phased out in North America. The other is that there is no active battery thermal management. The lack of battery conditioning means that when you operate the car outside of the optimal range for the battery you lose driving range and potentially increase the rate of battery degradation.</p><div class="no-row-height column-margin column-container"><span class="margin-aside">These flaws are not actually fatal if you can charge at home, don’t live in a hot climate, and are not planning to use the LEAF for road trips.</span></div></div>
<div class="page-columns page-full"><p>I have struggled a bit with the perceived limitations of driving a relatively short-range EV like the LEAF even though it arguably covers &gt;90% of my usage needs.  First of all, I was in the habit of refueling my gas tank when it approached 1/4 tank even though that likely equated to 100+ miles of range in the fuel efficient cars that I’ve been driving over the past 10+ years. With my LEAF, 100 miles of range is approaching the max that I would be willing to travel before charging. That requires a big shift in my thinking. Plus, the road trip limitations carry a general sense of a loss of freedom (which would not be a concern with a longer range EV).</p><div class="no-row-height column-margin column-container"><span class="margin-aside">The vast majority (<a href="https://afdc.energy.gov/data/10318">93%</a>) of U.S. vehicle trips are less than 30 miles.</span></div></div>
<p>I recently took my LEAF on a short road trip to gauge the experience. The trip was just under 200 miles each way. My car has a 40 kWh battery with 92% state of health. On the trip, I averaged 4 mi/kWh. Those numbers mean that with a fully charged battery I can get 147 miles of range [40 * 0.92 * 4]. But at 10% battery remaining the car starts warning you to charge, triggering the same irrational anxiety that had me filling my gas car at 1/4 tank, so we can knock another 14.7 miles off the practical range taking us down to 132 miles. Because fast charging rates decrease as the battery fills up, it is not recommended to top off the battery when DC fast charging. If I charge to 80%, I can expect to get about 103 miles of range [40 * 0.92 * 4 * (0.8 - 0.1)]. Put all of this together and I consider trips up to 235 miles to be a reasonable option in my LEAF. Of course, this assumes that there is a <em>working</em> DC fast charger at the right place along the route, that I will have access to destination charging at my lodging, and that temperatures are mild (even better if the terrain is flat and the winds are light).</p>
<p>[UPDATE 2025-11-30: I made another short road trip (~170 miles each way) in my LEAF. On this recent trip, I averaged 3.5 mi/kWh. At first, I thought that the lower efficiency was related to the colder temperatures, but my previous 4 mi/kWh average included all driving during that trip, not just highway driving. The EPA rates the 2024 Nissan LEAF S at 99 MPGe for highway driving, which is about 2.9 mi/kWh. If we use that value in my 80% calculation above, we get only 75 miles of highway range.</p>
<p>Along my route, the available fast charging stations were about 40-50 miles apart. That easily falls within my range, but, if the CHAdeMO charger at each stop (usually only one unit) was not working, then I would have been limping along to try to get to the next charger. On the way there, I took the conservative approach of stopping at all three chargers. Fortunately, I was able to charge successfully at each stop so I had no range anxiety, but all of that charging added roughly an hour compared to making the same trip in a gas car.</p>
<p>On my way there, I averaged only 3.3 mi/kWh while driving 70-75 mph uphill with the heat on. Because I made so many charging stops, though, I was always above 20% SOC when arriving at my next stop (even with the higher speeds and heat). On the way back, I was hoping to make the trip with only one charging stop, partly because I would be going mostly downhill and partly because I had more confidence that I would be able to charge successfully at my one planned stop. I drove the first 75 miles of the return trip at 70-75 mph with the heat and then charged to 80%. At that point, my efficiency was 3.5 mi/kWh. After leaving that charging stop, though, my range was dropping rapidly so I decided to reduce my speed down to 60-65 mph and turn off the heat. I also drove the last 5-10 miles on surface streets instead of the freeway. Those changes allowed me to make it home with 7% SOC. Based on the original ETA from the navigation, those changes also added 10-15 minutes to the drive. Arguably, I should have just made one more short charging stop (15-20 min) to make for a more comfortable drive. My overall return trip efficiency was 3.7 mi/kWh thanks to the more conservative driving on the second leg, though.]</p>
<div class="page-columns page-full"><p>Enough with the downsides. Let’s talk about why this car makes sense for me. The biggest factors are that I have a NEMA 14-50 outlet in my garage giving me access to level 2 charging at home and that I work from home with infrequent, short trips to the office. Moreover, I live in Sacramento with mild winters where I don’t expect cold weather to dramatically reduce my range.  The extra planning required for EV ownership doesn’t feel particularly onerous to me and, in fact, I quite enjoy thinking about how to drive more efficiently and optimize charging. I love the experience of charging at home and the satisfying sound of plugging in my car. I thoroughly enjoy the EV driving experience, including one-pedal driving and the quiet but relatively powerful engine.</p><div class="no-row-height column-margin column-container"><span class="margin-aside">On the flip side, the hot summers might hasten my battery degradation.</span></div></div>
<p>This LEAF is the lowest mileage car that I have ever purchased (~6000 miles). The exterior and interior are in great shape and I’m quite enjoying having such a pristine car (while it lasts). The main feature upgrade in this car over my 2017 Toyota Prius is Apple CarPlay, but, because my LEAF is the S trim, it is also missing features that are present in my old Prius, e.g., adaptive cruise control, forward parking sensors, and more.</p>
<p>It is easy to imagine driving this LEAF for many years, but one unexpected side effect of becoming a first-time EV owner is how much more interested I’ve become in other EV models. I’ve never been a car guy so this newfound, and presumably short-lived, interest in cars is unusual. From where I sit right now, though, I think I’m most likely to replace my current LEAF with a newer LEAF because beginning with the 2026 model year they have fixed the fatal flaws of the previous generations of the LEAF. Of course, EV technology is evolving so rapdily that it is hard to predict which model will most appeal to me in 5+ years. I would like to be able to say that this experience has made me resolved to never buy a gas car again, but I loved my 2017 Toyota Prius so much that if my driving needs were to dramatically change I could see myself going back to a hybrid. However, I think I can say with some confidence that I will never buy a plug-in hybrid because it seems to me that they offer the worst of both worlds.</p>
<p>Now, let’s move on to the data. I had previously worked with data provided by the California Energy Commission on the light-duty vehicle population to make a <a href="https://esassoc.shinyapps.io/light-duty-vehicle-population/">Shiny app</a> that overlaps heavily with the CEC’s own <a href="https://www.energy.ca.gov/data-reports/energy-almanac/zero-emission-vehicle-and-infrastructure-statistics-collection/light">dashboard</a>. In this post, I’m just presenting tabular summaries, but you can also plot the results with the <a href="https://github.com/hinkelman/gnuplot-pipe"><code>gnuplot-pipe</code></a> library (see <a href="../posts/eda-scheme">this post</a>).</p>
<p>I’ve copied the county-level data provided by the CEC to a CSV file and made it available for download <a href="../data/light-duty.csv">here</a>. First, let’s import the <code>dataframe</code> library, read the data, and do some preliminary processing.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb1-1">(import (dataframe))</span>
<span id="cb1-2"></span>
<span id="cb1-3">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> df</span></span>
<span id="cb1-4">  (-&gt; (csv-&gt;dataframe <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"light-duty.csv"</span>)</span>
<span id="cb1-5">      (dataframe-drop* Fuel-Type)</span>
<span id="cb1-6">      (dataframe-rename* (Data-Year Year)</span>
<span id="cb1-7">                         (Dashboard-Fuel-Type-Group Fuel-Type)</span>
<span id="cb1-8">                         (Number-of-Vehicles Count))))</span>
<span id="cb1-9"></span>
<span id="cb1-10">(dataframe-display df)</span>
<span id="cb1-11"></span>
<span id="cb1-12"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">40877</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> cols</span>
<span id="cb1-13">    Year   County               Fuel-Type    Make     Model    Count </span>
<span id="cb1-14">   &lt;num&gt;    &lt;str&gt;                   &lt;str&gt;   &lt;str&gt;     &lt;str&gt;    &lt;num&gt; </span>
<span id="cb1-15">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2010</span>.  Alameda  Battery Electric (BEV)    Ford    Ranger       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>. </span>
<span id="cb1-16">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2010</span>.  Alameda  Battery Electric (BEV)   Tesla  Roadster      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">17</span>. </span>
<span id="cb1-17">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2010</span>.  Alameda                  Diesel      na        na   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10939</span>. </span>
<span id="cb1-18">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2010</span>.  Alameda                Gasoline      na        na   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10974</span>. </span>
<span id="cb1-19">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2010</span>.  Alameda                Gasoline      na        na  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">840577</span>. </span>
<span id="cb1-20">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2010</span>.  Alameda         Gasoline Hybrid      na        na   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">22720</span>. </span>
<span id="cb1-21">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2010</span>.  Alameda                   Other      na        na     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">173</span>. </span>
<span id="cb1-22">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2010</span>.  Alameda                   Other      na        na      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">19</span>. </span>
<span id="cb1-23">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2010</span>.   Alpine                  Diesel      na        na      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">73</span>. </span>
<span id="cb1-24">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2010</span>.   Alpine                Gasoline      na        na      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">16</span>. </span></code></pre></div></div>
<p>The shiny app that I made doesn’t include any of the data on make and model so I will focus on make and model in this post. Make and model is provided for all zero-emission vehicles in the county-level dataset, but here I will work only with the BEVs.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb2-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> df-bev</span></span>
<span id="cb2-2">  (-&gt; df</span>
<span id="cb2-3">      (dataframe-filter*</span>
<span id="cb2-4">       (Fuel-Type)</span>
<span id="cb2-5">       (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> Fuel-Type <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Battery Electric (BEV)"</span>))</span>
<span id="cb2-6">      (dataframe-drop* Fuel-Type)))</span></code></pre></div></div>
<p>As a starting point, let’s sum across counties and models to create <code>year-make</code> and then find the 10 makes with the highest average annual EV population. This average only includes years with non-zero counts for each make because the <code>mean</code> procedure provided by the <code>dataframe</code> library drops <code>'na</code> by default.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb3-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> year-make</span></span>
<span id="cb3-2">  (dataframe-aggregate*</span>
<span id="cb3-3">   df-bev</span>
<span id="cb3-4">   (Year Make)</span>
<span id="cb3-5">   (Count (Count) (sum Count))))</span>
<span id="cb3-6"></span>
<span id="cb3-7">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> top-makes</span></span>
<span id="cb3-8">  (-&gt; year-make</span>
<span id="cb3-9">      (dataframe-aggregate*</span>
<span id="cb3-10">       (Make)</span>
<span id="cb3-11">       (Avg (Count) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">round</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">inexact</span> (mean Count)))))</span>
<span id="cb3-12">      (dataframe-sort* (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> Avg))</span>
<span id="cb3-13">      (dataframe-head <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>)))</span>
<span id="cb3-14"> </span>
<span id="cb3-15">(dataframe-display top-makes)</span>
<span id="cb3-16"></span>
<span id="cb3-17"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> cols</span>
<span id="cb3-18">        Make      Avg </span>
<span id="cb3-19">       &lt;str&gt;    &lt;num&gt; </span>
<span id="cb3-20">       Tesla  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">224091</span>. </span>
<span id="cb3-21">   Chevrolet   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">28379</span>. </span>
<span id="cb3-22">      Nissan   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">26785</span>. </span>
<span id="cb3-23">     Hyundai   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15330</span>. </span>
<span id="cb3-24">  Volkswagen   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">13816</span>. </span>
<span id="cb3-25">        Audi   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11981</span>. </span>
<span id="cb3-26">      Rivian   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11654</span>. </span>
<span id="cb3-27">        FIAT    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9582</span>. </span>
<span id="cb3-28">        Ford    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9397</span>. </span>
<span id="cb3-29">         Kia    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8344</span>. </span></code></pre></div></div>
<p>Now, let’s see how the population of those makes has changed over time. Nissan led the pack from 2011-2015 before the Tesla takeover. As of 2024, Nissan had fallen into 5th place for the number of EVs registered in California.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb4-1">(-&gt; year-make</span>
<span id="cb4-2">    (dataframe-filter* (Make) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">member</span> Make (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> top-makes 'Make)))</span>
<span id="cb4-3">    (dataframe-spread 'Make 'Count)</span>
<span id="cb4-4">    (dataframe-display <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">90</span>))</span>
<span id="cb4-5"></span>
<span id="cb4-6"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span> cols</span>
<span id="cb4-7">    Year    Ford    Tesla  Nissan  Chevrolet    FIAT     Kia  Volkswagen  Hyundai    Audi  Rivian </span>
<span id="cb4-8">   &lt;num&gt;   &lt;num&gt;    &lt;num&gt;   &lt;num&gt;      &lt;num&gt;   &lt;num&gt;   &lt;num&gt;       &lt;num&gt;    &lt;num&gt;   &lt;num&gt;   &lt;num&gt; </span>
<span id="cb4-9">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2010</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">51</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">431</span>.      na         na      na      na          na       na      na      na </span>
<span id="cb4-10">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2011</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">45</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">557</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3638</span>         na      na      na          na       na      na      na </span>
<span id="cb4-11">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2012</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">214</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">673</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5899</span>         na      na      na          na       na      na      na </span>
<span id="cb4-12">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2013</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1112</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7859</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12845</span>        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">239</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">317</span>      na          na       na      na      na </span>
<span id="cb4-13">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2014</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2095</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">13673</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">21623</span>       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1311</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5868</span>      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30</span>          na       na      na      na </span>
<span id="cb4-14">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2015</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3192</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">23498</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">28351</span>       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3087</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12152</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">770</span>        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2158</span>       na      na      na </span>
<span id="cb4-15">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2016</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3463</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">39591</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31694</span>       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5425</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">16002</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1617</span>        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5905</span>       na      na      na </span>
<span id="cb4-16">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2017</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3726</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">61747</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">32853</span>      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">17818</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">18748</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2521</span>        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9745</span>      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">342</span>      na      na </span>
<span id="cb4-17">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2018</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3412</span>.  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">129300</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">32638</span>      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">26570</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15023</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2653</span>        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8971</span>      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">762</span>      na      na </span>
<span id="cb4-18">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2019</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2817</span>.  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">197453</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31600</span>      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">33202</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11322</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3369</span>       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10081</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3125</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1449</span>      na </span>
<span id="cb4-19">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2020</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1953</span>.  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">261018</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30113</span>      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">33065</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8017</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4169</span>        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8586</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4540</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4010</span>      na </span>
<span id="cb4-20">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2021</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8297</span>.  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">378014</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">32841</span>      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">39277</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7430</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6957</span>       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">13461</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8181</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7152</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">265</span> </span>
<span id="cb4-21">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2022</span>.  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20004</span>.  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">550093</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">34503</span>      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">46680</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7034</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">13791</span>       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">17771</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">17693</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11983</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4817</span> </span>
<span id="cb4-22">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2023</span>.  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">36936</span>.  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">761556</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">36653</span>      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60958</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6629</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">21534</span>       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">29180</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">33672</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">19557</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">14940</span> </span>
<span id="cb4-23">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2024</span>.  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">53642</span>.  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">935895</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">39733</span>      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">72921</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6441</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">34371</span>       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">32306</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">54326</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">27737</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">26592</span> </span></code></pre></div></div>
<p>Let’s look at the same data as proportions. Unlike R’s <code>dplyr</code> where you can pair <code>group_by</code> with <code>mutate</code> for grouped operations, in <code>dataframe</code> we need to explicitly split, apply, and combine. <code>-&gt;</code> and <code>-&gt;&gt;</code> are the thread first and last operators, respectively. We use <code>-&gt;&gt;</code> to pass a list as the last argument to <code>map</code>. In this call to <code>dataframe-modify*</code>, we calculate a scalar value for each row of the dataframe and that scalar is automatically repeated for all rows in <code>dfx</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb5-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round-any </span>x places)</span>
<span id="cb5-2">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>factor (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">expt</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> places)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb5-3">    (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">round</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> x factor)) factor)))</span>
<span id="cb5-4"></span>
<span id="cb5-5">(-&gt; year-make</span>
<span id="cb5-6">    (dataframe-filter* (Make) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">member</span> Make (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> top-makes 'Make)))</span>
<span id="cb5-7">    (dataframe-split 'Year)</span>
<span id="cb5-8">    (-&gt;&gt; (map</span>
<span id="cb5-9">          (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (dfx)</span>
<span id="cb5-10">            (dataframe-modify*</span>
<span id="cb5-11">             dfx (Total () (sum (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> dfx 'Count)))))))</span>
<span id="cb5-12">    (dataframe-bind-all)</span>
<span id="cb5-13">    (dataframe-modify*</span>
<span id="cb5-14">     (Prop (Count Total) (round-any (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">inexact</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> Count Total)) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)))</span>
<span id="cb5-15">    (dataframe-drop* Count Total)</span>
<span id="cb5-16">    (dataframe-spread 'Make 'Prop)</span>
<span id="cb5-17">    (dataframe-display <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">90</span>))</span>
<span id="cb5-18"></span>
<span id="cb5-19"></span>
<span id="cb5-20"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span> cols</span>
<span id="cb5-21">    Year    Ford   Tesla  Nissan  Chevrolet    FIAT     Kia  Volkswagen  Hyundai    Audi  Rivian </span>
<span id="cb5-22">   &lt;num&gt;   &lt;num&gt;   &lt;num&gt;   &lt;num&gt;      &lt;num&gt;   &lt;num&gt;   &lt;num&gt;       &lt;num&gt;    &lt;num&gt;   &lt;num&gt;   &lt;num&gt; </span>
<span id="cb5-23">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2010</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1060</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.8940</span>      na         na      na      na          na       na      na      na </span>
<span id="cb5-24">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2011</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0110</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1310</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.858</span>         na      na      na          na       na      na      na </span>
<span id="cb5-25">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2012</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0320</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0990</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.869</span>         na      na      na          na       na      na      na </span>
<span id="cb5-26">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2013</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0500</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3510</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.574</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.011</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.014</span>      na          na       na      na      na </span>
<span id="cb5-27">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2014</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0470</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3070</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.485</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.029</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.132</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.001</span>          na       na      na      na </span>
<span id="cb5-28">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2015</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0440</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3210</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.387</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.042</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.166</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.011</span>       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.029</span>       na      na      na </span>
<span id="cb5-29">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2016</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0330</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3820</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.306</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.052</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.154</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.016</span>       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.057</span>       na      na      na </span>
<span id="cb5-30">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2017</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0250</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.4190</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.223</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.121</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.127</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.017</span>       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.066</span>    <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.002</span>      na      na </span>
<span id="cb5-31">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2018</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0160</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5900</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.149</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.121</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.068</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.012</span>       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.041</span>    <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.003</span>      na      na </span>
<span id="cb5-32">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2019</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0100</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.6710</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.107</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.113</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.038</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.011</span>       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.034</span>    <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.011</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.005</span>      na </span>
<span id="cb5-33">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2020</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0050</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.7340</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.085</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.093</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.023</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.012</span>       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.024</span>    <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.013</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.011</span>      na </span>
<span id="cb5-34">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2021</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0170</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.7530</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.065</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.078</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.015</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.014</span>       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.027</span>    <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.016</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.014</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.001</span> </span>
<span id="cb5-35">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2022</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0280</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.7590</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.048</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.064</span>    <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.01</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.019</span>       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.025</span>    <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.024</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.017</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.007</span> </span>
<span id="cb5-36">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2023</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0360</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.7450</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.036</span>       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.06</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.006</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.021</span>       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.029</span>    <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.033</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.019</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.015</span> </span>
<span id="cb5-37">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2024</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0420</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.7290</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.031</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.057</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.005</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.027</span>       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.025</span>    <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.042</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.022</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.021</span> </span></code></pre></div></div>
<p>I’m not generally one to care about the uniqueness of my car, but let’s see how common the few models that I considered were in my county in recent years. I was primarily choosing between the Nissan LEAF and the BMW i3, but I included a couple of others here. I would have considered the Hyundai IONIQ Electric more seriously, but they weren’t as easy to find. I never strongly considered the Chevy Bolt because of a battery recall related to battery fires, but the LEAF and the Bolt have dominated the affordable EV market.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb6-1">(-&gt; df-bev</span>
<span id="cb6-2">    (dataframe-filter*</span>
<span id="cb6-3">     (Year County Model)</span>
<span id="cb6-4">     (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">member</span> Year '(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2022</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2023</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2024</span>))</span>
<span id="cb6-5">          (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> County <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Sacramento"</span>)</span>
<span id="cb6-6">          (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">member</span> Model '(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"LEAF"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"i3"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IONIQ Electric"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Bolt EV"</span>))))</span>
<span id="cb6-7">    (dataframe-drop* County)</span>
<span id="cb6-8">    (dataframe-sort* (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string&gt;?</span> Make) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> Year))</span>
<span id="cb6-9">    (dataframe-display <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span>))</span>
<span id="cb6-10"></span>
<span id="cb6-11"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> cols</span>
<span id="cb6-12">    Year       Make           Model   Count </span>
<span id="cb6-13">   &lt;num&gt;      &lt;str&gt;           &lt;str&gt;   &lt;num&gt; </span>
<span id="cb6-14">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2022</span>.     Nissan            LEAF   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1713</span>. </span>
<span id="cb6-15">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2023</span>.     Nissan            LEAF   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1752</span>. </span>
<span id="cb6-16">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2024</span>.     Nissan            LEAF   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1755</span>. </span>
<span id="cb6-17">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2022</span>.    Hyundai  IONIQ Electric     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">79</span>. </span>
<span id="cb6-18">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2023</span>.    Hyundai  IONIQ Electric     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">69</span>. </span>
<span id="cb6-19">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2024</span>.    Hyundai  IONIQ Electric     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">66</span>. </span>
<span id="cb6-20">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2022</span>.  Chevrolet         Bolt EV   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1376</span>. </span>
<span id="cb6-21">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2023</span>.  Chevrolet         Bolt EV   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1355</span>. </span>
<span id="cb6-22">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2024</span>.  Chevrolet         Bolt EV   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1472</span>. </span>
<span id="cb6-23">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2022</span>.        BMW              i3     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">91</span>. </span>
<span id="cb6-24">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2023</span>.        BMW              i3     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">93</span>. </span>
<span id="cb6-25">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2024</span>.        BMW              i3     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">89</span>. </span></code></pre></div></div>
<p>Let’s look at the relative popularity over time of the different models offered by a few key manufacturers. Nissan is notable for not offering many options and my understanding is that Nissan will stop selling the ARIYA in North America after the introduction of the 3rd generation LEAF in 2026. I was disappointed to see that there are more Cybertrucks than IONIQ 6’s on California roads in 2024. The IONIQ 6 is a bigger car than I usually prefer, but I appreciate the emphasis on efficiency via the sleek shape.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb7-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">count-models </span>df make)</span>
<span id="cb7-2">  (-&gt; df</span>
<span id="cb7-3">      (dataframe-filter* (Make) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> Make make))</span>
<span id="cb7-4">      (dataframe-aggregate*</span>
<span id="cb7-5">       (Year Model)</span>
<span id="cb7-6">       (Count (Count) (sum Count)))</span>
<span id="cb7-7">      (dataframe-spread 'Model 'Count)))</span>
<span id="cb7-8"></span>
<span id="cb7-9">(dataframe-display (count-models df-bev <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Nissan"</span>) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span>)</span>
<span id="cb7-10"></span>
<span id="cb7-11"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">14</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> cols</span>
<span id="cb7-12">    Year    LEAF   ARIYA </span>
<span id="cb7-13">   &lt;num&gt;   &lt;num&gt;   &lt;num&gt; </span>
<span id="cb7-14">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2011</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3638</span>.      na </span>
<span id="cb7-15">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2012</span>.   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5899</span>.      na </span>
<span id="cb7-16">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2013</span>.  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12845</span>.      na </span>
<span id="cb7-17">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2014</span>.  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">21623</span>.      na </span>
<span id="cb7-18">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2015</span>.  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">28351</span>.      na </span>
<span id="cb7-19">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2016</span>.  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31694</span>.      na </span>
<span id="cb7-20">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2017</span>.  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">32853</span>.      na </span>
<span id="cb7-21">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2018</span>.  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">32638</span>.      na </span>
<span id="cb7-22">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2019</span>.  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31600</span>.      na </span>
<span id="cb7-23">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2020</span>.  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30113</span>.      na </span>
<span id="cb7-24">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2021</span>.  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">32841</span>.      na </span>
<span id="cb7-25">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2022</span>.  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">34503</span>.      na </span>
<span id="cb7-26">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2023</span>.  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">33742</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2911</span> </span>
<span id="cb7-27">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2024</span>.  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">32501</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7232</span> </span>
<span id="cb7-28"></span>
<span id="cb7-29">(dataframe-display (count-models df-bev <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Tesla"</span>) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span>)</span>
<span id="cb7-30"></span>
<span id="cb7-31"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span> cols</span>
<span id="cb7-32">    Year  Roadster  Model S  Model X  Model <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>  Model Y  Cybertruck </span>
<span id="cb7-33">   &lt;num&gt;     &lt;num&gt;    &lt;num&gt;    &lt;num&gt;    &lt;num&gt;    &lt;num&gt;       &lt;num&gt; </span>
<span id="cb7-34">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2010</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">431</span>.       na       na       na       na          na </span>
<span id="cb7-35">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2011</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">557</span>.       na       na       na       na          na </span>
<span id="cb7-36">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2012</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">575</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">98</span>       na       na       na          na </span>
<span id="cb7-37">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2013</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">568</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7291</span>       na       na       na          na </span>
<span id="cb7-38">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2014</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">559</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">13114</span>       na       na       na          na </span>
<span id="cb7-39">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2015</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">562</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">22936</span>       na       na       na          na </span>
<span id="cb7-40">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2016</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">568</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">34343</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4680</span>       na       na          na </span>
<span id="cb7-41">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2017</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">554</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">47580</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12737</span>      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">876</span>       na          na </span>
<span id="cb7-42">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2018</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">541</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55816</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20993</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">51950</span>       na          na </span>
<span id="cb7-43">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2019</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">517</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">59798</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">27347</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">109791</span>       na          na </span>
<span id="cb7-44">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2020</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">460</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60869</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">33528</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">144311</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">21850</span>          na </span>
<span id="cb7-45">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2021</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">450</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">65118</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">33483</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">197125</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">81838</span>          na </span>
<span id="cb7-46">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2022</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">417</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">71617</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">43858</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">266246</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">167955</span>          na </span>
<span id="cb7-47">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2023</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">399</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">74295</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">53424</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">338329</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">295097</span>          <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span> </span>
<span id="cb7-48">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2024</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">379</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">74678</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60377</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">376489</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">414659</span>        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9313</span> </span>
<span id="cb7-49"></span>
<span id="cb7-50">(dataframe-display (count-models df-bev <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Hyundai"</span>) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span>)</span>
<span id="cb7-51"></span>
<span id="cb7-52"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> cols</span>
<span id="cb7-53">    Year  IONIQ Electric  KONA EV  IONIQ <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>  IONIQ <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> </span>
<span id="cb7-54">   &lt;num&gt;           &lt;num&gt;    &lt;num&gt;    &lt;num&gt;    &lt;num&gt; </span>
<span id="cb7-55">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2017</span>.            <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">342</span>.       na       na       na </span>
<span id="cb7-56">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2018</span>.            <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">762</span>.       na       na       na </span>
<span id="cb7-57">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2019</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1428</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1697</span>       na       na </span>
<span id="cb7-58">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2020</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1419</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3121</span>       na       na </span>
<span id="cb7-59">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2021</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2031</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6150</span>       na       na </span>
<span id="cb7-60">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2022</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1932</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7975</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7786</span>       na </span>
<span id="cb7-61">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2023</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1778</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10751</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">17069</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4074</span> </span>
<span id="cb7-62">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2024</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1611</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11209</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">33580</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7926</span> </span>
<span id="cb7-63"></span>
<span id="cb7-64">(dataframe-display (count-models df-bev <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Chevrolet"</span>) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span>)</span>
<span id="cb7-65"></span>
<span id="cb7-66"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span> cols</span>
<span id="cb7-67">    Year  Spark EV  Bolt EV  Bolt EUV    S-10  Blazer EV  Silverado EV  Equinox EV </span>
<span id="cb7-68">   &lt;num&gt;     &lt;num&gt;    &lt;num&gt;     &lt;num&gt;   &lt;num&gt;      &lt;num&gt;         &lt;num&gt;       &lt;num&gt; </span>
<span id="cb7-69">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2013</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">239</span>.       na        na      na         na            na          na </span>
<span id="cb7-70">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2014</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1311</span>.       na        na      na         na            na          na </span>
<span id="cb7-71">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2015</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3087</span>.       na        na      na         na            na          na </span>
<span id="cb7-72">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2016</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5425</span>.       na        na      na         na            na          na </span>
<span id="cb7-73">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2017</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5273</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12545</span>        na      na         na            na          na </span>
<span id="cb7-74">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2018</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4260</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">22310</span>        na      na         na            na          na </span>
<span id="cb7-75">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2019</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2762</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30440</span>        na      na         na            na          na </span>
<span id="cb7-76">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2020</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2464</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30601</span>        na      na         na            na          na </span>
<span id="cb7-77">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2021</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2356</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">35870</span>      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1014</span>      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">37</span>         na            na          na </span>
<span id="cb7-78">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2022</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2207</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">35094</span>      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9343</span>      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">36</span>         na            na          na </span>
<span id="cb7-79">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2023</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2051</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">38280</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20469</span>      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">37</span>         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">48</span>            <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">73</span>          na </span>
<span id="cb7-80">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2024</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1864</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">37837</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">21898</span>      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">37</span>       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4217</span>          <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1987</span>        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5081</span> </span></code></pre></div></div>
<p>The last tables made me curious about which models have had the biggest percent change from one year to the next. We use a split-apply-combine strategy again here to create a new column with the count for the next year. Lots of list reversing to create the <code>Count-Next</code> column. When displaying the results, I decided to constrain the output to only include models that had a count of at least 500 in the previous year. This approach eliminates examples like the Cybertruck which increased by 77508% from 2023 to 2024.</p>
<p>The Honda Clarity Electric is interesting for appearing on the list of biggest increases and then repeatedly appearing on the list of biggest decreases. The Tesla Model 3 made a huge splash when it went from less than 1000 cars in 2017 to over 50,000 in 2018.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb8-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> df-bev-change</span></span>
<span id="cb8-2">  (-&gt; df-bev</span>
<span id="cb8-3">      (dataframe-aggregate*</span>
<span id="cb8-4">       (Year Make Model)</span>
<span id="cb8-5">       (Count (Count) (sum Count)))</span>
<span id="cb8-6">      (dataframe-split 'Make 'Model)</span>
<span id="cb8-7">      (-&gt;&gt; (map</span>
<span id="cb8-8">            (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (dfx)</span>
<span id="cb8-9">              (dataframe-modify*</span>
<span id="cb8-10">               dfx (Count-Next () (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">reverse</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cons</span> 'na (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">reverse</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cdr</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> dfx 'Count))))))))))</span>
<span id="cb8-11">      (dataframe-bind-all)</span>
<span id="cb8-12">      (dataframe-remove-na 'Count-Next)</span>
<span id="cb8-13">      (dataframe-modify*</span>
<span id="cb8-14">       (Change% (Count Count-Next) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">inexact</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> Count-Next Count) Count)))))))</span>
<span id="cb8-15">               </span>
<span id="cb8-16">(-&gt; df-bev-change</span>
<span id="cb8-17">    (dataframe-filter* (Count) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> Count <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span>))</span>
<span id="cb8-18">    (dataframe-sort* (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> Change%))</span>
<span id="cb8-19">    (dataframe-display <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20</span>))</span>
<span id="cb8-20"></span>
<span id="cb8-21"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">253</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> cols</span>
<span id="cb8-22">    Year           Make                  Model   Count  Count-Next   Change% </span>
<span id="cb8-23">   &lt;num&gt;          &lt;str&gt;                  &lt;str&gt;   &lt;num&gt;       &lt;num&gt;     &lt;num&gt; </span>
<span id="cb8-24">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2013</span>.            BMW                ActiveE    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">515</span>.        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">251</span>.  -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">51.2621</span> </span>
<span id="cb8-25">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2022</span>.          Honda       Clarity Electric    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">702</span>.        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">425</span>.  -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">39.4587</span> </span>
<span id="cb8-26">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2017</span>.  Mercedes-Benz                B-Class   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2701</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1722</span>.  -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">36.2458</span> </span>
<span id="cb8-27">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2016</span>.          Smart  Fortwo Electric Drive   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3026</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1954</span>.  -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">35.4263</span> </span>
<span id="cb8-28">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2018</span>.      Chevrolet               Spark EV   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4260</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2762</span>.  -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">35.1643</span> </span>
<span id="cb8-29">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2020</span>.          Honda       Clarity Electric   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1613</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1050</span>.  -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">34.9039</span> </span>
<span id="cb8-30">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2021</span>.          Honda       Clarity Electric   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1050</span>.        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">702</span>.  -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">33.1429</span> </span>
<span id="cb8-31">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2019</span>.          Honda       Clarity Electric   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2398</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1613</span>.  -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">32.7356</span> </span>
<span id="cb8-32">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2023</span>.         Cruise              Cruise AV    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">930</span>.        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">632</span>.  -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">32.0430</span> </span>
<span id="cb8-33">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2019</span>.           Ford                  Focus   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2745</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1913</span>.  -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">30.3097</span> </span>
<span id="cb8-34">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2019</span>.           FIAT                   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span>e  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11322</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8017</span>.  -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">29.1910</span> </span>
<span id="cb8-35">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2018</span>.  Mercedes-Benz                B-Class   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1722</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1230</span>.  -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">28.5714</span> </span>
<span id="cb8-36">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2017</span>.          Honda                 Fit EV    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">667</span>.        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">494</span>.  -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">25.9370</span> </span>
<span id="cb8-37">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2018</span>.           FIAT                   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span>e  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15023</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11322</span>.  -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">24.6356</span> </span>
<span id="cb8-38">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2019</span>.  Mercedes-Benz                B-Class   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1230</span>.        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">939</span>.  -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">23.6585</span> </span>
<span id="cb8-39">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2019</span>.            Kia                Soul EV   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2221</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1712</span>.  -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">22.9176</span> </span>
<span id="cb8-40">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2016</span>.         Toyota                RAV4 EV   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2156</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1724</span>.  -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">20.0371</span> </span>
<span id="cb8-41">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2017</span>.           FIAT                   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span>e  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">18748</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15023</span>.  -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">19.8688</span> </span>
<span id="cb8-42">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2017</span>.      Chevrolet               Spark EV   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5273</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4260</span>.  -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">19.2111</span> </span>
<span id="cb8-43">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2018</span>.           Ford                  Focus   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3328</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2745</span>.  -<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">17.5180</span> </span>
<span id="cb8-44"></span>
<span id="cb8-45">(-&gt; df-bev-change</span>
<span id="cb8-46">    (dataframe-filter* (Count) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> Count <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span>))</span>
<span id="cb8-47">    (dataframe-sort* (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> Change%))</span>
<span id="cb8-48">    (dataframe-display <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20</span>))</span>
<span id="cb8-49"></span>
<span id="cb8-50"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">253</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> cols</span>
<span id="cb8-51">    Year           Make                  Model   Count  Count-Next    Change% </span>
<span id="cb8-52">   &lt;num&gt;          &lt;str&gt;                  &lt;str&gt;   &lt;num&gt;       &lt;num&gt;      &lt;num&gt; </span>
<span id="cb8-53">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2017</span>.          Tesla                Model <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">876</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">51950</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">5830.3653</span> </span>
<span id="cb8-54">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2022</span>.         Rivian                    R1S    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">579</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7659</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1222.7979</span> </span>
<span id="cb8-55">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2021</span>.      Chevrolet               Bolt EUV   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1014</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9343</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">821.4004</span> </span>
<span id="cb8-56">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2022</span>.           Audi              Q4 e-tron    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">645</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3593</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">457.0543</span> </span>
<span id="cb8-57">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2023</span>.       Cadillac                  LYRIQ   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1443</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6620</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">358.7665</span> </span>
<span id="cb8-58">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2022</span>.            BMW                     iX   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1510</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6281</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">315.9603</span> </span>
<span id="cb8-59">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2020</span>.          Tesla                Model Y  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">21850</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">81838</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">274.5446</span> </span>
<span id="cb8-60">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2022</span>.            BMW                     i4   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3207</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11647</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">263.1743</span> </span>
<span id="cb8-61">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2020</span>.        Porsche                 Taycan   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1047</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3710</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">254.3457</span> </span>
<span id="cb8-62">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2021</span>.       Polestar                      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1269</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4155</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">227.4232</span> </span>
<span id="cb8-63">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2022</span>.          Lucid                    Air   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1043</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3258</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">212.3682</span> </span>
<span id="cb8-64">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2022</span>.  Mercedes-Benz                    EQS   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3463</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10134</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">192.6364</span> </span>
<span id="cb8-65">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2013</span>.          Smart  Fortwo Electric Drive    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">654</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1842</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">181.6514</span> </span>
<span id="cb8-66">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2019</span>.           Audi                 e-tron   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1449</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4010</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">176.7426</span> </span>
<span id="cb8-67">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2022</span>.           Ford        F-150 Lightning   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2331</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6383</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">173.8310</span> </span>
<span id="cb8-68">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2015</span>.     Volkswagen                 e-Golf   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2158</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5905</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">173.6330</span> </span>
<span id="cb8-69">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2016</span>.          Tesla                Model X   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4680</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12737</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">172.1581</span> </span>
<span id="cb8-70">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2017</span>.          Honda       Clarity Electric    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">727</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1844</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">153.6451</span> </span>
<span id="cb8-71">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2023</span>.         Nissan                  ARIYA   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2911</span>.       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7232</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">148.4370</span> </span>
<span id="cb8-72">   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2021</span>.           Ford         Mustang Mach-E   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6367</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15817</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">148.4215</span> </span></code></pre></div></div>



 ]]></description>
  <category>Scheme</category>
  <category>dataframe</category>
  <category>EV</category>
  <guid>https://www.travishinkelman.com/posts/electric-vehicles-california.html</guid>
  <pubDate>Thu, 23 Oct 2025 00:00:00 GMT</pubDate>
</item>
<item>
  <title>NetLogo: a retrospective</title>
  <link>https://www.travishinkelman.com/posts/netlogo-retrospective.html</link>
  <description><![CDATA[ 




<p>In this post, I briefly reflect on my experiences with <a href="https://ccl.northwestern.edu/netlogo/">NetLogo</a>, which played a key role in my professional life.</p>
<p>My meandering graduate school research experiences were all broadly related to predator-prey interactions, foraging behavior, and animal movement. <a href="https://digitalcommons.unl.edu/dissertations/AAI3523971/">During my PhD (the 2nd try)</a>, I was studying the movement behavior of ladybug larvae after they consumed low-quality, potentially toxic, prey. I was interested in modeling their movement with the potential of eventually exploring how high-quality prey could benefit from the association with low-quality prey.</p>
<div class="page-columns page-full"><p>My PhD advisor, an R programmer, understandably encouraged me to pursue this modeling project with R, but I had stumbled across a paper with a simple animal movement or foraging model that included the NetLogo code in the appendix.  I was primarily using R for statistics at the time and I had a clearer vision for how I would get started on this project in NetLogo than in R, which is not surprising because NetLogo is much better suited for 2D movement modeling than R.</p><div class="no-row-height column-margin column-container"><span class="margin-aside">I briefly scanned my library of old papers, but my memory is too hazy on the details to find the actual paper.</span></div></div>
<p>I was quickly hooked on NetLogo. The NetLogo environment is beginner friendly, the core ideas and approach are intuitive, and the built-in graphical approach provides quick visual feedback on whether your code is doing what you think it is doing. Detractors will say that NetLogo is only useful for toy models and prototyping, but it is a <a href="https://publications.goettingen-research-online.de/handle/2/43378">capable platform for agent-based models</a>. I think it is fair to say that my current love of programming grew more out of my experiences with NetLogo than MATLAB or R.</p>
<div class="page-columns page-full"><p>My initial attempts to build a model of ladybird larvae movement centered on how to best implement the behavioral rules governing their movement. I was mostly flailing around while trying different ideas (which was fun!) and largely ignorant of the state of the art, particularly in the physics literature. After presenting on my initial modeling attempts to the grad students and faculty in my department, my dear, <a href="https://math.unl.edu/news/memoriam-nolting-remembered-his-generosity/">late</a> friend, <a href="https://www.bennolting.org">Ben Nolting</a>, gently nudged me in the direction of more elegant approaches. Our work together on this project eventually led to <a href="https://doi.org/10.1016/j.ecocom.2015.03.002">this paper</a>. We didn’t publish the NetLogo code with the paper, but I later put it on <a href="https://github.com/hinkelman/composite-random-search">GitHub</a>. </p><div class="no-row-height column-margin column-container"><span class="margin-aside">Ben also played a critical and supportive role in a short-lived <a href="https://datavoreconsulting.com">consulting business</a>.</span></div></div>
<p>Even after leaving academia for consulting, I hoped to work in my free time on extending our model to incorporate a second resource type to pursue my original interest in using the model to study shared predation. I made some progress [<a href="https://github.com/hinkelman/shared-predation">code</a>], but my motivation was insufficient to stay on top of the literature and chase down any novel ideas that might arise from using our movement model as the mechanism of shared predation.</p>
<p>My last tango with NetLogo involved trying to replicate <a href="https://doi.org/10.1111/j.1095-8649.2003.00212.x">Hill et al.&nbsp;(2003)</a>. I had discovered <a href="https://rescience.github.io">ReScience C</a>, which has the goal of encouraging replication of published computational research. Not only was I philosophically aligned with the ReScience mission, but I was excited at the prospect of doing research where the emphasis wasn’t on novelty and selling my ideas. I reached out to Ben about the possibility of collaborating on a side project for ReScience and proposed replicating Hill et al.&nbsp;(2003), which complemented our paper.</p>
<blockquote class="blockquote">
<p>Our work, which represents very general search behavior, and that of Hill et al.&nbsp;(2003), which focused on a specific system, provide complementary evidence for the potential importance of composite foraging strategies that are not based on time.</p>
</blockquote>
<p>Ben thought it sounded like a fun side project. We exchanged numerous emails about how to implement the model in NetLogo [<a href="https://github.com/hinkelman/plaice-search-model">code</a>], but couldn’t reconcile some early discrepancies in the results and lost our momentum. Replication is difficult. Human language lacks the precision of programming languages and trying to figure out what someone else meant was not enough fun to keep pushing forward on this side project.</p>
<p>I spent many years (too many!) as a graduate student where I dreamed of a productive career as a research scientist. I have had a very hard time letting go of that dream. In my first job after my PhD, I worked for a company, <a href="https://www.fishsciences.net">Cramer Fish Sciences</a>, that conducted original research, published papers, etc. I wasn’t doing much research myself, but the proximity to research slowed and masked the death of my research scientist dream. I’m finally comfortable acknowledging that original research is in my rearview mirror and fully embrace my future as a data scientist and programmer. With that, I say a fond farewell to NetLogo and the central role it played in my programming journey.</p>



 ]]></description>
  <category>NetLogo</category>
  <guid>https://www.travishinkelman.com/posts/netlogo-retrospective.html</guid>
  <pubDate>Sun, 18 May 2025 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Updating Shiny Scorekeeper app with Shiny modules and bslib</title>
  <link>https://www.travishinkelman.com/posts/shiny-scorekeeper-update.html</link>
  <description><![CDATA[ 




<p><a href="https://github.com/hinkelman/Shiny-Scorekeeper">Shiny Scorekeeper</a> is a basketball scorekeeper app built with the <a href="https://shiny.posit.co">Shiny</a> web framework for <a href="https://www.r-project.org">R</a>. The app was initially built in 2018, but I recently decided to update it to improve maintainability and provide a more modern look. It’s sort of a strange choice to invest time in this project in 2025. I built the app for scoring videos of my son’s youth basketball games, but my son is no longer a youth and I haven’t used the app in years. However, I have a fondness for the app because I had fun building it initially and it served me well for the years that I used it.</p>
<p>This new version is <strong>not</strong> about adding new features. The core functionality in the app is relatively unchanged, e.g., I’m still using <a href="../posts/dt-datatable-crud/">editable DataTables from the <code>DT</code> package</a> to create and manage rosters. One of the big changes was splitting the code among <a href="https://mastering-shiny.org/scaling-modules.html">Shiny modules</a> and an <a href="https://github.com/hinkelman/scorekeepeR">R package</a>. In the previous version, the <code>server.R</code> file was over 800 lines of code that I didn’t find very easy to maintain or extend.</p>
<p>I moved some of the code into an R package partly because I’ve recently had fun playing with Tk in R and Scheme (see <a href="../posts/eda-scheme-tk/">this post</a>) and thought it might be fun to try to build a version of the app with a Tk interface (as an alternative to the Shiny interface). I had plenty of moments, though, where I regretted adding the extra overhead of having that code in a separate R package, especially considering the payoff is mostly hypothetical and delayed (e.g., future maintenance or different interface). I also didn’t make any effort to think about whether the functions in the package are written in a general way that will work equally well with a Tk interface.</p>
<p>Despite building many Shiny apps over the years, including some reasonably complex apps, I had never used Shiny modules. One one of the primary objectives in this Shiny Scorekeeper refresh project was to learn how to use Shiny modules. My use of modules here was limited to the simplest use case, though, i.e., splitting code among files. The app is comprised of three sections (Roster, Scorekeeper, Stats Viewer) that led to obvious breaks for splitting into modules.</p>
<p>The biggest friction that I encountered with using modules is that auto reload is not triggered by changes to module files. Fortunately, the auto reload behavior will be included in a future version of Shiny (see <a href="https://github.com/rstudio/shiny/pull/4184">this pull request</a>). The most common mistake that I made with modules was forgetting to <a href="https://mastering-shiny.org/scaling-modules.html#namespacing">namespace UI elements</a>, which often produces unexpected behavior without any errors sent to the R console. The only other aspect that I found a little tricky was understanding how to pass values around among the modules.</p>
<p>The other big change was switching from <a href="https://rstudio.github.io/shinydashboard/"><code>shinydashboard</code></a> to <a href="https://rstudio.github.io/bslib/"><code>bslib</code></a>. Design is not one of my strengths so I tend to stick with default themes and colors. By default, <code>shinydashboard</code> uses too much color for my liking.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.travishinkelman.com/img/scorekeeper-old.png" class="img-fluid figure-img"></p>
<figcaption>Image of old version of Scorekeeper section</figcaption>
</figure>
</div>
<p>The <code>bslib</code> default uses very little color, which looks modern to me, but <code>bslib</code> also provides many <a href="https://rstudio.github.io/bslib/articles/theming/index.html">themes</a>.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.travishinkelman.com/img/scorekeeper-new.png" class="img-fluid figure-img"></p>
<figcaption>Image of new version of Scorekeeper section</figcaption>
</figure>
</div>
<p>I’ve started using <code>bslib</code> in nearly all of my Shiny apps. The default layouts look better than stock Shiny (or <code>shinydashboard</code>) apps and the elements compose nicely to create more complex layouts. I think the new <code>bslib</code> version of Shiny Scorekeeper uses space more effectively, which followed naturally from the different default layout options (e.g., panel navigation in the top bar instead of the sidebar for <code>page_navbar</code>).</p>
<p>I decided to stick to more of the standard Shiny UI components in this version. That was partly because I perceived a more uniform look with those elements when using <code>bslib</code>. The one 3rd-party component that I couldn’t give up was <code>shinyWidgets::pickerInput</code>. When using multiple select, the Shiny alternative (<code>selectInput</code>) is uglier and provides far fewer options (e.g., select/deselect all, live search, etc.).</p>
<p>The Stats Viewer in Shiny Scorekeeper changed more than any other section. Previously, I used <code>DT</code> tables as the mechanism for sorting and filtering the team and game data (by selecting rows in the tables). This approach allowed for compact presentation of the details associated with each team and game, but provided an unconventional interface that I ended up not liking.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.travishinkelman.com/img/stats-old.png" class="img-fluid figure-img"></p>
<figcaption>Image of old version of Stats Viewer section</figcaption>
</figure>
</div>
<p>For the new version, I have hierarchical inputs to filter down to the desired game stats. This approach leads to a relatively large hierarchy: leagues -&gt; teams -&gt; seasons -&gt; scoring margin -&gt; opponents -&gt; dates. Changes at the top of the hierarchy are propagated dynamically to update all of the other inputs. This requires more code than my previous approach with tables and could lead to notable lag in updating of the game stats table as data size increases.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.travishinkelman.com/img/stats-new.png" class="img-fluid figure-img"></p>
<figcaption>Image of new version of Stats Viewer section</figcaption>
</figure>
</div>
<p>I also replaced the <code>DT</code> game stats table with a <a href="https://glin.github.io/reactable/"><code>reactable</code></a> version. <code>DT</code> tables have been my go-to option for Shiny apps for many years, but I recently read that the <a href="https://bookdown.org/yihui/rmarkdown-cookbook/table-other.html"><code>DT</code> author thinks <code>reactable</code> is generally better than <code>DT</code></a>. I would have used <code>reactable</code> for all tables in Shiny Scorekeeper, but <code>reactable</code> tables are not editable so I needed to stick with <code>DT</code> tables for the roster section. I also think it is nice that the game stats table has a different look to reinforce that it is not editable.</p>



 ]]></description>
  <category>R</category>
  <category>Shiny</category>
  <guid>https://www.travishinkelman.com/posts/shiny-scorekeeper-update.html</guid>
  <pubDate>Sun, 27 Apr 2025 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Exploratory data analysis with Scheme, Gnuplot, and Tk</title>
  <link>https://www.travishinkelman.com/posts/eda-scheme-tk.html</link>
  <description><![CDATA[ 




<p>In my <a href="../posts/programming-horizons/">second post on this blog</a>, I expressed an interest in learning how to build desktop applications. I have yet to pursue that interest. Instead, I’ve primarily continued developing <a href="https://shiny.posit.co">Shiny</a> apps deployed on the web (but see <a href="https://github.com/hinkelman/Shiny-Scorekeeper">Shiny Scorekeeper</a>). Recently, though, I’ve spent some time learning about the <a href="https://www.tcl.tk">Tk GUI toolkit</a> for developing desktop applications. In this post, I revisit an old <a href="../posts/eda-scheme/">post</a> using the <a href="https://github.com/hinkelman/dataframe/"><code>dataframe</code></a> and <a href="https://github.com/hinkelman/gnuplot-pipe"><code>gnuplot-pipe</code></a> libraries for Scheme to conduct simple exploratory data analysis (EDA) and add an interface with <a href="https://github.com/hinkelman/chez-tk/"><code>chez-tk</code></a>.</p>
<section id="tcltk" class="level2">
<h2 class="anchored" data-anchor-id="tcltk">Tcl/Tk</h2>
<p>A few months ago I saw on <a href="https://news.ycombinator.com/item?id=41661906">Hacker News</a> that Tcl/Tk accounced a major release. My interest was piqued by the generally favorable comments and comparisons to Lisp. I also like the generality that comes from the large number of languages that provide bindings to Tk. One of those languages is my primary programming language, R. It seems that the GUI options for R have largely collapsed to only Shiny and <a href="https://r-universe.dev/manuals/tcltk.html"><code>tcltk</code></a>. To satisfy my curiousity, I tackled a little <a href="../pdf/ZoopSynth-tcltk.pdf">project</a> to learn more about the <code>tcltk</code> package in R.</p>
<p>I was also interested in available bindings to Tk for my favorite programming language, Scheme, and found <a href="https://snow-fort.org/s/peterlane.info/peter/rebottled/pstk/1.7.0/index.html">PS/Tk</a>.</p>
<blockquote class="blockquote">
<p>The PSTK library has had a long history in the Scheme community and, in one form or another, is available for many Scheme implementations. The current file includes its history starting from an implementation of Chicken/Tk by Wolf-Dieter Busch from 2004 based on earlier code by Sven Hartrumpf from 1997. Nils Holm made the library portable, and so created PSTK. Ken Dickey created an R6RS version.</p>
</blockquote>
<p>PS/Tk communicates with Tcl/Tk through a process port. The versions of PS/Tk code that I found did not include R6RS compatibility so I added the code needed to open a process port in Chez Scheme, converted from R7RS to R6RS library, called it <code>chez-tk</code>, and submitted it to <a href="https://akkuscm.org/packages/chez-tk/">Akku</a>. I’ve collected <a href="https://github.com/hinkelman/chez-tk/tree/main/examples">examples</a> for using <code>chez-tk</code> based on existing PS/Tk examples or translating examples from <a href="https://tkdocs.com/">TkDocs</a>. In translating those examples, I was primarily using <a href="https://docs.python.org/3/library/tkinter.html"><code>tkinter</code></a> for Python to understand how they work. I was impressed by the autocompletion and documentation for <code>tkinter</code> available through VS Code. For <code>tcltk</code> and <code>chez-tk</code>, you have to learn the translation rules and use the Tcl/Tk documentation.</p>
<p>After working up a set of <code>chez-tk</code> examples, the only apparent bug that I found was related to the <a href="https://github.com/hinkelman/chez-tk/issues/1">inclusion of parentheses in listbox choices</a>. It was a small change in the code to fix that bug, and I didn’t notice any negative impacts when running through the examples after making the change, but I also don’t understand why that procedure was written that way in the first place. That’s an uneasy feeling.</p>
</section>
<section id="app-overview" class="level2">
<h2 class="anchored" data-anchor-id="app-overview">App Overview</h2>
<p>When I first started making Shiny apps 10+ years ago, I was drawn to the potential to make my work in R accessible to non-R users. I didn’t anticipate the extent to which I would find graphical user interfaces to multi-dimensional datasets useful for my own data exploration efforts. This <code>chez-tk</code> example is made in that spirit, i.e., the app isn’t packaged into a standalone desktop application for other users. The user needs to know how to use Chez Scheme and Akku and needs to install Tcl/Tk and Gnuplot.</p>
<p>The app allows for filtering on years, months, and cities and summarizes an annual or monthly time series grouped by city for the selected response variable. Each click of the button will generate a plot in a new window.</p>
<p><img src="https://www.travishinkelman.com/img/EDA-App-Screenshot.png" class="img-fluid"></p>
</section>
<section id="data-preparation" class="level2">
<h2 class="anchored" data-anchor-id="data-preparation">Data Preparation</h2>
<section id="libraries" class="level3">
<h3 class="anchored" data-anchor-id="libraries">Libraries</h3>
<p>All of the libraries in the import statement below are available through <a href="https://akkuscm.org/packages/">Akku</a>. <code>dataframe</code> is used for data manipulation. Only one procedure is imported from <code>wax irregex</code> to process a string that is returned from Tcl/Tk. <code>gnuplot-pipe</code> is used for plotting. <code>chez-tk</code> allows us to build a user interface. [All of the code is available in a single file in this <a href="https://gist.github.com/hinkelman/7236f4041dc56ed15541e3cad65d7626">gist</a>.]</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb1-1">(import (dataframe)</span>
<span id="cb1-2">        (only (wak irregex) irregex-split)</span>
<span id="cb1-3">        (prefix (gnuplot-pipe) gp:)</span>
<span id="cb1-4">        (chez-tk))</span></code></pre></div></div>
</section>
<section id="data" class="level3">
<h3 class="anchored" data-anchor-id="data">Data</h3>
<p>We are using the Texas housing dataset included as part of the <a href="https://ggplot2.tidyverse.org/"><code>ggplot2</code></a> package for R. I’ve written that dataset to a <a href="../data/txhousing.csv">CSV file</a> for use in this post.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb2-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> df </span>(csv-&gt;dataframe <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"txhousing.csv"</span>))</span>
<span id="cb2-2"></span>
<span id="cb2-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (dataframe-display df)</span>
<span id="cb2-4"></span>
<span id="cb2-5"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8602</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span> cols</span>
<span id="cb2-6">     city    year   month   sales    volume  median  listings  inventory       date </span>
<span id="cb2-7">    &lt;str&gt;   &lt;num&gt;   &lt;num&gt;   &lt;num&gt;     &lt;num&gt;   &lt;num&gt;     &lt;num&gt;      &lt;num&gt;      &lt;num&gt; </span>
<span id="cb2-8">  Abilene   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2000</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">72</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">5.380</span>E+6  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">71400</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">701</span>.     <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6.3000</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2000.0000</span> </span>
<span id="cb2-9">  Abilene   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2000</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">98</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6.505</span>E+6  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">58700</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">746</span>.     <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6.6000</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2000.0833</span> </span>
<span id="cb2-10">  Abilene   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2000</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">130</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">9.285</span>E+6  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">58100</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">784</span>.     <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6.8000</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2000.1667</span> </span>
<span id="cb2-11">  Abilene   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2000</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">98</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">9.730</span>E+6  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">68600</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">785</span>.     <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6.9000</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2000.2500</span> </span>
<span id="cb2-12">  Abilene   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2000</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">141</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.059</span>E+7  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">67300</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">794</span>.     <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6.8000</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2000.3333</span> </span>
<span id="cb2-13">  Abilene   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2000</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">156</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.391</span>E+7  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">66900</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">780</span>.     <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6.6000</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2000.4167</span> </span>
<span id="cb2-14">  Abilene   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2000</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">152</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.264</span>E+7  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">73500</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">742</span>.     <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6.2000</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2000.5000</span> </span>
<span id="cb2-15">  Abilene   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2000</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">131</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.071</span>E+7  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">75000</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">765</span>.     <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6.4000</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2000.5833</span> </span>
<span id="cb2-16">  Abilene   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2000</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">104</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">7.615</span>E+6  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">64500</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">771</span>.     <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6.5000</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2000.6667</span> </span>
<span id="cb2-17">  Abilene   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2000</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>.    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">101</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">7.040</span>E+6  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">59300</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">764</span>.     <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6.6000</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2000.7500</span> </span></code></pre></div></div>
</section>
<section id="global-variables" class="level3">
<h3 class="anchored" data-anchor-id="global-variables">Global Variables</h3>
<p>We define global variables based on <code>df</code> for use in the app. First, though, we need to define a helper procedure to double quote any strings in a list that have spaces because <code>chez-tk</code> appends those strings into one big string for passing to Tcl/Tk. Ideally, <code>chez-tk</code> would handle this for us, but, for now, I’m reluctant to make too many changes to <code>chez-tk</code> (see above).</p>
<p>We get the list of cities from the dataframe and remove duplicates. For some reason, there is a problem with three of the cities causing the app to crash with a message about “invalid listvar values.” I have no idea why just those three cities cause a problem, but, for now, I’ve decided not to try to chase down that problem. The other thing to point out is that the options for the combobox are defined as a single string in <code>vars-labs</code>, which also shows the double quoting requirement. When a response variable is selected in the app, the column name is looked up using the associations in <code>vars</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb3-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">double-quote </span>lst)</span>
<span id="cb3-2">  (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (x)</span>
<span id="cb3-3">         (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>x-list (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string-&gt;list</span> x)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb3-4">           (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">member</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">#\</span><span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">space</span> x-list)</span>
<span id="cb3-5">               (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string-append</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\"</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span> x <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\"</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb3-6">               x)))</span>
<span id="cb3-7">       lst))</span>
<span id="cb3-8"></span>
<span id="cb3-9">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> cities </span>(remove-duplicates (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> df 'city)))</span>
<span id="cb3-10">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> cities</span></span>
<span id="cb3-11">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">filter</span></span>
<span id="cb3-12">   (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (x) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">member</span> x '(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Montgomery County"</span></span>
<span id="cb3-13">                                <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Port Arthur"</span></span>
<span id="cb3-14">                                <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Wichita Falls"</span>))))</span>
<span id="cb3-15">   cities))</span>
<span id="cb3-16">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> cities-dq </span>(double-quote cities))</span>
<span id="cb3-17"></span>
<span id="cb3-18">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> min-yr </span>(apply <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">min</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> df 'year)))</span>
<span id="cb3-19">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> max-yr </span>(apply <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">max</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> df 'year)))</span>
<span id="cb3-20">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> months </span>'(Jan Feb Mar Apr May Jun</span>
<span id="cb3-21">                     Jul Aug Sep Oct Nov Dec))</span>
<span id="cb3-22">                     </span>
<span id="cb3-23">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> vars </span>'((<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Median Sale Price"</span> median)</span>
<span id="cb3-24">               (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Sales"</span> sales)</span>
<span id="cb3-25">               (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Volume"</span> volume)</span>
<span id="cb3-26">               (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Listings"</span> listings)</span>
<span id="cb3-27">               (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Inventory"</span> inventory)))</span>
<span id="cb3-28">               </span>
<span id="cb3-29">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> vars-labs </span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\"</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">Median Sale Price</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\"</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> Sales Volume Listings Inventory"</span>)</span></code></pre></div></div>
</section>
<section id="filter" class="level3">
<h3 class="anchored" data-anchor-id="filter">Filter</h3>
<p>We create a small wrapper procedure around a standard <code>dataframe-filter*</code>. The <code>month</code> column in <code>df</code> is represented by numeric months. If we add one to the indices of the selected months, then we get the numeric months for use in the filter. We use the cities indices to get the city names from <code>cities</code> (not <code>cities-dq</code>). We remove all rows with missing values in <code>resp-var</code> with <code>dataframe-remove-na</code>. If there were missing values in <code>year</code>, <code>month</code>, and <code>city</code> columns, then we would need to add them to the <code>dataframe-remove-na</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb4-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter-data </span>df min-yr max-yr months-idx cities-idx cities resp-var)</span>
<span id="cb4-2">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>months-sel (map add1 months-idx)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb4-3">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>cities-sel (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (x) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">list-ref</span> cities x)) cities-idx)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb4-4">    (-&gt; df</span>
<span id="cb4-5">        (dataframe-remove-na resp-var)</span>
<span id="cb4-6">        (dataframe-filter*</span>
<span id="cb4-7">         (city year month)</span>
<span id="cb4-8">         (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> year min-yr)</span>
<span id="cb4-9">              (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> year max-yr)</span>
<span id="cb4-10">              (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">member</span> month months-sel)</span>
<span id="cb4-11">              (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">member</span> city cities-sel))))))</span></code></pre></div></div>
</section>
<section id="aggregate" class="level3">
<h3 class="anchored" data-anchor-id="aggregate">Aggregate</h3>
<p>As with filtering, we are wrapping <code>dataframe-aggregate</code>. In this case, though, we can’t use the macro version (indicated with a trailing <code>*</code>). The macro versions of the dataframe verbs are intended for interactive use and provide simpler syntax. The grouping variables are <code>city</code> and <code>xvar</code>. The new column is named <code>mean-rv</code> where ‘rv’ stands for response variable. <code>(list (list resp-var))</code> provides the names of the columns used in the lambda expressions (one sub-list for each expression).</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb5-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">agg-data </span>df xvar resp-var)</span>
<span id="cb5-2">  (dataframe-aggregate</span>
<span id="cb5-3">   df</span>
<span id="cb5-4">   (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">list</span> 'city xvar)</span>
<span id="cb5-5">   '(mean-rv)</span>
<span id="cb5-6">   (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">list</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">list</span> resp-var))</span>
<span id="cb5-7">   (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (resp-var) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">exact-&gt;inexact</span> (mean resp-var)))))</span></code></pre></div></div>
</section>
<section id="plot" class="level3">
<h3 class="anchored" data-anchor-id="plot">Plot</h3>
<p><code>gp:send</code> sends commands to Gnuplot as strings. When setting the axis labels, we need to surround the label with single quotation marks to distinguish the label from the rest of the command string. To plot multiple sets of data, <code>gp:plot</code> accepts a list where the first item is a string with optional properties (e.g., title provides a label for the legend), the second is a list with x-coordinates, and the third is a list with y-coordinates.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb6-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">plot-data </span>df x y xvar-str resp-var-str)</span>
<span id="cb6-2">  (gp:call/gnuplot</span>
<span id="cb6-3">   (gp:send <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"set key top left"</span>)</span>
<span id="cb6-4">   (gp:send (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string-append</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"set xlabel </span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\'</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span> xvar-str <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\'</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>))</span>
<span id="cb6-5">   (gp:send (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string-append</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"set ylabel </span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\'</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">Avg. "</span> resp-var-str <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\'</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>))</span>
<span id="cb6-6">   (gp:send <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"set style data linespoints"</span>)</span>
<span id="cb6-7">   (gp:plot</span>
<span id="cb6-8">    (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (c)</span>
<span id="cb6-9">           (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>df-sub (dataframe-filter*</span>
<span id="cb6-10">                          df</span>
<span id="cb6-11">                          (city)</span>
<span id="cb6-12">                          (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> c city))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb6-13">             (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">list</span></span>
<span id="cb6-14">              (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string-append</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"title '"</span> c <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"'"</span>)</span>
<span id="cb6-15">              (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> df-sub x)</span>
<span id="cb6-16">              (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> df-sub y))))</span>
<span id="cb6-17">         (remove-duplicates (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> df 'city))))))</span></code></pre></div></div>
</section>
</section>
<section id="app-details" class="level2">
<h2 class="anchored" data-anchor-id="app-details">App Details</h2>
<section id="named-frames-and-widgets" class="level3">
<h3 class="anchored" data-anchor-id="named-frames-and-widgets">Named Frames and Widgets</h3>
<p><a href="https://tktable.sourceforge.net/tile/">Tile</a> provides reimplementations of many classic widgets in the <code>ttk</code> namespace. In the first line in the code block below, we opt to use the Tile versions over the classic versions for all widgets with <code>ttk-map-widgets</code>. <code>tk-start</code> initializes the Tk shell.</p>
<p>In <code>chez-tk</code>, widgets are represented as procedures that can be used to configure the widget. In this app, we use frames, labels, spinboxes, listboxes, radiobuttons, a combobox, and a button, but only a few of them require names for subsequent configuration. The named procedures also specify the relationship of the frames and widgets, e.g., <code>tk</code> creates <code>frame</code> and <code>frame</code> creates <code>months-lb</code>, <code>cities-lb</code>, <code>vars-cb</code>, and all other widgets.</p>
<p>Commands are represented as symbols (e.g., <code>'create-widget</code>) whereas parameters are represented as symbols with trailing colons (e.g., <code>'height:</code>). Scheme symbols can be used in place of strings and Scheme values such as <code>#f</code> are converted to the Tcl/Tk equivalent. <code>tk-var</code> associates a Tk variable name with a widget.</p>
<p>When <code>'exportselection:</code> is set to <code>#t</code>, clicking outside of the listbox deselects any listbox selections. For multiple selections in listboxes, the <code>'selectmode:</code> needs to be set to <code>'multiple</code> or <code>'extended</code>.</p>
<blockquote class="blockquote">
<p>If the selection mode is multiple or extended, any number of elements may be selected at once, including discontiguous ranges. In multiple mode, clicking button 1 on an element toggles its selection state without affecting any other elements. In extended mode, pressing button 1 on an element selects it, deselects everything else, and sets the anchor to the element under the mouse; dragging the mouse with button 1 down extends the selection to include all the elements between the anchor and the element under the mouse, inclusive.</p>
</blockquote>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb7-1">(ttk-map-widgets 'all)</span>
<span id="cb7-2">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> tk </span>(tk-start))</span>
<span id="cb7-3">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> frame </span>(tk 'create-widget 'frame 'padding: '(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>)))</span>
<span id="cb7-4">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> months-lb</span></span>
<span id="cb7-5">  (frame 'create-widget 'listbox 'listvariable: (tk-var 'months-tk)</span>
<span id="cb7-6">         'height: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> 'exportselection: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#f</span> 'selectmode: 'extended))</span>
<span id="cb7-7">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> cities-lb</span></span>
<span id="cb7-8">  (frame 'create-widget 'listbox 'listvariable: (tk-var 'cities-tk)</span>
<span id="cb7-9">         'height: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> 'exportselection: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#f</span> 'selectmode: 'extended))</span>
<span id="cb7-10">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> vars-cb</span></span>
<span id="cb7-11">  (frame 'create-widget 'combobox 'values: vars-labs 'state: 'readonly))</span></code></pre></div></div>
</section>
<section id="app-layout" class="level3">
<h3 class="anchored" data-anchor-id="app-layout">App Layout</h3>
<p>We are using the grid geometry manager with a simple layout of three columns and nine rows all contained in a single frame. Widgets are sized to the content so a long label like <code>Response Variable</code> should be set to span multiple columns to prevent undesirable extra space. The <code>'sticky:</code> parameter uses cardinal directions (<code>'nwes</code>) for alignment of widgets. Most widgets can be created within a call to <code>tk/grid</code> because there is no subsequent configuration of those widgets, just setting and getting the Tk variable.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb8-1">(tk/grid frame)</span>
<span id="cb8-2">(tk/grid (frame 'create-widget 'label 'text: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Years"</span>)</span>
<span id="cb8-3">         'column: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> 'row: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> 'sticky: 'w 'pady: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>)</span>
<span id="cb8-4">(tk/grid (frame 'create-widget 'spinbox 'from: min-yr 'to: max-yr</span>
<span id="cb8-5">                'textvariable: (tk-var 'min-yr-tk) 'width: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>)</span>
<span id="cb8-6">         'column: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> 'row: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> 'sticky: 'w)</span>
<span id="cb8-7">(tk/grid (frame 'create-widget 'spinbox 'from: min-yr 'to: max-yr</span>
<span id="cb8-8">                'textvariable: (tk-var 'max-yr-tk) 'width: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>)</span>
<span id="cb8-9">         'column: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>  'row: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> 'sticky: 'w)</span>
<span id="cb8-10"></span>
<span id="cb8-11">(tk/grid (frame 'create-widget 'label 'text: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Months"</span>)</span>
<span id="cb8-12">         'column: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> 'row: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> 'sticky: 'w)</span>
<span id="cb8-13">(tk/grid months-lb 'column: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> 'row: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> 'columnspan: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> 'sticky: 'we 'pady: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>)</span>
<span id="cb8-14"></span>
<span id="cb8-15">(tk/grid (frame 'create-widget 'label 'text: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Cities"</span>)</span>
<span id="cb8-16">         'column: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> 'row: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> 'sticky: 'w)</span>
<span id="cb8-17">(tk/grid cities-lb 'column: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> 'row: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> 'columnspan: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> 'sticky: 'we 'pady: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>)</span>
<span id="cb8-18"></span>
<span id="cb8-19">(tk/grid (frame 'create-widget 'label 'text: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"X Variable"</span>)</span>
<span id="cb8-20">         'column: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> 'row: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> 'sticky: 'w 'pady: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>)</span>
<span id="cb8-21">(tk/grid (frame 'create-widget 'radiobutton 'text: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Year"</span> 'value: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Year"</span></span>
<span id="cb8-22">                'variable: (tk-var 'xvar-tk))</span>
<span id="cb8-23">         'column: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> 'row: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> 'sticky: 'e)</span>
<span id="cb8-24">(tk/grid (frame 'create-widget 'radiobutton 'text: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Month"</span> 'value: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Month"</span></span>
<span id="cb8-25">                'variable: (tk-var 'xvar-tk))</span>
<span id="cb8-26">         'column: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> 'row: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> 'sticky: 'e)</span>
<span id="cb8-27"></span>
<span id="cb8-28">(tk/grid (frame 'create-widget 'label 'text: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Response Variable"</span>)</span>
<span id="cb8-29">         'column: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> 'row: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> 'columnspan: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> 'sticky: 'w)</span>
<span id="cb8-30">(tk/grid vars-cb 'column: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> 'row: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span> 'columnspan: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> 'sticky: 'we)</span></code></pre></div></div>
</section>
<section id="commands" class="level3">
<h3 class="anchored" data-anchor-id="commands">Commands</h3>
<p>In this app, we only have one command, <code>plot-cmd</code>, which filters, aggregates, and plots data. <code>plot-cmd</code> is associated with the plot button via the <code>'command:</code> parameter. A command procedure takes no arguments. Within <code>plot-cmd</code>, we retrieve the state of all of the app widgets at the time that the button was clicked and then pass those values to the procedures that we described above, i.e., <code>filter-data</code>, <code>agg-data</code>, and <code>plot-data</code>.</p>
<p>For several widgets, we use <code>tk-get-var</code> with the Tk variable name to get the current widget value and convert it to the appropriate type. For the combobox, we use the Scheme name (<code>vars-cb</code>) with <code>'get</code>. Similarly, for listboxes, we use the Scheme name with <code>'curselection</code>, which returns a string of the selected indices, e.g., <code>"0 3 4 8"</code>. <code>prepare-curselection</code> splits that string into a list of numeric indices for use in <code>filter-data</code>.</p>
<p>If the filtering and aggregating steps produce an empty dataframe, then clicking on the plot button has no effect (because otherwise the app would crash). Ideally, the user would receive feedback on why the plot isn’t displayed, but, unfortunately, that feature is not a simple addition to the app (based on my current understanding of Tcl/Tk).</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb9-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">prepare-curselection </span>x)</span>
<span id="cb9-2">  (map <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string-&gt;number</span> (irregex-split <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">" "</span> x)))</span>
<span id="cb9-3"></span>
<span id="cb9-4">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> plot-cmd</span></span>
<span id="cb9-5">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> ()</span>
<span id="cb9-6">    (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let*</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>xvar-str (tk-get-var 'xvar-tk)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb9-7">           <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>xvar (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> xvar-str <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Year"</span>) 'year 'month)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb9-8">           <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>rv-str (vars-cb 'get)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb9-9">           <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>rv (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cadr</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">assoc</span> rv-str vars))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb9-10">           <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>df-sub (filter-data</span>
<span id="cb9-11">                    df</span>
<span id="cb9-12">                    (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string-&gt;number</span> (tk-get-var 'min-yr-tk))</span>
<span id="cb9-13">                    (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string-&gt;number</span> (tk-get-var 'max-yr-tk))</span>
<span id="cb9-14">                    (prepare-curselection (months-lb 'curselection))</span>
<span id="cb9-15">                    (prepare-curselection (cities-lb 'curselection))</span>
<span id="cb9-16">                    cities</span>
<span id="cb9-17">                    rv)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb9-18">      <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; can't aggregate empty dataframe</span></span>
<span id="cb9-19">      (when (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> (dataframe-dim df-sub)) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span>
<span id="cb9-20">        (plot-data (agg-data df-sub xvar rv) xvar 'mean-rv xvar-str rv-str)))))</span>
<span id="cb9-21"></span>
<span id="cb9-22">(tk/grid (frame 'create-widget 'button 'text: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Plot"</span> 'command: plot-cmd)</span>
<span id="cb9-23">         'column: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> 'row: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span> 'columnspan: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> 'sticky: 'we 'pady: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>)</span></code></pre></div></div>
</section>
<section id="initial-values" class="level3">
<h3 class="anchored" data-anchor-id="initial-values">Initial Values</h3>
<p>For spinboxes and radiobuttons, <code>tk-set-var!</code> sets the initial value. For the combobox, the initial value is set with the Scheme name, <code>vars-cb</code>, and <code>'set</code>. For listboxes, <code>tk-set-var!</code> sets the options, but the initial values are set with the Scheme name. Here is the Tcl/Tk documentation for listbox selection set:</p>
<blockquote class="blockquote">
<p>pathName selection set first ?last?<br>
Selects all of the elements in the range between first and last, inclusive, without affecting the selection state of elements outside that range.</p>
</blockquote>
<p>This nicely illustrates the translation between Tk and <code>chez-tk</code> where the Scheme name is used in place of the pathName and the rest of the expression is almost identical. For <code>months-lb</code>, we initially select all months. For <code>cities-lb</code>, we are selecting multiple elements that are not part of an inclusive range so we set the selected values iteratively. We use a helper procedure, <code>get-idx</code>, to get indices for a subset of the cities.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb10-1">(tk-set-var! 'min-yr-tk min-yr)</span>
<span id="cb10-2">(tk-set-var! 'max-yr-tk max-yr)</span>
<span id="cb10-3">(tk-set-var! 'months-tk months)</span>
<span id="cb10-4">(tk-set-var! 'cities-tk cities-dq)</span>
<span id="cb10-5">(tk-set-var! 'xvar-tk <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Year"</span>)</span>
<span id="cb10-6">(vars-cb 'set <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Median Sale Price"</span>)</span>
<span id="cb10-7">(months-lb 'selection 'set <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span>)</span>
<span id="cb10-8"></span>
<span id="cb10-9">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">get-idx </span>lst lst-sub)</span>
<span id="cb10-10">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; get indices of lst-sub from lst</span></span>
<span id="cb10-11">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let*</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>idx (iota (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">length</span> lst))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb10-12">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>lst-idx (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (x i) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cons</span> x i)) lst idx)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb10-13">    (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (y) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cdr</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">assoc</span> y lst-idx))) lst-sub)))</span>
<span id="cb10-14"></span>
<span id="cb10-15">(<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for-each</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (x) (cities-lb 'selection 'set x))</span>
<span id="cb10-16">          (get-idx cities '(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Austin"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Dallas"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"El Paso"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Houston"</span></span>
<span id="cb10-17">                            <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Lubbock"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"San Antonio"</span>)))</span></code></pre></div></div>
</section>
</section>
<section id="conclusions" class="level2">
<h2 class="anchored" data-anchor-id="conclusions">Conclusions</h2>
<p>I have enjoyed learning the basics of making GUIs with Tk in Scheme and R. I don’t mind the outdated look of the widgets and I like the compactness of the interface (compared to a Shiny app). I think it would be fun to make a <code>chez-tk</code> version of my <a href="https://github.com/hinkelman/Shiny-Scorekeeper">Shiny-Scorekeeper app</a> (or even a <code>tcltk</code> version in R). I’m also interested in the possibility of packaging <code>chez-tk</code> and <code>tcltk</code> apps into standalone executables.</p>


</section>

 ]]></description>
  <category>Scheme</category>
  <category>dataframe</category>
  <category>gnuplot-pipe</category>
  <category>chez-tk</category>
  <category>Tk</category>
  <guid>https://www.travishinkelman.com/posts/eda-scheme-tk.html</guid>
  <pubDate>Thu, 26 Dec 2024 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Reading JSON files as Scheme dataframes</title>
  <link>https://www.travishinkelman.com/posts/json-dataframe-scheme.html</link>
  <description><![CDATA[ 




<p>In a <a href="../posts/reading-and-writing-json-files-in-r-and-chez-scheme/">previous post</a>, I wrote about reading and writing JSON files in R and Chez Scheme. After updating that post, I was curious about how much code it would take to convert a Scheme object read from a JSON file into a <a href="https://akkuscm.org/packages/dataframe/">dataframe</a>. It is arguably a rare circumstance that a dataframe is the best data representation for JSON. In this post, we will tackle the limited case of reading JSON files that were created by writing R dataframes to JSON.</p>
<p>First, let’s use the <a href="https://jeroen.cran.dev/jsonlite/"><code>jsonlite</code> package</a> for R to write the <a href="https://allisonhorst.github.io/palmerpenguins/"><code>palmerpenguins</code> dataset</a> to JSON. <code>toJSON</code> provides the option to convert to row- or column-based JSON formats. [The JSON files created with the R code below are available <a href="../data/penguins-row.json">here</a> and <a href="../data/penguins-col.json">here</a>.]</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;">library</span>(jsonlite)</span>
<span id="cb1-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(palmerpenguins)</span>
<span id="cb1-3"></span>
<span id="cb1-4"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">writeLines</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">toJSON</span>(penguins, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dataframe =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"rows"</span>), </span>
<span id="cb1-5">           <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"penguins-row.json"</span>)</span>
<span id="cb1-6"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">writeLines</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">toJSON</span>(penguins, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dataframe =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"columns"</span>), </span>
<span id="cb1-7">           <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"penguins-col.json"</span>)</span></code></pre></div></div>
<p>Next, let’s import our Scheme libraries and read the data. We are using the <a href="https://akkuscm.org/packages/json-tools/"><code>json-tools</code> library</a> for reading JSON.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb2-1">(import (json)</span>
<span id="cb2-2">        (dataframe))</span>
<span id="cb2-3"></span>
<span id="cb2-4">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> json-row</span></span>
<span id="cb2-5">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">call-with-input-file</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"penguins-row.json"</span> json-read))</span>
<span id="cb2-6"></span>
<span id="cb2-7">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> json-col</span></span>
<span id="cb2-8">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">call-with-input-file</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"penguins-col.json"</span> json-read))</span></code></pre></div></div>
<p>Tabular data in JSON can be oriented by rows or columns.</p>
<blockquote class="blockquote">
<p>However, unfortunately R is an exception in its preference for column-based storage: most languages, systems, databases, APIs, etc, are optimized for record based operations. For this reason, the conventional way to store and communicate tabular data in JSON seems to almost exclusively row based.</p>
</blockquote>
<p>Given that, let’s start with <code>json-row</code>. <code>json-read</code> converts the row-based format into a list of vectors where each vector represents a row comprised of pairs with the column name and row value.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb3-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> json-row)</span>
<span id="cb3-2"></span>
<span id="cb3-3">#((<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"species"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Adelie"</span>) (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"island"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Torgersen"</span>)</span>
<span id="cb3-4">  (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"bill_length_mm"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">39.1</span>) (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"bill_depth_mm"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">18.7</span>)</span>
<span id="cb3-5">  (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"flipper_length_mm"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">181</span>) (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"body_mass_g"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3750</span>)</span>
<span id="cb3-6">  (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sex"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"male"</span>) (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"year"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>))</span></code></pre></div></div>
<p><code>toJSON</code> handles missing values in the row-based format by not including the name-value pair.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb4-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">list-ref</span> json-row <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)</span>
<span id="cb4-2"></span>
<span id="cb4-3">#((<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"species"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Adelie"</span>) (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"island"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Torgersen"</span>)</span>
<span id="cb4-4">  (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"year"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>))</span></code></pre></div></div>
<p>To convert to a dataframe, we need the column names, but we can’t just use <code>(car json-row)</code> because it might not include all of the column names. The following procedure gets the length of each row <code>n</code> and finds the number of columns <code>n-max</code>. We <code>cons</code> the <code>n</code> values onto an index <code>ind</code> because we use <code>list-ref</code> to get one of the rows from <code>json-row</code> that includes all columns. From there, we extract the column names from that row. Of course, if you know, for example, that the first row contains all columns, then you can just use <code>(map car (vector-&gt;list (car json-row)))</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb5-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">get-names-str </span>json-row)</span>
<span id="cb5-2">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let*</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>ind (iota (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">length</span> json-row))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb5-3">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>n (map <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">vector-length</span> json-row)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb5-4">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>n-max (apply <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">max</span> n)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb5-5">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>n-sub (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">filter</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (pair)</span>
<span id="cb5-6">                          (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> pair) n-max))</span>
<span id="cb5-7">                        (map <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cons</span> n ind))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb5-8">    (map <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">vector-&gt;list</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">list-ref</span> json-row (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cdr</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> n-sub)))))))</span>
<span id="cb5-9"></span>
<span id="cb5-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (get-names-str json-row)</span>
<span id="cb5-11"></span>
<span id="cb5-12">(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"species"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"island"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"bill_length_mm"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"bill_depth_mm"</span></span>
<span id="cb5-13">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"flipper_length_mm"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"body_mass_g"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sex"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"year"</span>)</span></code></pre></div></div>
<p>The row-based JSON values are extracted into a row-based list of lists with <code>get-vals</code>. We use nested maps to map over all rows and all column names. If a column name is not found (via <code>assoc</code>), then we return ’na (symbol used for missing values in the <code>dataframe</code> library) to create sub-lists that all have the same length.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb6-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">get-vals </span>json-row names-str)</span>
<span id="cb6-2">  (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (vec)</span>
<span id="cb6-3">         (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (nm)</span>
<span id="cb6-4">                (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>pair (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">assoc</span> nm (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">vector-&gt;list</span> vec))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb6-5">                  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> pair (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cdr</span> pair) 'na)))</span>
<span id="cb6-6">              names-str))</span>
<span id="cb6-7">       json-row))</span>
<span id="cb6-8"></span>
<span id="cb6-9"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> (get-vals json-row (get-names-str json-row)))</span>
<span id="cb6-10"></span>
<span id="cb6-11">(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Adelie"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Torgersen"</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">39.1</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">18.7</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">181</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3750</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"male"</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>)</span>
<span id="cb6-12"></span>
<span id="cb6-13"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">list-ref</span> (get-vals json-row (get-names-str json-row)) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)</span>
<span id="cb6-14"></span>
<span id="cb6-15">(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Adelie"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Torgersen"</span> na na na na na <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>)</span></code></pre></div></div>
<p>We transpose the values into a list of columns that is the same length as our column names. A dataframe in Scheme is comprised of a list of series that are all the same length. <code>make-series</code> takes a name as symbol and a list of values to make a new series. <code>transpose</code> is provided by the dataframe library.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb7-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> row-df</span></span>
<span id="cb7-2">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>names-str (get-names-str json-row)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb7-3">    (make-dataframe</span>
<span id="cb7-4">     (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (nm lst)</span>
<span id="cb7-5">            (make-series nm lst))</span>
<span id="cb7-6">          (map <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string-&gt;symbol</span> names-str)</span>
<span id="cb7-7">          (transpose (get-vals json-row names-str))))))</span>
<span id="cb7-8"></span>
<span id="cb7-9"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (dataframe-glimpse row-df)</span>
<span id="cb7-10"></span>
<span id="cb7-11"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">344</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span> cols</span>
<span id="cb7-12"> species            &lt;str&gt;   Adelie, Adelie, Adelie, Adelie, Adelie, Adelie, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> </span>
<span id="cb7-13"> island             &lt;str&gt;   Torgersen, Torgersen, Torgersen, Torgersen, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span>     </span>
<span id="cb7-14"> bill_length_mm     &lt;num&gt;   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">39.1</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">39.5</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">40.3</span>, na, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">36.7</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">39.3</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">38.9</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">39.2</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span>   </span>
<span id="cb7-15"> bill_depth_mm      &lt;num&gt;   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">18.7</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">17.4</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">18</span>, na, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">19.3</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">20.6</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">17.8</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">19.6</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span>     </span>
<span id="cb7-16"> flipper_length_mm  &lt;num&gt;   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">181</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">186</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">195</span>, na, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">193</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">190</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">181</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">195</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">193</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span>     </span>
<span id="cb7-17"> body_mass_g        &lt;num&gt;   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3750</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3800</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3250</span>, na, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3450</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3650</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3625</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4675</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span>   </span>
<span id="cb7-18"> sex                &lt;str&gt;   male, female, female, na, female, male, female, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> </span>
<span id="cb7-19"> year               &lt;num&gt;   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> </span></code></pre></div></div>
<p>Let’s switch gears to working with the column-based case and the <code>json-col</code> object that we created earlier. <code>json-read</code> converts the column-based format into a vector of lists where the first item of each list is the column name and the other values are the column values.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb8-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (list-head (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">list-ref</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">vector-&gt;list</span> json-col) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>)</span>
<span id="cb8-2"></span>
<span id="cb8-3">(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"body_mass_g"</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3750</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3800</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3250</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"NA"</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3450</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3650</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3625</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4675</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3475</span>)</span>
<span id="cb8-4"></span>
<span id="cb8-5"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (list-head (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">list-ref</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">vector-&gt;list</span> json-col) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>)</span>
<span id="cb8-6"></span>
<span id="cb8-7">(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sex"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"male"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"female"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"female"</span> null <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"female"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"male"</span></span>
<span id="cb8-8">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"female"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"male"</span> null)</span></code></pre></div></div>
<p>Because the column-based format is similar to the structure of a dataframe, the code to convert <code>json-col</code> to a dataframe is simpler.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb9-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> col-df</span></span>
<span id="cb9-2">  (make-dataframe</span>
<span id="cb9-3">   (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (col)</span>
<span id="cb9-4">          (make-series</span>
<span id="cb9-5">           (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string-&gt;symbol</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> col))</span>
<span id="cb9-6">           (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cdr</span> col)))</span>
<span id="cb9-7">        (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">vector-&gt;list</span> json-col))))</span>
<span id="cb9-8"></span>
<span id="cb9-9"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (dataframe-glimpse col-df)</span>
<span id="cb9-10"></span>
<span id="cb9-11"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">344</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span> cols</span>
<span id="cb9-12"> species            &lt;str&gt;   Adelie, Adelie, Adelie, Adelie, Adelie, Adelie, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> </span>
<span id="cb9-13"> island             &lt;str&gt;   Torgersen, Torgersen, Torgersen, Torgersen, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span>     </span>
<span id="cb9-14"> bill_length_mm     &lt;num&gt;   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">39.1</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">39.5</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">40.3</span>, na, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">36.7</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">39.3</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">38.9</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">39.2</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span>   </span>
<span id="cb9-15"> bill_depth_mm      &lt;num&gt;   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">18.7</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">17.4</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">18</span>, na, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">19.3</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">20.6</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">17.8</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">19.6</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span>     </span>
<span id="cb9-16"> flipper_length_mm  &lt;num&gt;   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">181</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">186</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">195</span>, na, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">193</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">190</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">181</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">195</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">193</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span>     </span>
<span id="cb9-17"> body_mass_g        &lt;num&gt;   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3750</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3800</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3250</span>, na, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3450</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3650</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3625</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4675</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span>   </span>
<span id="cb9-18"> sex                &lt;str&gt;   male, female, female, null, female, male, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span>       </span>
<span id="cb9-19"> year               &lt;num&gt;   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> </span></code></pre></div></div>
<p>For missing values in the column-based format, <code>toJSON</code> uses <code>NA</code> for numbers and <code>null</code> for strings. <code>json-read</code> leaves the <code>NA</code> as is and converts the <code>null</code> to <code>'null</code>, but <code>make-dataframe</code> automatically converts <code>NA</code> to <code>'na</code> (missing value representation) and <code>'null</code> to <code>"null"</code> (because of implicit conversion to maintain same type throughout the column). It isn’t strictly necessary to convert <code>"null"</code> to <code>'na</code>, but we will do that below. If you already know that only the <code>sex</code> column has <code>null</code> values, then you can modify just that column. Alternatively, we can identify the names of the string columns with some mapping and filtering and apply the same procedure to all string columns.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb10-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> col-df2</span></span>
<span id="cb10-2">  (dataframe-modify*</span>
<span id="cb10-3">   col-df</span>
<span id="cb10-4">   (sex (sex) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> sex <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"null"</span>) 'na sex))))</span>
<span id="cb10-5"></span>
<span id="cb10-6">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> col-df3</span></span>
<span id="cb10-7">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let*</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>name-type (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (series)</span>
<span id="cb10-8">                           (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cons</span> (series-type series)</span>
<span id="cb10-9">                                 (series-name series)))</span>
<span id="cb10-10">                         (dataframe-slist col-df))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb10-11">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>str-names (map <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cdr</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">filter</span></span>
<span id="cb10-12">                              (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (pair)</span>
<span id="cb10-13">                                (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">symbol=?</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> pair) 'str))</span>
<span id="cb10-14">                              name-type))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb10-15">    (apply</span>
<span id="cb10-16">     dataframe-modify-at</span>
<span id="cb10-17">     col-df</span>
<span id="cb10-18">     (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (x) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> x <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"null"</span>) 'na x))</span>
<span id="cb10-19">     str-names)))</span>
<span id="cb10-20"></span>
<span id="cb10-21"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (dataframe-equal? row-df col-df)</span>
<span id="cb10-22"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#f</span></span>
<span id="cb10-23"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (dataframe-equal? row-df col-df2 col-df3)</span>
<span id="cb10-24"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#t</span></span></code></pre></div></div>
<p>I thought about adding this functionality to the <code>dataframe</code> library, but I don’t think it is a common enough use case to warrant the additional code maintenance and dependency on <code>json-tools</code>.</p>



 ]]></description>
  <category>Scheme</category>
  <category>json-tools</category>
  <category>dataframe</category>
  <category>R</category>
  <category>jsonlite</category>
  <category>JSON</category>
  <guid>https://www.travishinkelman.com/posts/json-dataframe-scheme.html</guid>
  <pubDate>Wed, 06 Nov 2024 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Horse racing game win probability</title>
  <link>https://www.travishinkelman.com/posts/horse-game.html</link>
  <description><![CDATA[ 




<p>When gathering with family, we like to play yard, card, and board games. On a recent visit, one of the favorite games was the <a href="https://www.scheels.com/p/79830436058/">Across the Board Kentucky Derby Horse Racing Game</a>. The game produced a lot of cheers and jeers and provided a fun diversion with no skill and little concentration required. After losing a little money, though, I lost interest in playing the game and decided to write some R code to simulate the game and generate win probabilities.</p>
<p>The game involves dealing a deck of cards (with Kings and Aces removed) to any number of players (well, up to 44 players where each player would be dealt one card). The cards in a player’s hand represent wagers on the winning horse where horses are numbered 2-12 and the jack and queen cards represent 11 and 12, respectively. Two dice are rolled and the total of the dice determines which horse moves around the board. The number of steps for a horse to win is scaled roughly in proportion to the probability of that number being rolled. Below we enumerate all of the possible rolls with <code>expand.grid</code>, calculate the probability of each roll, and compare those probabilities to the probabilities based on the number of steps included on the game board.</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">rolls_df <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">expand.grid</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dice1 =</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;">6</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dice2 =</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;">6</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb1-2">  dplyr<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;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">roll =</span> dice1 <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> dice2) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb1-3">  dplyr<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;">count</span>(roll) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb1-4">  dplyr<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;">mutate</span>(</span>
<span id="cb1-5">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">steps =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">14</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">16</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">14</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>),</span>
<span id="cb1-6">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">prob =</span> n <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>(n),</span>
<span id="cb1-7">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">prob_steps =</span> steps <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>(steps)</span>
<span id="cb1-8">  )</span>
<span id="cb1-9"></span>
<span id="cb1-10"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> rolls_df</span>
<span id="cb1-11"></span>
<span id="cb1-12">   roll n steps       prob prob_steps</span>
<span id="cb1-13"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.02777778</span>       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.03</span></span>
<span id="cb1-14"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.05555556</span>       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.06</span></span>
<span id="cb1-15"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.08333333</span>       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.08</span></span>
<span id="cb1-16"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.11111111</span>       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.11</span></span>
<span id="cb1-17"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">14</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.13888889</span>       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.14</span></span>
<span id="cb1-18"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">16</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.16666667</span>       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.16</span></span>
<span id="cb1-19"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">14</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.13888889</span>       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.14</span></span>
<span id="cb1-20"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.11111111</span>       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.11</span></span>
<span id="cb1-21"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.08333333</span>       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.08</span></span>
<span id="cb1-22"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.05555556</span>       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.06</span></span>
<span id="cb1-23"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.02777778</span>       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.03</span></span></code></pre></div></div>
<p>We can use the <code>sample</code> function to simulate rolling the dice. <code>sample.int</code> provides better performance, but requires adding <code>1L</code> to shift our samples from <code>1:11</code> to our horse numbers of <code>2:12</code>.</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">roll <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(n, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">replace =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">prob =</span> rolls_df<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>prob) {</span>
<span id="cb2-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sample.int</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> n, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">replace =</span> replace, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">prob =</span> prob) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>L</span>
<span id="cb2-3">}</span>
<span id="cb2-4"></span>
<span id="cb2-5"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">roll</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500000</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;">500000</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)</span>
<span id="cb2-6"></span>
<span id="cb2-7">    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span> </span>
<span id="cb2-8"><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.028</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.055</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.084</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.111</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.139</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.167</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.139</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.111</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.083</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.056</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.028</span> </span></code></pre></div></div>
<p>With this board setup, all horses have a roughly equal probability of winning because the horses that are rolled more rarely have fewer steps to move around the board. The game dynamics are made more interesting by introducing scratches, i.e., horses that are not able to participate in a race. We can use our <code>roll</code> function to generate the scratches. The number of scratches is always four different horses.</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="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">roll</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">replace =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span>)</span>
<span id="cb3-2">[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>] <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span></span></code></pre></div></div>
<p>The scratches determine how much players must contribute to the kitty. The first scratch horse is 1x and the last is 4x. Players pay the scratch value for every card in their hand that matches a scratch horse. We played with quarters so the starting kitty was always $10. Every time a player rolls a value that matches the scratch horse, they have to contribute that scratch amount to the kitty. The following function calculates the value of the kitty given a vector of dice rolls. In the example below, each rolled 7 would require the player to put a quarter in the kitty and the 10 would require $0.75.</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">get_kitty <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(base_value, scratches, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">rolls =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NULL</span>) {</span>
<span id="cb4-2">  init <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> base_value <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># multiply by 4 for 4 suits in deck</span></span>
<span id="cb4-3">  vals <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NULL</span></span>
<span id="cb4-4">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.null</span>(rolls) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">length</span>(rolls) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) {</span>
<span id="cb4-5">    vals <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sapply</span>(rolls, <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(x) {</span>
<span id="cb4-6">      mult <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">which</span>(scratches <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> x) <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># index in scratches indicates multiplier</span></span>
<span id="cb4-7">      <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">length</span>(mult) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) mult <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> base_value <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span></span>
<span id="cb4-8">    })</span>
<span id="cb4-9">  }</span>
<span id="cb4-10">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sum</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(init, vals))</span>
<span id="cb4-11">}</span>
<span id="cb4-12"></span>
<span id="cb4-13"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> base_value <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.25</span></span>
<span id="cb4-14"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> scratches <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">roll</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span>)</span>
<span id="cb4-15"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> rolls <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">roll</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>)</span>
<span id="cb4-16"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> scratches</span>
<span id="cb4-17">[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span></span>
<span id="cb4-18"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> rolls</span>
<span id="cb4-19">[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span></span>
<span id="cb4-20"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">get_kitty</span>(base_value, scratches)</span>
<span id="cb4-21">[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>] <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span></span>
<span id="cb4-22"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">get_kitty</span>(base_value, scratches, rolls)</span>
<span id="cb4-23">[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>] <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">11.25</span></span></code></pre></div></div>
<p>Rather than trying to do the math to determine how likely each horse is to win. I used Monte Carlo simulations to find the win probabilities for any point in a game (described by vector of rolls). I’ve covered most of the basic logic of the calculations here, but all of the code is available through <a href="https://github.com/hinkelman/horse-game">GitHub</a>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb5-1">sim_one_game <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(scratches, rolls, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">winner_only =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>) {</span>
<span id="cb5-2">  steps_remain <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">get_steps_remain</span>(scratches, rolls)</span>
<span id="cb5-3">  active <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(steps_remain)</span>
<span id="cb5-4">  sr <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> steps_remain</span>
<span id="cb5-5">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">any</span>(sr[active] <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)) {</span>
<span id="cb5-6">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">stop</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Winner was already determined"</span>)</span>
<span id="cb5-7">  }</span>
<span id="cb5-8">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># conservative choice; highly unlikely to need 200 rolls to finish a game</span></span>
<span id="cb5-9">  sim_rolls_pool <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">roll</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">200</span>)</span>
<span id="cb5-10">  i <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span>
<span id="cb5-11">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">while</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">all</span>(sr[active] <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)) {</span>
<span id="cb5-12">    r <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> sim_rolls_pool[i] <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># integer 2–12</span></span>
<span id="cb5-13">    i <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> i <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span>
<span id="cb5-14">    idx <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> r <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>L <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># integer 1–11</span></span>
<span id="cb5-15">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (active[idx]) {</span>
<span id="cb5-16">      sr[idx] <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> sr[idx] <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>L</span>
<span id="cb5-17">    }</span>
<span id="cb5-18">  }</span>
<span id="cb5-19">  winner <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">names</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">which</span>(sr <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;">0</span>))</span>
<span id="cb5-20">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (winner_only) {</span>
<span id="cb5-21">    winner</span>
<span id="cb5-22">  } <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> {</span>
<span id="cb5-23">    sim_rolls <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> sim_rolls_pool[<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">seq_len</span>(i <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)] <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># trim to actual length</span></span>
<span id="cb5-24">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">list</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"winner"</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> winner, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"rolls"</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(rolls, sim_rolls))</span>
<span id="cb5-25">  }</span>
<span id="cb5-26">}</span></code></pre></div></div>
<p>I ran 100,000 simulations of the game to determine which horses win most often. 2 or 12 each win about 20% of the time, 3/11 and 4/10 ~ 9.5%, 5/9 = 5.5%, 6/7/8 = 3.5%. The primary driver behind that outcome is that 2 and 12 are less likely to end up as scratches than 3 and 11 and so on. 4/10 have roughly the same win probability as 3/11, despite 4/10 requiring more steps to move around the board than 3/11, which is a byproduct of how the board is discretized and is evident in <code>rolls_df</code> where the <code>prob</code> is higher than the <code>prob_steps</code> for 4/10. Same idea applies to why 7 has a similar win probability to 6/8.</p>
<p>The figure below shows the kitty distribution paneled by the winning horse for those 100,000 simulated games with a base value of $0.25. The overall average kitty was $24.45 with the winner-specific averages ranging from $22.30 (12) to $26.80 (8). The kitty grows largest in games where 6/7/8 win because it takes the most steps for those horses to make it around the board.</p>
<p><img src="https://www.travishinkelman.com/img/kitty-ggridges.png" class="img-fluid"></p>
<p>Lastly, I thought it would be fun to record the game live and provide updates on which horse was most likely to win as the game progressed. I was initially doing that within my original R script, but I decided to make a <a href="https://hinkelman.shinyapps.io/horse-game/">Shiny app</a> to facilitate that process. The app layout is not great and it is missing some useful functionality (e.g., roll history not displayed and not able to undo if wrong button was clicked).</p>
<p>UPDATE (2026-04-01): I have been resistant to adopting AI. I would like to say that my resistance was born of noble intentions based on environmental and ethical concerns, but it arguably arose more from my negative emotions related to AI potentially taking away my favorite tasks at work. Recently, though, I have started experimenting with Claude and found myself enjoying finishing long languishing side projects. One example was improving my little Shiny app for the horse game. It is now much more compact and useable on a mobile device. The new version includes the roll history, an undo button, and disabling of inputs for invalid states. I also dropped the plots in favor of a cleaner approach with value boxes.</p>
<p>My initial version performed a lot of the calculations within dataframes using <code>dplyr</code> functionality. I found that approach intuitive, but it was slow so I rewrote it with the vector approach (see <a href="https://github.com/hinkelman/horse-game">repo</a>).</p>



 ]]></description>
  <category>R</category>
  <category>Shiny</category>
  <guid>https://www.travishinkelman.com/posts/horse-game.html</guid>
  <pubDate>Sat, 26 Oct 2024 00:00:00 GMT</pubDate>
</item>
<item>
  <title>RPI and SOS in Scheme, Python, and Elixir</title>
  <link>https://www.travishinkelman.com/posts/rpi.html</link>
  <description><![CDATA[ 




<p>Last spring, I played in a 3x3 basketball leage with 14 teams and only 6 regular-season games. The unbalanced schedule made me wonder if we would end up with wonky playoff seeding. I thought it would be fun to calculate the Rating Percentage Index (RPI) and Strength Of Schedule (SOS) for each team to assess discrepancies between W-L record and team rating. I was mostly following the R code for RPI in <a href="http://dpmartin42.github.io/posts/r/college-basketball-rankings">this post</a> and the SOS calculations <a href="https://hackastat.eu/en/learn-a-stat-strength-of-schedule-sos/">here</a>. For comparison, I wrote code in Scheme (<a href="https://github.com/hinkelman/dataframe">dataframe</a>), Python (<a href="https://pola.rs/">Polars</a>), and Elixir (<a href="https://hexdocs.pm/explorer/Explorer.html">Explorer</a>), which is also using <a href="https://docs.rs/polars/latest/polars/">Polars</a> as the backend. All code and data are available <a href="https://github.com/hinkelman/rpi">here</a>. Disclaimer: the Python and Elixir code works, but it may not be the most idiomatic or performant way to write that code.</p>
<p>First, let’s load libraries and read the data.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb1-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Scheme dataframe</span></span>
<span id="cb1-2">(import (dataframe))</span>
<span id="cb1-3"></span>
<span id="cb1-4">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> df </span>(csv-&gt;dataframe <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"GameResults.csv"</span>))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Python Polars</span></span>
<span id="cb2-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> polars <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> pl</span>
<span id="cb2-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> statistics <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> stats</span>
<span id="cb2-4"></span>
<span id="cb2-5">df <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pl.read_csv(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"GameResults.csv"</span>)</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb3-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Elixir Explorer</span></span>
<span id="cb3-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">require</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Explorer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">DataFrame</span>, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">as:</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">DF</span></span>
<span id="cb3-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">require</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Explorer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Series</span>, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">as:</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Series</span></span>
<span id="cb3-4"></span>
<span id="cb3-5">df <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">DF</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>from_csv!<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"GameResults.csv"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div></div>
<p>Every game was comprised of three sets to 21 points (win by two points). The league tracked W-L record by game, but I used sets to increase the amount of data. The actual RPI calculation includes a weighting factor for home and away games, but all of these games were played at a neutral site, which simplified the calculations. There were several forfeits, which the league tracked as losses, but I decided to exclude them from my dataset.</p>
<p>This is the format of the raw data…</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb4-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (dataframe-display df)</span>
<span id="cb4-2"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">132</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> cols</span>
<span id="cb4-3">    week     set       winner         loser  winner_score  loser_score </span>
<span id="cb4-4">   &lt;num&gt;   &lt;num&gt;        &lt;str&gt;         &lt;str&gt;         &lt;num&gt;        &lt;num&gt; </span>
<span id="cb4-5">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.   Above ParR  CityOfThrees           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">22</span>.          <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">16</span>. </span>
<span id="cb4-6">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>.   Above ParR  CityOfThrees           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">23</span>.          <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">21</span>. </span>
<span id="cb4-7">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>.   Above ParR  CityOfThrees           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">21</span>.          <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span>. </span>
<span id="cb4-8">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.        Kangz          Tsaf           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">21</span>.          <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">17</span>. </span>
<span id="cb4-9">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>.         Tsaf         Kangz           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">21</span>.          <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">19</span>. </span>
<span id="cb4-10">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>.        Kangz          Tsaf           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">21</span>.          <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span>. </span>
<span id="cb4-11">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.  Team Avatar        Motley           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">22</span>.          <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">14</span>. </span>
<span id="cb4-12">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>.       Motley   Team Avatar           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">21</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>. </span>
<span id="cb4-13">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>.       Motley   Team Avatar           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">23</span>.          <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">21</span>. </span>
<span id="cb4-14">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.     Chow Men      Bob Ross           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">21</span>.          <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>. </span></code></pre></div></div>
<p>The approach to calculating W-L record involves two passes through the data, which could prove costly with a larger dataset. The <code>type</code> parameter refers to the <code>winner</code> or <code>loser</code> column in the dataframe and is passed as a symbol (Scheme), string (Python), or atom (Elixir). Polars and Explorer both use square brackets for extracting a dataframe column whereas <code>$</code> is used in Scheme dataframe.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb5-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Scheme dataframe</span></span>
<span id="cb5-2">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">calc-wl </span>game-data team type)</span>
<span id="cb5-3">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">length</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">filter</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (x) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> team x)) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> game-data type))))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb6-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Python Polars</span></span>
<span id="cb6-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> calc_wl(game_data, team, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">type</span>):</span>
<span id="cb6-3">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> pl.Series.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>(game_data[<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">type</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> team)</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb7-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Elixir Explorer</span></span>
<span id="cb7-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> calc_wl<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game_data, team, type<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb7-3">  <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Series</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>sum<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Series</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>equal<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game_data<span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span>type<span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span>, team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">))</span></span>
<span id="cb7-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>All of the calculations involve filtering the dataset to the focal <code>team</code> and potentially excluding games played against another team (<code>opp</code>). Perhaps the most notable difference here (other than the verbosity of the Scheme code) is the different ways that dataframe columns are referenced. Scheme dataframe and Explorer use unquoted column names. Polars uses the <code>col</code> function and quoted names. In Explorer, a query expression expects unquoted names to refer to dataframe columns and the <code>^</code> is needed to indicate that a variable is defined outside of the query (e.g., <code>^team</code> and <code>^opp</code>). In Scheme dataframe, column names are specified separately (i.e., <code>(winner loser)</code>) to create the distinction between column names and other variables. This approach was taken to mirror lambda syntax, but maybe I should explore whether I could use the <code>^</code> inside the filter expression to avoid the redundant listing of column names.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb8-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Scheme dataframe</span></span>
<span id="cb8-2">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter-team </span>game-data team)</span>
<span id="cb8-3">  (dataframe-filter*</span>
<span id="cb8-4">   game-data</span>
<span id="cb8-5">   (winner loser)</span>
<span id="cb8-6">   (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">or</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> winner team)</span>
<span id="cb8-7">       (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> loser team))))</span>
<span id="cb8-8"></span>
<span id="cb8-9">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter-team-opp </span>game-data team opp)</span>
<span id="cb8-10">  (dataframe-filter*</span>
<span id="cb8-11">   (filter-team game-data team)</span>
<span id="cb8-12">   (winner loser)</span>
<span id="cb8-13">   (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> winner opp))</span>
<span id="cb8-14">        (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> loser opp)))))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb9-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Python Polars</span></span>
<span id="cb9-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> filter_team(game_data, team):</span>
<span id="cb9-3">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> pl.DataFrame.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">filter</span>(</span>
<span id="cb9-4">        game_data, </span>
<span id="cb9-5">        (pl.col(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"winner"</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> team) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> (pl.col(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"loser"</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> team))</span>
<span id="cb9-6"></span>
<span id="cb9-7"></span>
<span id="cb9-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> filter_team_opp(game_data, team, opp):</span>
<span id="cb9-9">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> pl.DataFrame.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">filter</span>(</span>
<span id="cb9-10">        filter_team(game_data, team),</span>
<span id="cb9-11">        (pl.col(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"winner"</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> opp) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> (pl.col(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"loser"</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> opp))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb10-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Elixir Explorer</span></span>
<span id="cb10-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> filter_team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game_data, team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb10-3">  <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">DF</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>filter<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game_data, winner <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">^</span>team <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">or</span> loser <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">^</span>team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb10-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb10-5"></span>
<span id="cb10-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> filter_team_opp<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game_data, team, opp<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb10-7">  <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">DF</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>filter<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>filter_team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game_data, team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span>, winner<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> !=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">^</span>opp <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> loser<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> !=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">^</span>opp<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb10-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>I’ve arguably opted to split the code into too many function as indicated by the difficulty I had in naming this next function. This code takes the dataframe column of winners and finds the proportion that match the specified team. This function is only applied to a filtered dataset for the specified team.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb11-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Scheme</span></span>
<span id="cb11-2">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">wp </span>winners team)</span>
<span id="cb11-3">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>team-winners (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">filter</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (x) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> team x)) winners)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb11-4">    (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">inexact</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">length</span> team-winners) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">length</span> winners)))))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb12-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Python Polars</span></span>
<span id="cb12-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> wp(winners, team):</span>
<span id="cb12-3">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> pl.Series.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>(winners <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> team) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> pl.Series.count(winners)</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb13-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Elixir Explorer</span></span>
<span id="cb13-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> wp<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>winners, team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb13-3">  <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Series</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>sum<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Series</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>equal<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>winners, team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">))</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Series</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>count<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>winners<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb13-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>In <code>calc-wp</code>, we are combining our previous functions so the code is similar in all languages.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb14-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Scheme dataframe</span></span>
<span id="cb14-2">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">calc-wp </span>game-data team)</span>
<span id="cb14-3">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>games-played (filter-team game-data team)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb14-4">    (wp (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> games-played 'winner) team)))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb15-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Python Polars</span></span>
<span id="cb15-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> calc_wp(game_data, team):</span>
<span id="cb15-3">  games_played <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> filter_team(game_data, team)</span>
<span id="cb15-4">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> wp(games_played[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"winner"</span>], team)</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb16-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Elixir Explorer</span></span>
<span id="cb16-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> calc_wp<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game_data, team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb16-3">  games_played <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> filter_team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game_data, team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb16-4">  wp<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>games_played<span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:winner</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span>, team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb16-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>I was also interested in point differential (PD) as a metric, but it became clear as the season wore on that the scores were not very accurate. The league used set differential as a tiebreaker so the scores were largely irrelevant as long as they recorded the correct set winners and losers. I’ve included two versions of the Scheme code for comparison. While legible, I find the Polars code a bit ugly here.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb17-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Scheme</span></span>
<span id="cb17-2">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">calc-pd </span>game-data team)</span>
<span id="cb17-3">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let*</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>games-played (filter-team game-data team)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb17-4">    (sum (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (w ws ls) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> team w) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> ws ls) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> ls ws)))</span>
<span id="cb17-5">              (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> games-played 'winner)</span>
<span id="cb17-6">              (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> games-played 'winner_score)</span>
<span id="cb17-7">              (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> games-played 'loser_score)))))</span>
<span id="cb17-8"></span>
<span id="cb17-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Scheme dataframe</span></span>
<span id="cb17-10">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">calc-pd </span>game-data team)</span>
<span id="cb17-11">  (-&gt; game-data</span>
<span id="cb17-12">      (filter-team team)</span>
<span id="cb17-13">      (dataframe-modify*</span>
<span id="cb17-14">       (pd (winner winner_score loser_score)</span>
<span id="cb17-15">           (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> team winner)</span>
<span id="cb17-16">               (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> winner_score loser_score)</span>
<span id="cb17-17">               (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> loser_score winner_score))))</span>
<span id="cb17-18">      (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> 'pd)</span>
<span id="cb17-19">      (sum)))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb18-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Python Polars</span></span>
<span id="cb18-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> calc_pd(game_data, team):</span>
<span id="cb18-3">    pd <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pl.DataFrame.with_columns(</span>
<span id="cb18-4">        filter_team(game_data, team),</span>
<span id="cb18-5">        pl.when(pl.col(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"winner"</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> team)</span>
<span id="cb18-6">        .then(pl.col(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"winner_score"</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> pl.col(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"loser_score"</span>))</span>
<span id="cb18-7">        .otherwise(pl.col(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"loser_score"</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> pl.col(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"winner_score"</span>))</span>
<span id="cb18-8">        .alias(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"pd"</span>))</span>
<span id="cb18-9">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> pl.Series.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>(pd[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"pd"</span>])</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb19-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Elixir Explorer</span></span>
<span id="cb19-2">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> calc_pd<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game_data, team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb19-3">    game_data</span>
<span id="cb19-4">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> filter_team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb19-5">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">DF</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>mutate<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb19-6">      <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">pd:</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>winner <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">^</span>team, </span>
<span id="cb19-7">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">do:</span> winner_score <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> loser_score, </span>
<span id="cb19-8">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>: loser_score <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> winner_score<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb19-9">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb19-10">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">DF</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>pull<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"pd"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb19-11">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Series</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>sum<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb19-12">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>In calculating the opponents’ winning percentage, we need to exclude games played against the focal team with <code>filter-team-opp</code>. The way the parameters are named is potentially confusing. In <code>(map (lambda (x) (calc-wp-owp game-data x team)) opps)</code>, we are iterating through all opponents of <code>team</code> and calculating their WP against everybody except <code>team</code> and then calculating the mean of all opponents’ WP. The function for <code>calc-oowp</code> is is nearly the same as <code>calc-owp</code> so is not shown here.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb20-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Scheme</span></span>
<span id="cb20-2">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">calc-owp </span>game-data team)</span>
<span id="cb20-3">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let*</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>opp-games (filter-team game-data team)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb20-4">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>opps (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (w l) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> team w) l w))</span>
<span id="cb20-5">                    (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> opp-games 'winner)</span>
<span id="cb20-6">                    (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> opp-games 'loser))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb20-7">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>owp (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (x) (calc-wp-owp game-data x team)) opps)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb20-8">    (mean owp)))</span>
<span id="cb20-9"></span>
<span id="cb20-10">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">calc-wp-owp </span>game-data team opp)</span>
<span id="cb20-11">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>games-played (filter-team-opp game-data team opp)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb20-12">    (wp (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> games-played 'winner) team)))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb21-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Python Polars</span></span>
<span id="cb21-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> calc_owp(game_data, team):</span>
<span id="cb21-3">    opp_games <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pl.DataFrame.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">filter</span>(</span>
<span id="cb21-4">        game_data, (pl.col(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"winner"</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> team) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> (pl.col(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"loser"</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> team))</span>
<span id="cb21-5">    opp <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pl.DataFrame.with_columns(</span>
<span id="cb21-6">        opp_games,</span>
<span id="cb21-7">        pl.when(pl.col(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"winner"</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> team)</span>
<span id="cb21-8">        .then(pl.col(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"loser"</span>))</span>
<span id="cb21-9">        .otherwise(pl.col(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"winner"</span>))</span>
<span id="cb21-10">        .alias(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"opp"</span>))</span>
<span id="cb21-11">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> stats.mean([calc_wp_owp(game_data, x, team) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> x <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> opp[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"opp"</span>]])</span>
<span id="cb21-12"></span>
<span id="cb21-13"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> calc_wp_owp(game_data, team, opp):</span>
<span id="cb21-14">  games_played <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> filter_team_opp(game_data, team, opp)</span>
<span id="cb21-15">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> wp(games_played[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"winner"</span>], team)</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb22" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb22-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Elixir Explorer</span></span>
<span id="cb22-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> calc_owp<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game_data, team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb22-3">  game_data</span>
<span id="cb22-4">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">DF</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>filter<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>winner <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">^</span>team <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">or</span> loser <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">^</span>team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb22-5">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">DF</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>mutate<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">opp:</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>winner <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">^</span>team, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">do:</span> loser, <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>: winner<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">))</span></span>
<span id="cb22-6">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">DF</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>pull<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"opp"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb22-7">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># transform is computationally expensive b/c of type conversion</span></span>
<span id="cb22-8">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Series</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>transform<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">fn</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> calc_wp_owp<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game_data, x, team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb22-9">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Series</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>mean<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb22-10"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb22-11"></span>
<span id="cb22-12"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> calc_wp_owp<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game_data, team, opp<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb22-13">  games_played <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> filter_team_opp<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game_data, team, opp<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb22-14">  wp<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>games_played<span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:winner</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span>, team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb22-15"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>The next functions are simple arithmetic, but are included to show Scheme’s prefix mathematical operations and how the <code>\</code> is used in Python to break an operation across lines.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb23" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb23-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Scheme</span></span>
<span id="cb23-2">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">calc-sos </span>game-data team)</span>
<span id="cb23-3">  (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> (calc-owp game-data team)) (calc-oowp game-data team)) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>))</span>
<span id="cb23-4"></span>
<span id="cb23-5">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">calc-rpi </span>game-data team)</span>
<span id="cb23-6">  (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.25</span> (calc-wp game-data team))</span>
<span id="cb23-7">     (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span> (calc-owp game-data team))</span>
<span id="cb23-8">     (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.25</span> (calc-oowp game-data team))))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb24" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb24-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Python</span></span>
<span id="cb24-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> calc_sos(game_data, team):</span>
<span id="cb24-3">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> calc_owp(game_data, team) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> calc_oowp(game_data, team)) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span></span>
<span id="cb24-4"></span>
<span id="cb24-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> calc_rpi(game_data, team):</span>
<span id="cb24-6">  rpi <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.25</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> calc_wp(game_data, team) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb24-7">    <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> calc_owp(game_data, team) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb24-8">    <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.25</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> calc_oowp(game_data, team)</span>
<span id="cb24-9">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> rpi</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb25" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb25-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Elixir</span></span>
<span id="cb25-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> calc_sos<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game_data, team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb25-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> calc_owp<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game_data, team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> calc_oowp<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game_data, team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">))</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span></span>
<span id="cb25-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb25-5"></span>
<span id="cb25-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> calc_rpi<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game_data, team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb25-7">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.25</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> calc_wp<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game_data, team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb25-8">    <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> calc_owp<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game_data, team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb25-9">    <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.25</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> calc_oowp<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game_data, team<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb25-10"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>We need a list of all teams for iteration. Even though both Polars and Explorer are using Rust polars as a backend, my understanding is that Python Polars is using similar naming to Rust polars, but Explorer is creating an API that is more similar to <a href="https://dplyr.tidyverse.org/">R dyplr</a> (e.g., unique vs distinct). Scheme dataframe returns a list whereas Polars and Explorer both return Series. The Scheme list is used in a mapping operation and the Polars Series can be used in a list comprehension, but the Explorer Series is converted to an enumerable for mapping.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb26" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb26-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Scheme</span></span>
<span id="cb26-2">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> teams </span>(remove-duplicates (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">append</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> df 'winner) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> df 'loser))))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb27" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb27-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Python Polars</span></span>
<span id="cb27-2">teams <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"winner"</span>].append(df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"loser"</span>]).unique()</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb28" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb28-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Elixir Explorer</span></span>
<span id="cb28-2">teams <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span></span>
<span id="cb28-3">  <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Series</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>concat<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>df<span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:winner</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span>, df<span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:loser</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb28-4">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Series</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>distinct<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb28-5">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Series</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>to_enum<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">()</span></span></code></pre></div></div>
<p>Finally, we put it all together and create a dataframe with all of our calculated columns sorted by descending RPI. The process is similar in all languages (but, again, most verbose in Scheme) and involves mapping (Scheme, Elixir) or list comprehensions (Python) to iterate over all the teams. In Scheme and Python, we set the number of rows displayed equal to the number of teams. I ran the Elixir code in Livebook and interactively changed the number of rows to display.</p>
<p>I made no effort to write performant code because the dataset is so small, but the Python and Elixir code take 2-3 seconds on my machine while the Scheme code is effectively instanteous. I’m assuming that is mostly overhead of dealing with the Rust polars backend and would be a neglible element of the overall compute time with a larger dataset.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb29" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb29-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Scheme dataframe</span></span>
<span id="cb29-2">(-&gt; (make-dataframe</span>
<span id="cb29-3">     (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">list</span> (make-series 'Team teams)</span>
<span id="cb29-4">           (make-series 'Win (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (x) (calc-wl df x 'winner)) teams))</span>
<span id="cb29-5">           (make-series 'Loss (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (x) (calc-wl df x 'loser)) teams))</span>
<span id="cb29-6">           (make-series 'WP (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (x) (calc-wp df x)) teams))</span>
<span id="cb29-7">           (make-series 'PD (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (x) (calc-pd df x)) teams))</span>
<span id="cb29-8">           (make-series 'SOS (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (x) (calc-sos df x)) teams))</span>
<span id="cb29-9">           (make-series 'RPI (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (x) (calc-rpi df x)) teams))))</span>
<span id="cb29-10">    (dataframe-sort* (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> RPI))</span>
<span id="cb29-11">    (dataframe-display (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">length</span> teams)))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb30" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb30-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Python Polars</span></span>
<span id="cb30-2">pl.Config.set_tbl_rows(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(teams))</span>
<span id="cb30-3">pl.DataFrame(</span>
<span id="cb30-4">  {</span>
<span id="cb30-5">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"team"</span>: teams,</span>
<span id="cb30-6">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"win"</span>: [calc_wl(df, x, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"winner"</span>) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> x <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> teams],</span>
<span id="cb30-7">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"loss"</span>: [calc_wl(df, x, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"loser"</span>) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> x <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> teams],</span>
<span id="cb30-8">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"wp"</span>: [calc_wp(df, x) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> x <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> teams],</span>
<span id="cb30-9">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"pd"</span>: [calc_pd(df, x) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> x <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> teams],</span>
<span id="cb30-10">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sos"</span>: [calc_sos(df, x) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> x <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> teams],</span>
<span id="cb30-11">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"rpi"</span>: [calc_rpi(df, x) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> x <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> teams]</span>
<span id="cb30-12">  }</span>
<span id="cb30-13">).sort(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"rpi"</span>, descending <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb31" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb31-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Elixir Explorer</span></span>
<span id="cb31-2"><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">DF</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>new<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb31-3">  <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">team:</span> teams,</span>
<span id="cb31-4">  <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">win:</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Enum</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>map<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>teams, <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">fn</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">RPI</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>calc_wl<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>df, x, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:winner</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span>,</span>
<span id="cb31-5">  <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">loss:</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Enum</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>map<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>teams, <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">fn</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">RPI</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>calc_wl<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>df, x, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:loser</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span>,</span>
<span id="cb31-6">  <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">wp:</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Enum</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>map<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>teams, <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">fn</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">RPI</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>calc_wp<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>df, x<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span>,</span>
<span id="cb31-7">  <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">pd:</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Enum</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>map<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>teams, <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">fn</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">RPI</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>calc_pd<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>df, x<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span>,</span>
<span id="cb31-8">  <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">sos:</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Enum</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>map<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>teams, <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">fn</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">RPI</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>calc_sos<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>df, x<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span>,</span>
<span id="cb31-9">  <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">rpi:</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Enum</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>map<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>teams, <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">fn</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">RPI</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>calc_rpi<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>df, x<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb31-10"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb31-11"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">DF</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>sort_by<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">desc:</span> rpi<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div></div>
<p>Here were the RPI rankings at the end of the regular season:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb32" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb32-1"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">14</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span> cols</span>
<span id="cb32-2">             Team     Win    Loss      WP      PD     SOS     RPI </span>
<span id="cb32-3">            &lt;str&gt;   &lt;num&gt;   &lt;num&gt;   &lt;num&gt;   &lt;num&gt;   &lt;num&gt;   &lt;num&gt; </span>
<span id="cb32-4">         Spartans     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">16</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.8889</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">141</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5971</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.6701</span> </span>
<span id="cb32-5">         Chow Men     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">14</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.7778</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">103</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5274</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5900</span> </span>
<span id="cb32-6">  The Free Agents     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.6111</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">59</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5385</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5567</span> </span>
<span id="cb32-7">             &gt;30%      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5333</span>     -<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5464</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5432</span> </span>
<span id="cb32-8">       Above ParR      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5333</span>    -<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5364</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5357</span> </span>
<span id="cb32-9">        The Big <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.6111</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.4905</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5206</span> </span>
<span id="cb32-10">     Net Positive      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5000</span>    -<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.4956</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.4967</span> </span>
<span id="cb32-11">         Bob Ross      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.4444</span>    -<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">23</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.4968</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.4837</span> </span>
<span id="cb32-12">           Motley      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5333</span>     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">17</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.4603</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.4786</span> </span>
<span id="cb32-13">       The A-Team      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1111</span>    -<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">83</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5855</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.4669</span> </span>
<span id="cb32-14">      Team Avatar      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5000</span>    -<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">24</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.4242</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.4431</span> </span>
<span id="cb32-15">            Kangz      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3889</span>    -<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.4501</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.4348</span> </span>
<span id="cb32-16">             Tsaf      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">14</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.2222</span>    -<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">92</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.4563</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3978</span> </span>
<span id="cb32-17">     CityOfThrees      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>.     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1667</span>    -<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">74</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.4432</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3741</span> </span></code></pre></div></div>
<p>The top 3 ranked teams were also seeded as teams 1-3 in the playoffs based only on game record and set differential (not set record, RPI, etc.). &gt;30% was seeded at #11 because they forfeited twice, which I didn’t attempt to account for. Team Avatar was the #6 seed because they benefited from forfeits that aren’t reflected in the rankings. Apart from the effects of forfeits, the RPI rankings for each team were generally within 1 or 2 places from the playoff seeding. I was surprised that only six regular season games produced playoff seedings that so reasonably reflected the teams’ rankings.</p>



 ]]></description>
  <category>Scheme</category>
  <category>Python</category>
  <category>Elixir</category>
  <category>dataframe</category>
  <category>Polars</category>
  <category>Explorer</category>
  <guid>https://www.travishinkelman.com/posts/rpi.html</guid>
  <pubDate>Mon, 02 Sep 2024 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Proof of Kaprekar’s constant in Scheme, Python, and Elixir</title>
  <link>https://www.travishinkelman.com/posts/kaprekar.html</link>
  <description><![CDATA[ 




<p>I thoroughly enjoyed this <a href="https://demian.ferrei.ro/blog/programmer-vs-mathematician">delightful post</a> on <a href="https://en.wikipedia.org/wiki/6174">Kaprekar’s constant</a>, which was new to me. Similar to the post author, I also like to use programming to understand mathematical concepts. I thought it would be a fun exercise to translate the example Ruby code to my favorite language, Scheme, and two other languages that I’m learning, Python and Elixir.</p>
<p>Kaprekar’s routine is an iterative process that starts with a 4-digit number and (usually) ends at 6174. Here is an example starting with 55:</p>
<pre><code>5500 - 0055 = 5445
5544 - 4455 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174
7641 - 1467 = 6174</code></pre>
<p>In Scheme and Python, the approach is to convert the number to a string, left pad with zeros (if necessary), split into a list of characters (Scheme) or strings (Python), sort the list, convert back to string, and then convert to number.</p>
<p>Python provides a function for left padding a string.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>.rjust(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"55"</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"0"</span>)</span>
<span id="cb2-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">'0055'</span></span></code></pre></div></div>
<p>In Scheme, we use <code>format</code> to write a left pad procedure. Format directives are written as strings that start with <code>~</code>. The <code>~a</code> directive prints the object as with <code>display</code>. Commas separate four optional arguments: <code>mincol</code>, <code>colinc</code>, <code>minpad</code>, <code>padchars</code>. The width of the output is specified with <code>mincol</code>. We use the default values for <code>colinc</code> and <code>minpad</code>, which is why we need <code>,,,</code>. The <code>padchars</code> are preceded by <code>'</code>. The <code>@</code> indicates that the padding is placed on the left.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb3-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">string-pad-left </span>x mincol padchars)</span>
<span id="cb3-2">  (format</span>
<span id="cb3-3">   (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string-append</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"~"</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">number-&gt;string</span> mincol) <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">",,,'"</span> padchars <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"@a"</span>)</span>
<span id="cb3-4">   x))</span>
<span id="cb3-5"></span>
<span id="cb3-6"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (string-pad-left <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"55"</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"0"</span>)</span>
<span id="cb3-7"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"0055"</span></span></code></pre></div></div>
<p>In Elixir, we are only working with integers; no conversion to characters or strings. We “pad” the list instead of the string. <code>++</code> concatenates two lists.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb4-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> pad_left<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>lst, width, value<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb4-2">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> length<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>lst<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> width <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb4-3">    <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">List</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>duplicate<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>value, width <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> length<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>lst<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">))</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span> lst</span>
<span id="cb4-4">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span></span>
<span id="cb4-5">    lst</span>
<span id="cb4-6">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb4-7"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb4-8"></span>
<span id="cb4-9"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> pad_left<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-10"><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span></span></code></pre></div></div>
<p>In Scheme and Python, we create functions that convert a number to a list of characters (Scheme) or strings (Python) and back again. In both cases, we build the 4-digit left padding into the conversion to lists and, thus, <code>number-&gt;list</code> and <code>num2list</code> are not as general as their names imply. <code>num2list</code> takes advantage of strings being iterable and uses a list comprehension to pull apart the newly created string (from <code>n</code>) into a list. The <code>join</code> syntax is a bit weird to me as a Python novice. Elixir provides <code>digits</code> and <code>undigits</code> that provide the functionality we need without working with strings.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb5-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Scheme</span></span>
<span id="cb5-2">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">number-&gt;list </span>n)</span>
<span id="cb5-3">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string-&gt;list</span> (string-pad-left (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">number-&gt;string</span> n) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"0"</span>)))</span>
<span id="cb5-4"></span>
<span id="cb5-5">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">list-&gt;number </span>lst)</span>
<span id="cb5-6">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string-&gt;number</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">list-&gt;string</span> lst)))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb6-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Python</span></span>
<span id="cb6-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> num2list(n):</span>
<span id="cb6-3">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> [x <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> x <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>.rjust(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>(n), <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"0"</span>)]</span>
<span id="cb6-4"></span>
<span id="cb6-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> list2num(lst):</span>
<span id="cb6-6">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span>.join(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>(x) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> x <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> lst))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb7-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Elixir</span></span>
<span id="cb7-2"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Integer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>digits<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1234</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb7-3"><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb7-4"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Integer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>undigits<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb7-5"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1234</span></span></code></pre></div></div>
<p>For repdigits (e.g., 1111, 2222), the result of the Kaprekar routine is 0, not 6174. Although not strictly necessary, I will follow the original post and create functions for detecting repdigits. The Python and Elixir functions use the same logic but different approachs, i.e., strings and sets in Python and unique list values in Elixir. The Scheme version iterates over all characters (after converting the number to list of characters) to check if each character is the same as the first. Scheme and Elixir both have the convention of using <code>?</code> in boolean functions, which I think pops out nicely when reading code (arguably better than the <code>is_</code> prefix).</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb8-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Scheme</span></span>
<span id="cb8-2">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">repdigit? </span>n)</span>
<span id="cb8-3">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>lst (number-&gt;list n)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb8-4">    (for-all (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (x) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">char=?</span> x (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> lst))) lst)))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb9-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Python</span></span>
<span id="cb9-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> is_repdigits(n):</span>
<span id="cb9-3">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">set</span>(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>(n))) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb10-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Elixir</span></span>
<span id="cb10-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> repdigits?<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>n<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb10-3">  length<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Enum</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>uniq<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Integer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>digits<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>n<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)))</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span>
<span id="cb10-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>As pointed out in the original post, for the Kaprekar routine, we are only working with 4-digit numbers, which allows for a simpler approach using modulo.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb11-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Scheme</span></span>
<span id="cb11-2">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">repdigit? </span>n)</span>
<span id="cb11-3">  (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">modulo</span> n <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1111</span>) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb12-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Python</span></span>
<span id="cb12-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> is_repdigits(n):</span>
<span id="cb12-3">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1111</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span></span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb13-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Elixir</span></span>
<span id="cb13-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> repdigits?<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>n<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb13-3">  <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Integer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>mod<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>n, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1111</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span></span>
<span id="cb13-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>Our functions for sorting digits allow for specifying sort direction (via <code>pred</code>, <code>rev</code>, and <code>sorter</code>). As a reminder, padding is included in <code>number-&gt;list</code> and <code>num2list</code>, but first appears for Elixir in <code>sort_digits</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb14-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Scheme</span></span>
<span id="cb14-2">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sort-digits </span>n pred)</span>
<span id="cb14-3">  (list-&gt;number (sort pred (number-&gt;list n))))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb15-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Python</span></span>
<span id="cb15-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> sort_digits(n, rev):</span>
<span id="cb15-3">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> list2num(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sorted</span>(num2list(n), reverse <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> rev))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb16-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Elixir</span></span>
<span id="cb16-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> sort_digits<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>n, sorter<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb16-3">  <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Integer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>undigits<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Enum</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>sort<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>pad_left<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Integer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>digits<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>n<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span>, sorter<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">))</span></span>
<span id="cb16-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>We use recursion to implement the Kaprekar routine, which is similar in all three languages. None of these functions have guards against numbers bigger than four digits so you can end up in an infinte loop.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb17-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Scheme</span></span>
<span id="cb17-2">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kap </span>n)</span>
<span id="cb17-3">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>d (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> (sort-digits n <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">char&gt;?</span>) (sort-digits n <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">char&lt;?</span>))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb17-4">    (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> n d) n (kap d))))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb18-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Python</span></span>
<span id="cb18-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> kap(n):</span>
<span id="cb18-3">    d <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sort_digits(n, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> sort_digits(n, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>)</span>
<span id="cb18-4">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> d):</span>
<span id="cb18-5">        result <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> n</span>
<span id="cb18-6">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb18-7">        result <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> kap(d)</span>
<span id="cb18-8">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> result</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb19-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Elixir</span></span>
<span id="cb19-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> kap<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>n<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb19-3">  d <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sort_digits<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>n, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:desc</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> sort_digits<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>n, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:asc</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb19-4">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> d, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">do:</span> n, <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>: kap<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>d<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb19-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>The last step is to iterate through all integers from 0 to 9999 and raise an exception if the routine doesn’t result in 6174 (or is a repdigit). These blocks of code all execute silently and provide proof of Kaprekar’s constant. Note that <code>repdigits?(n)</code> can be replaced by <code>kap(n) == 0</code> (or similar for the other languages).</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb20-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Scheme</span></span>
<span id="cb20-2">(<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for-each</span></span>
<span id="cb20-3"> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (n)</span>
<span id="cb20-4">   (unless (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">or</span> (repdigit? n) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (kap n) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6174</span>))</span>
<span id="cb20-5">     (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">assertion-violation</span></span>
<span id="cb20-6">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"kap loop"</span></span>
<span id="cb20-7">      (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string-append</span></span>
<span id="cb20-8">       (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">number-&gt;string</span> n)</span>
<span id="cb20-9">       <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">" is not a repdigit nor does it converge to 674"</span>))))</span>
<span id="cb20-10">  (iota <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10000</span>))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb21-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Python</span></span>
<span id="cb21-2"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> n <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10000</span>):</span>
<span id="cb21-3">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> (is_repdigits(n) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">or</span> kap(n) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6174</span>):</span>
<span id="cb21-4">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">raise</span> <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">Exception</span>(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>(n) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">" is not a repdigit nor does it converge to 674"</span>)</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb22" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb22-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Elixir</span></span>
<span id="cb22-2"><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Enum</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>each<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb22-3">  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">..</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9999</span>,</span>
<span id="cb22-4">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">fn</span> n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span></span>
<span id="cb22-5">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">unless</span> repdigits?<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>n<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">or</span> kap<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>n<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6174</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb22-6">      <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">raise</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">#{</span>n<span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> is not a repdigit nor does it converge to 674"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb22-7">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb22-8">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb22-9"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div></div>



 ]]></description>
  <category>Scheme</category>
  <category>Python</category>
  <category>Elixir</category>
  <guid>https://www.travishinkelman.com/posts/kaprekar.html</guid>
  <pubDate>Thu, 30 May 2024 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Dataframe manipulation in Scheme</title>
  <link>https://www.travishinkelman.com/posts/dataframe-manipulation.html</link>
  <description><![CDATA[ 




<p>This is yet another post where I try out my <a href="https://github.com/hinkelman/dataframe/"><code>dataframe</code></a> library for Scheme (R6RS) on examples found in blog posts. This blog <a href="https://statsandr.com/blog/introduction-to-data-manipulation-in-r-with-dplyr/">post</a> demonstrates data manipulation with <a href="https://dplyr.tidyverse.org/"><code>dplyr</code></a> (R). I provide only the Scheme code and some commentary. You will have to click through to the original post to see how it compares to R.</p>
<section id="library-and-data" class="level3">
<h3 class="anchored" data-anchor-id="library-and-data">Library and Data</h3>
<p>First, we import the <code>dataframe</code> library and the <code>shuffle</code> procedure from <a href="https://github.com/hinkelman/dataframe/"><code>chez-stats</code></a>. The original post uses the <a href="https://github.com/allisonhorst/palmerpenguins">Palmer Penguins</a> dataset, which I wrote to a <a href="../data/penguins.csv">csv file</a> from R. We read the data from file and select only the columns used in this post. <code>dataframe-display</code> is similar to <code>head</code> in R and <code>dataframe-glimpse</code> is similar to <code>str</code>, but <code>dataframe</code> currently provides no functionality comparable to <code>summary</code> in R.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb1-1">(import (dataframe)</span>
<span id="cb1-2">        (only (chez-stats)</span>
<span id="cb1-3">              shuffle))</span>
<span id="cb1-4"></span>
<span id="cb1-5">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> dat</span></span>
<span id="cb1-6">  (-&gt; (csv-&gt;dataframe <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"penguins.csv"</span>)</span>
<span id="cb1-7">      (dataframe-select* species body_mass_g sex year)))</span>
<span id="cb1-8"></span>
<span id="cb1-9">(dataframe-display dat)</span>
<span id="cb1-10"></span>
<span id="cb1-11"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">344</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> cols</span>
<span id="cb1-12">  species  body_mass_g     sex    year </span>
<span id="cb1-13">    &lt;str&gt;        &lt;num&gt;   &lt;str&gt;   &lt;num&gt; </span>
<span id="cb1-14">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3750</span>    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb1-15">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3800</span>  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb1-16">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3250</span>  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb1-17">   Adelie           na      na   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb1-18">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3450</span>  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb1-19">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3650</span>    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb1-20">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3625</span>  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb1-21">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4675</span>    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb1-22">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3475</span>      na   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb1-23">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4250</span>      na   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb1-24"></span>
<span id="cb1-25">(dataframe-glimpse dat)</span>
<span id="cb1-26"></span>
<span id="cb1-27"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">344</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> cols</span>
<span id="cb1-28"> species      &lt;str&gt;   Adelie, Adelie, Adelie, Adelie, Adelie, Adelie, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span>       </span>
<span id="cb1-29"> body_mass_g  &lt;num&gt;   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3750</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3800</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3250</span>, na, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3450</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3650</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3625</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4675</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3475</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span>   </span>
<span id="cb1-30"> sex          &lt;str&gt;   male, female, female, na, female, male, female, male, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> </span>
<span id="cb1-31"> year         &lt;num&gt;   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> </span></code></pre></div></div>
</section>
<section id="filter-observations" class="level3">
<h3 class="anchored" data-anchor-id="filter-observations">Filter Observations</h3>
<p>The <code>dataframe</code> library includes some handling of missing values, represented as <code>'na</code>, but nothing currently that will automatically drop <code>'na</code> values while filtering as in <code>dplyr::filter</code>. A couple of options for handling <code>'na</code> are presented in the code below. In the original blog post, they built up to a compound filter with pipe operators, but here I will just cut to the chase and show the final version.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb2-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; this version is more readable, but requires two passes through the dataframe</span></span>
<span id="cb2-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;;  i.e., first with dataframe-remove-na and then with dataframe-filter</span></span>
<span id="cb2-3">(-&gt; dat</span>
<span id="cb2-4">    (dataframe-remove-na 'body_mass_g 'sex)</span>
<span id="cb2-5">    (dataframe-filter*</span>
<span id="cb2-6">     (body_mass_g sex)</span>
<span id="cb2-7">     (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> body_mass_g <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4000</span>)</span>
<span id="cb2-8">          (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> sex <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"female"</span>)))</span>
<span id="cb2-9">    (dataframe-display))</span>
<span id="cb2-10"></span>
<span id="cb2-11"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; this version is more awkward to read (and write)</span></span>
<span id="cb2-12"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;;  but does all the filtering in one pass</span></span>
<span id="cb2-13">(-&gt; dat</span>
<span id="cb2-14">    (dataframe-filter*</span>
<span id="cb2-15">     (body_mass_g sex)</span>
<span id="cb2-16">     (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> (na? body_mass_g))</span>
<span id="cb2-17">               (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> body_mass_g <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4000</span>))</span>
<span id="cb2-18">          (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> (na? sex))</span>
<span id="cb2-19">               (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> sex <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"female"</span>))))</span>
<span id="cb2-20">    (dataframe-display))</span>
<span id="cb2-21"></span>
<span id="cb2-22"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">58</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> cols</span>
<span id="cb2-23">  species  body_mass_g     sex    year </span>
<span id="cb2-24">    &lt;str&gt;        &lt;num&gt;   &lt;str&gt;   &lt;num&gt; </span>
<span id="cb2-25">   Gentoo        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4500</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb2-26">   Gentoo        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4450</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb2-27">   Gentoo        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4550</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb2-28">   Gentoo        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4800</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb2-29">   Gentoo        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4400</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb2-30">   Gentoo        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4650</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb2-31">   Gentoo        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4650</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb2-32">   Gentoo        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4200</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb2-33">   Gentoo        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4150</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb2-34">   Gentoo        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4800</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span></code></pre></div></div>
</section>
<section id="extract-observations" class="level3">
<h3 class="anchored" data-anchor-id="extract-observations">Extract Observations</h3>
<p>The <code>dataframe</code> library doesn’t include a slice function, but we can accomplish similar functionality with other <code>dataframe</code> procedures. You can slice by row indices using <code>dataframe-ref</code>. <code>dataframe-head</code> is similar to <code>slice_head</code>. <code>dataframe-tail</code> works similarly to <code>list-tail</code> in Scheme but differently than <code>slice_tail</code> in <code>dplyr</code> and requires jumping through some extra hoops to replicate <code>slice_tail</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb3-1">(dataframe-display (dataframe-ref dat '(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">36</span>)))</span>
<span id="cb3-2"></span>
<span id="cb3-3"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> cols</span>
<span id="cb3-4">  species  body_mass_g     sex    year </span>
<span id="cb3-5">    &lt;str&gt;        &lt;num&gt;   &lt;str&gt;   &lt;num&gt; </span>
<span id="cb3-6">   Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3800</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb3-7">   Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3450</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb3-8">   Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3950</span>.    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb3-9"></span>
<span id="cb3-10">(dataframe-display (dataframe-head dat <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>))</span>
<span id="cb3-11"></span>
<span id="cb3-12"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> cols</span>
<span id="cb3-13">  species  body_mass_g     sex    year </span>
<span id="cb3-14">    &lt;str&gt;        &lt;num&gt;   &lt;str&gt;   &lt;num&gt; </span>
<span id="cb3-15">   Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3750</span>.    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb3-16">   Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3800</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb3-17">   Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3250</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb3-18"></span>
<span id="cb3-19">(dataframe-display (dataframe-tail dat (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> (dataframe-dim dat)) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)))</span>
<span id="cb3-20"></span>
<span id="cb3-21"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> cols</span>
<span id="cb3-22">    species  body_mass_g     sex    year </span>
<span id="cb3-23">      &lt;str&gt;        &lt;num&gt;   &lt;str&gt;   &lt;num&gt; </span>
<span id="cb3-24">  Chinstrap        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3775</span>.    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2009</span>. </span>
<span id="cb3-25">  Chinstrap        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4100</span>.    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2009</span>. </span>
<span id="cb3-26">  Chinstrap        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3775</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2009</span>. </span></code></pre></div></div>
<p>It takes considerably more code to replicate <code>slice_min</code> and <code>slice_max</code> from <code>dplyr</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb4-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; equivalent of `slice_min` example in original post</span></span>
<span id="cb4-2">(-&gt; (dataframe-filter*</span>
<span id="cb4-3">     dat</span>
<span id="cb4-4">     (body_mass_g)</span>
<span id="cb4-5">     (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> (na? body_mass_g))</span>
<span id="cb4-6">          (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> body_mass_g (quantile (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> dat 'body_mass_g) <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.25</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>))))</span>
<span id="cb4-7">    (dataframe-sort* (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> body_mass_g))</span>
<span id="cb4-8">    (dataframe-display))</span>
<span id="cb4-9"></span>
<span id="cb4-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; previous version only works with filter as the first step in the pipe</span></span>
<span id="cb4-11"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;;  this version works with filter step anywhere in the pipe</span></span>
<span id="cb4-12">(-&gt; dat</span>
<span id="cb4-13">    (dataframe-remove-na 'body_mass_g)</span>
<span id="cb4-14">    (-&gt;&gt;</span>
<span id="cb4-15">     ((<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (dfx)</span>
<span id="cb4-16">        (dataframe-filter*</span>
<span id="cb4-17">         dfx</span>
<span id="cb4-18">         (body_mass_g)</span>
<span id="cb4-19">         (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> body_mass_g (quantile (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> dfx 'body_mass_g) <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.25</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>))))))</span>
<span id="cb4-20">    (dataframe-sort* (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> body_mass_g))</span>
<span id="cb4-21">    (dataframe-display))</span>
<span id="cb4-22"></span>
<span id="cb4-23"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">89</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> cols</span>
<span id="cb4-24">    species  body_mass_g     sex    year </span>
<span id="cb4-25">      &lt;str&gt;        &lt;num&gt;   &lt;str&gt;   &lt;num&gt; </span>
<span id="cb4-26">  Chinstrap        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2700</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2008</span>. </span>
<span id="cb4-27">     Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2850</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2008</span>. </span>
<span id="cb4-28">     Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2850</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2008</span>. </span>
<span id="cb4-29">     Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2900</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2008</span>. </span>
<span id="cb4-30">     Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2900</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2008</span>. </span>
<span id="cb4-31">     Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2900</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2009</span>. </span>
<span id="cb4-32">  Chinstrap        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2900</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb4-33">     Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2925</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2009</span>. </span>
<span id="cb4-34">     Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2975</span>.      na   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb4-35">     Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3000</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.</span>
<span id="cb4-36"></span>
<span id="cb4-37"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; equivalent of `slice_max` example in original post</span></span>
<span id="cb4-38">(-&gt; (dataframe-filter*</span>
<span id="cb4-39">     dat</span>
<span id="cb4-40">     (body_mass_g)</span>
<span id="cb4-41">     (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> (na? body_mass_g))</span>
<span id="cb4-42">          (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> body_mass_g (quantile (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> dat 'body_mass_g) <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.75</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>))))</span>
<span id="cb4-43">    (dataframe-sort* (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> body_mass_g))</span>
<span id="cb4-44">    (dataframe-display))</span>
<span id="cb4-45"></span>
<span id="cb4-46"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">90</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> cols</span>
<span id="cb4-47">    species  body_mass_g     sex    year </span>
<span id="cb4-48">      &lt;str&gt;        &lt;num&gt;   &lt;str&gt;   &lt;num&gt; </span>
<span id="cb4-49">     Gentoo        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4750</span>.    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2008</span>. </span>
<span id="cb4-50">     Gentoo        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4750</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2008</span>. </span>
<span id="cb4-51">     Gentoo        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4750</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2008</span>. </span>
<span id="cb4-52">     Gentoo        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4750</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2009</span>. </span>
<span id="cb4-53">     Gentoo        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4750</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2009</span>. </span>
<span id="cb4-54">     Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4775</span>.    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2009</span>. </span>
<span id="cb4-55">     Gentoo        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4800</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb4-56">     Gentoo        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4800</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb4-57">  Chinstrap        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4800</span>.    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2008</span>. </span>
<span id="cb4-58">     Gentoo        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4850</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2008</span>. </span></code></pre></div></div>
</section>
<section id="sample-observations" class="level3">
<h3 class="anchored" data-anchor-id="sample-observations">Sample Observations</h3>
<p>The equivalent of <code>sample_n</code> and <code>sample_frac</code> don’t currently exist in <code>dataframe</code>, but it doesn’t take much code to reproduce that functionality. Here, we lean on <code>shuffle</code> from <code>chez-stats</code> to randomly arrange the indices and then call <code>dataframe-ref</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb5-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">get-first-n </span>lst n)</span>
<span id="cb5-2">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> loop (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>lst lst<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb5-3">             <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>out '()<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb5-4">             <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>count <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb5-5">    (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">or</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null?</span> lst) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> count n))</span>
<span id="cb5-6">        (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">reverse</span> out)</span>
<span id="cb5-7">        (loop (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cdr</span> lst) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cons</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> lst) out) (add1 count)))))</span>
<span id="cb5-8"></span>
<span id="cb5-9">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sample-n </span>df n)</span>
<span id="cb5-10">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let*</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>ind1 (iota (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> (dataframe-dim df)))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb5-11">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>ind2 (get-first-n (shuffle ind1) n)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb5-12">    (dataframe-ref df ind2)))</span>
<span id="cb5-13"></span>
<span id="cb5-14">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sample-frac </span>df frac)</span>
<span id="cb5-15">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let*</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>rows (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> (dataframe-dim df))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb5-16">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>n (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">floor</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">inexact</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> rows frac)))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb5-17">    (sample-n df n)))</span>
<span id="cb5-18"></span>
<span id="cb5-19">(dataframe-display (sample-n dat <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>))</span>
<span id="cb5-20"></span>
<span id="cb5-21"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> cols</span>
<span id="cb5-22">  species  body_mass_g     sex    year </span>
<span id="cb5-23">    &lt;str&gt;        &lt;num&gt;   &lt;str&gt;   &lt;num&gt; </span>
<span id="cb5-24">   Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4250</span>.    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2009</span>. </span>
<span id="cb5-25">   Gentoo        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5250</span>.    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2009</span>. </span>
<span id="cb5-26">   Gentoo        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4600</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2008</span>. </span>
<span id="cb5-27"></span>
<span id="cb5-28"> (dataframe-display (sample-frac dat <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>/2))</span>
<span id="cb5-29"></span>
<span id="cb5-30"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">172</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> cols</span>
<span id="cb5-31">    species  body_mass_g     sex    year </span>
<span id="cb5-32">      &lt;str&gt;        &lt;num&gt;   &lt;str&gt;   &lt;num&gt; </span>
<span id="cb5-33">     Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3325</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb5-34">     Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3275</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2009</span>. </span>
<span id="cb5-35">     Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3475</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2009</span>. </span>
<span id="cb5-36">  Chinstrap        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3650</span>.    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb5-37">     Gentoo        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4550</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb5-38">  Chinstrap        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3675</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2009</span>. </span>
<span id="cb5-39">     Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4600</span>.    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb5-40">     Gentoo        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4650</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb5-41">  Chinstrap        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3325</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2009</span>. </span>
<span id="cb5-42">     Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3075</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2009</span>. </span></code></pre></div></div>
</section>
<section id="sort-observations" class="level3">
<h3 class="anchored" data-anchor-id="sort-observations">Sort Observations</h3>
<p>Sorting also requires explicitly handling missing values. <code>dataframe-sort</code> first sorts based on the expression on the left and then moves right through all other expressions (in this case, it means first sorting by body mass and then sex).</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb6-1">(-&gt; dat</span>
<span id="cb6-2">    (dataframe-remove-na 'body_mass_g 'sex)</span>
<span id="cb6-3">    (dataframe-sort* (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> body_mass_g) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string&lt;?</span> sex))</span>
<span id="cb6-4">    (dataframe-display))</span>
<span id="cb6-5"></span>
<span id="cb6-6"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">333</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> cols</span>
<span id="cb6-7">    species  body_mass_g     sex    year </span>
<span id="cb6-8">      &lt;str&gt;        &lt;num&gt;   &lt;str&gt;   &lt;num&gt; </span>
<span id="cb6-9">  Chinstrap        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2700</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2008</span>. </span>
<span id="cb6-10">     Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2850</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2008</span>. </span>
<span id="cb6-11">     Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2850</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2008</span>. </span>
<span id="cb6-12">     Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2900</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2008</span>. </span>
<span id="cb6-13">     Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2900</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2008</span>. </span>
<span id="cb6-14">     Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2900</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2009</span>. </span>
<span id="cb6-15">  Chinstrap        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2900</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb6-16">     Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2925</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2009</span>. </span>
<span id="cb6-17">     Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3000</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb6-18">     Adelie        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3000</span>.  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2009</span>. </span></code></pre></div></div>
</section>
<section id="select-variables" class="level3">
<h3 class="anchored" data-anchor-id="select-variables">Select Variables</h3>
<p><code>dplyr</code>’s <code>select</code> provides particularly rich functionality for selecting columns from a dataframe. In the <code>dataframe</code> library, you can only select or drop columns by exact column names.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb7-1">(dataframe-display (dataframe-select* dat body_mass_g year))</span>
<span id="cb7-2"></span>
<span id="cb7-3"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">344</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> cols</span>
<span id="cb7-4">  body_mass_g    year </span>
<span id="cb7-5">        &lt;num&gt;   &lt;num&gt; </span>
<span id="cb7-6">         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3750</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb7-7">         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3800</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb7-8">         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3250</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb7-9">           na   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb7-10">         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3450</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb7-11">         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3650</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb7-12">         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3625</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb7-13">         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4675</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb7-14">         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3475</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb7-15">         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4250</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb7-16"></span>
<span id="cb7-17">(dataframe-display (dataframe-drop* dat body_mass_g year))</span>
<span id="cb7-18"></span>
<span id="cb7-19"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">344</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> cols</span>
<span id="cb7-20">  species     sex </span>
<span id="cb7-21">    &lt;str&gt;   &lt;str&gt; </span>
<span id="cb7-22">   Adelie    male </span>
<span id="cb7-23">   Adelie  female </span>
<span id="cb7-24">   Adelie  female </span>
<span id="cb7-25">   Adelie      na </span>
<span id="cb7-26">   Adelie  female </span>
<span id="cb7-27">   Adelie    male </span>
<span id="cb7-28">   Adelie  female </span>
<span id="cb7-29">   Adelie    male </span>
<span id="cb7-30">   Adelie      na </span>
<span id="cb7-31">   Adelie      na </span>
<span id="cb7-32"></span>
<span id="cb7-33"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; re-arrange column order</span></span>
<span id="cb7-34">(dataframe-display (dataframe-select* dat sex species body_mass_g year))</span>
<span id="cb7-35"></span>
<span id="cb7-36"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">344</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> cols</span>
<span id="cb7-37">     sex  species  body_mass_g    year </span>
<span id="cb7-38">   &lt;str&gt;    &lt;str&gt;        &lt;num&gt;   &lt;num&gt; </span>
<span id="cb7-39">    male   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3750</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb7-40">  female   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3800</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb7-41">  female   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3250</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb7-42">      na   Adelie           na   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb7-43">  female   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3450</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb7-44">    male   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3650</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb7-45">  female   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3625</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb7-46">    male   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4675</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb7-47">      na   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3475</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb7-48">      na   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4250</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span></code></pre></div></div>
</section>
<section id="rename-variables" class="level3">
<h3 class="anchored" data-anchor-id="rename-variables">Rename Variables</h3>
<p>Renaming columns works similarly to <code>dplyr</code>, but the order is <code>(old-name new-name)</code> not <code>new_name = old_name</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb8-1">(dataframe-display</span>
<span id="cb8-2"> (dataframe-rename* dat (body_mass_g body_mass) (year study_year)))</span>
<span id="cb8-3"></span>
<span id="cb8-4"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">344</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> cols</span>
<span id="cb8-5">  species  body_mass     sex  study_year </span>
<span id="cb8-6">    &lt;str&gt;      &lt;num&gt;   &lt;str&gt;       &lt;num&gt; </span>
<span id="cb8-7">   Adelie       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3750</span>    male       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb8-8">   Adelie       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3800</span>  female       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb8-9">   Adelie       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3250</span>  female       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb8-10">   Adelie         na      na       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb8-11">   Adelie       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3450</span>  female       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb8-12">   Adelie       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3650</span>    male       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb8-13">   Adelie       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3625</span>  female       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb8-14">   Adelie       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4675</span>    male       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb8-15">   Adelie       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3475</span>      na       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb8-16">   Adelie       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4250</span>      na       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span></code></pre></div></div>
</section>
<section id="create-or-modify-variables" class="level1">
<h1>Create or Modify Variables</h1>
<p>Again, we have to explicitly handle <code>'na</code> values because <code>/</code> and <code>&lt;</code> don’t handle symbols and <code>dataframe</code> doesn’t provide alternatives. In the second example, we can create a new column that is not based on any columns in the dataframe by not specifying any columns <code>()</code> to use in the expression.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb9-1">(dataframe-display</span>
<span id="cb9-2"> (dataframe-modify*</span>
<span id="cb9-3">  dat</span>
<span id="cb9-4">  (body_mass_kg</span>
<span id="cb9-5">   (body_mass_g)</span>
<span id="cb9-6">   (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (na? body_mass_g) 'na (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">inexact</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> body_mass_g <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000</span>))))))</span>
<span id="cb9-7"></span>
<span id="cb9-8"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">344</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> cols</span>
<span id="cb9-9">  species  body_mass_g     sex    year  body_mass_kg </span>
<span id="cb9-10">    &lt;str&gt;        &lt;num&gt;   &lt;str&gt;   &lt;num&gt;         &lt;num&gt; </span>
<span id="cb9-11">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3750</span>    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.          <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.75</span> </span>
<span id="cb9-12">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3800</span>  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.           <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.8</span> </span>
<span id="cb9-13">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3250</span>  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.          <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.25</span> </span>
<span id="cb9-14">   Adelie           na      na   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.            na </span>
<span id="cb9-15">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3450</span>  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.          <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.45</span> </span>
<span id="cb9-16">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3650</span>    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.          <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.65</span> </span>
<span id="cb9-17">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3625</span>  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.         <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.625</span> </span>
<span id="cb9-18">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4675</span>    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.         <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.675</span> </span>
<span id="cb9-19">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3475</span>      na   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.         <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.475</span> </span>
<span id="cb9-20">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4250</span>      na   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.          <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.25</span> </span>
<span id="cb9-21"></span>
<span id="cb9-22">(dataframe-display</span>
<span id="cb9-23"> (dataframe-modify*</span>
<span id="cb9-24">  dat</span>
<span id="cb9-25">  (id () (iota (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> (dataframe-dim dat))))))</span>
<span id="cb9-26"></span>
<span id="cb9-27"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">344</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> cols</span>
<span id="cb9-28">  species  body_mass_g     sex    year      id </span>
<span id="cb9-29">    &lt;str&gt;        &lt;num&gt;   &lt;str&gt;   &lt;num&gt;   &lt;num&gt; </span>
<span id="cb9-30">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3750</span>    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>. </span>
<span id="cb9-31">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3800</span>  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>. </span>
<span id="cb9-32">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3250</span>  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>. </span>
<span id="cb9-33">   Adelie           na      na   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>. </span>
<span id="cb9-34">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3450</span>  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>. </span>
<span id="cb9-35">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3650</span>    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>. </span>
<span id="cb9-36">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3625</span>  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>. </span>
<span id="cb9-37">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4675</span>    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>. </span>
<span id="cb9-38">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3475</span>      na   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>. </span>
<span id="cb9-39">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4250</span>      na   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>. </span>
<span id="cb9-40"></span>
<span id="cb9-41">(dataframe-display</span>
<span id="cb9-42"> (dataframe-modify*</span>
<span id="cb9-43">  dat</span>
<span id="cb9-44">  (body_mass_cat</span>
<span id="cb9-45">   (body_mass_g)</span>
<span id="cb9-46">   (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (na? body_mass_g)</span>
<span id="cb9-47">       'na</span>
<span id="cb9-48">       (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> body_mass_g <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4000</span>) <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"High"</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Low"</span>)))))</span>
<span id="cb9-49"></span>
<span id="cb9-50"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">344</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> cols</span>
<span id="cb9-51">  species  body_mass_g     sex    year  body_mass_cat </span>
<span id="cb9-52">    &lt;str&gt;        &lt;num&gt;   &lt;str&gt;   &lt;num&gt;          &lt;str&gt; </span>
<span id="cb9-53">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3750</span>    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.            Low </span>
<span id="cb9-54">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3800</span>  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.            Low </span>
<span id="cb9-55">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3250</span>  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.            Low </span>
<span id="cb9-56">   Adelie           na      na   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.             na </span>
<span id="cb9-57">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3450</span>  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.            Low </span>
<span id="cb9-58">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3650</span>    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.            Low </span>
<span id="cb9-59">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3625</span>  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.            Low </span>
<span id="cb9-60">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4675</span>    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.           High </span>
<span id="cb9-61">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3475</span>      na   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.            Low </span>
<span id="cb9-62">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4250</span>      na   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.           High </span>
<span id="cb9-63"></span>
<span id="cb9-64">(dataframe-display</span>
<span id="cb9-65"> (dataframe-modify*</span>
<span id="cb9-66">  dat</span>
<span id="cb9-67">  (body_mass_cat</span>
<span id="cb9-68">   (body_mass_g)</span>
<span id="cb9-69">   (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cond</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(na? body_mass_g) 'na<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb9-70">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> body_mass_g <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3500</span>) <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Low"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb9-71">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> body_mass_g <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4750</span>) <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"High"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb9-72">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Medium"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>))))</span>
<span id="cb9-73"></span>
<span id="cb9-74"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">344</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> cols</span>
<span id="cb9-75">  species  body_mass_g     sex    year  body_mass_cat </span>
<span id="cb9-76">    &lt;str&gt;        &lt;num&gt;   &lt;str&gt;   &lt;num&gt;          &lt;str&gt; </span>
<span id="cb9-77">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3750</span>    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.         Medium </span>
<span id="cb9-78">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3800</span>  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.         Medium </span>
<span id="cb9-79">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3250</span>  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.            Low </span>
<span id="cb9-80">   Adelie           na      na   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.             na </span>
<span id="cb9-81">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3450</span>  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.            Low </span>
<span id="cb9-82">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3650</span>    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.         Medium </span>
<span id="cb9-83">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3625</span>  female   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.         Medium </span>
<span id="cb9-84">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4675</span>    male   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.         Medium </span>
<span id="cb9-85">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3475</span>      na   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.            Low </span>
<span id="cb9-86">   Adelie         <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4250</span>      na   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.         Medium </span></code></pre></div></div>
<section id="identify-distinct-values" class="level3">
<h3 class="anchored" data-anchor-id="identify-distinct-values">Identify Distinct Values</h3>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb10-1">(-&gt; dat</span>
<span id="cb10-2">    (dataframe-select* species)</span>
<span id="cb10-3">    (dataframe-unique)</span>
<span id="cb10-4">    (dataframe-display))</span>
<span id="cb10-5"></span>
<span id="cb10-6"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> cols</span>
<span id="cb10-7">    species </span>
<span id="cb10-8">      &lt;str&gt; </span>
<span id="cb10-9">     Adelie </span>
<span id="cb10-10">     Gentoo </span>
<span id="cb10-11">  Chinstrap </span>
<span id="cb10-12"></span>
<span id="cb10-13">(-&gt; dat</span>
<span id="cb10-14">    (dataframe-select* species year)</span>
<span id="cb10-15">    (dataframe-unique)</span>
<span id="cb10-16">    (dataframe-display))</span>
<span id="cb10-17"></span>
<span id="cb10-18"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> cols</span>
<span id="cb10-19">    species    year </span>
<span id="cb10-20">      &lt;str&gt;   &lt;num&gt; </span>
<span id="cb10-21">     Adelie   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb10-22">     Adelie   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2008</span>. </span>
<span id="cb10-23">     Adelie   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2009</span>. </span>
<span id="cb10-24">     Gentoo   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb10-25">     Gentoo   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2008</span>. </span>
<span id="cb10-26">     Gentoo   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2009</span>. </span>
<span id="cb10-27">  Chinstrap   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>. </span>
<span id="cb10-28">  Chinstrap   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2008</span>. </span>
<span id="cb10-29">  Chinstrap   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2009</span>. </span></code></pre></div></div>
</section>
<section id="aggregate-observations" class="level3">
<h3 class="anchored" data-anchor-id="aggregate-observations">Aggregate Observations</h3>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb11-1">(dataframe-display</span>
<span id="cb11-2"> (dataframe-aggregate*</span>
<span id="cb11-3">  dat</span>
<span id="cb11-4">  (species sex)</span>
<span id="cb11-5">  (mean (body_mass_g) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">inexact</span> (mean body_mass_g)))</span>
<span id="cb11-6">  (sd (body_mass_g) (standard-deviation body_mass_g))))</span>
<span id="cb11-7"></span>
<span id="cb11-8"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> cols</span>
<span id="cb11-9">    species     sex       mean        sd </span>
<span id="cb11-10">      &lt;str&gt;   &lt;str&gt;      &lt;num&gt;     &lt;num&gt; </span>
<span id="cb11-11">     Adelie    male  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4043.4932</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">346.8116</span> </span>
<span id="cb11-12">     Adelie  female  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3368.8356</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">269.3801</span> </span>
<span id="cb11-13">     Adelie      na  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3540.0000</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">477.1661</span> </span>
<span id="cb11-14">     Gentoo  female  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4679.7414</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">281.5783</span> </span>
<span id="cb11-15">     Gentoo    male  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">5484.8361</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">313.1586</span> </span>
<span id="cb11-16">     Gentoo      na  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4587.5000</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">338.1937</span> </span>
<span id="cb11-17">  Chinstrap  female  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3527.2059</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">285.3339</span> </span>
<span id="cb11-18">  Chinstrap    male  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3938.9706</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">362.1376</span> </span>
<span id="cb11-19"></span>
<span id="cb11-20">(dataframe-display</span>
<span id="cb11-21"> (dataframe-aggregate*</span>
<span id="cb11-22">  dat</span>
<span id="cb11-23">  (species)</span>
<span id="cb11-24">  (n_obs (species) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">length</span> species))))</span>
<span id="cb11-25"></span>
<span id="cb11-26"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> cols</span>
<span id="cb11-27">    species   n_obs </span>
<span id="cb11-28">      &lt;str&gt;   &lt;num&gt; </span>
<span id="cb11-29">     Adelie    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">152</span>. </span>
<span id="cb11-30">     Gentoo    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">124</span>. </span>
<span id="cb11-31">  Chinstrap     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">68</span>. </span></code></pre></div></div>


</section>
</section>

 ]]></description>
  <category>Scheme</category>
  <category>dataframe</category>
  <category>R</category>
  <category>dplyr</category>
  <guid>https://www.travishinkelman.com/posts/dataframe-manipulation.html</guid>
  <pubDate>Mon, 22 Apr 2024 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Comparing dataframe operations in Scheme, Python, and R</title>
  <link>https://www.travishinkelman.com/posts/clunky-pandas.html</link>
  <description><![CDATA[ 




<p>I recently came across <a href="https://www.sumsar.net/blog/pandas-feels-clunky-when-coming-from-r/">this blog post</a> that calls <a href="https://pandas.pydata.org/"><code>pandas</code></a> (Python) “clunky” compared to the “silky smooth” <a href="https://dplyr.tidyverse.org/"><code>dplyr</code></a> (R). No objections from me. <code>dplyr</code> is my favorite R package. I thought it would fun to compare the relative clunkiness of my <a href="https://github.com/hinkelman/dataframe/"><code>dataframe</code></a> library for Scheme (R6RS) to <code>pandas</code> and <code>dplyr</code>. I will include the R and Python code here to save some clicking back and forth, but will mostly be commenting on the Scheme code.</p>
<section id="reading-in-the-data" class="level2">
<h2 class="anchored" data-anchor-id="reading-in-the-data">Reading in the data</h2>
<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;"># R </span></span>
<span id="cb1-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(dplyr)</span>
<span id="cb1-3">purchases <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">read.csv</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"purchases.csv"</span>)</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Python</span></span>
<span id="cb2-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> pandas <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> pd</span>
<span id="cb2-3">purchases <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.read_csv(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"purchases.csv"</span>)</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb3-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Scheme</span></span>
<span id="cb3-2">(import (dataframe))</span>
<span id="cb3-3">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> purchases </span>(csv-&gt;dataframe <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"purchases.csv"</span>))</span></code></pre></div></div>
</section>
<section id="how-much-do-we-sell..-lets-take-the-total-sum" class="level2">
<h2 class="anchored" data-anchor-id="how-much-do-we-sell..-lets-take-the-total-sum">“How much do we sell..? Let’s take the total sum!”</h2>
<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="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># R </span></span>
<span id="cb4-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sum</span>(purchases<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>amount)</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb5-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Python</span></span>
<span id="cb5-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>(purchases[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"amount"</span>])</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb6-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Scheme</span></span>
<span id="cb6-2">(sum (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> purchases 'amount))</span></code></pre></div></div>
</section>
<section id="ah-they-wanted-it-by-country" class="level2">
<h2 class="anchored" data-anchor-id="ah-they-wanted-it-by-country">“Ah, they wanted it by country…”</h2>
<p><code>dataframe-aggregate*</code> is a macro to slightly reduce the verbosity of the Scheme code, but it still falls short of the brevity and readability of the <code>dplyr</code> code.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb7-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># R </span></span>
<span id="cb7-2">purchases <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(country) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarize</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">total =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sum</span>(amount))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb8-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Python</span></span>
<span id="cb8-2">(purchases</span>
<span id="cb8-3">  .groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"country"</span>)</span>
<span id="cb8-4">  .agg(total<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"amount"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sum"</span>)) </span>
<span id="cb8-5">  .reset_index()                </span>
<span id="cb8-6">)</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb9-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Scheme</span></span>
<span id="cb9-2">(dataframe-aggregate* purchases (country) (total (amount) (sum amount)))</span></code></pre></div></div>
</section>
<section id="and-i-guess-i-should-deduct-the-discount." class="level2">
<h2 class="anchored" data-anchor-id="and-i-guess-i-should-deduct-the-discount.">“And I guess I should deduct the discount.”</h2>
<p>In Version 1, subtracting the discount is included by mapping over the columns within <code>dataframe-aggregate*</code>. In Version 2, <code>dataframe-modify*</code> handles mapping down the columns and produces more compact code. Version 2 illustrates the similarities in <code>dataframe-modify*</code> and <code>dataframe-aggregate*</code> with the primary difference being that you need to specify the grouping columns, e.g., <code>(country)</code> in <code>dataframe-aggregate*</code>, but the general form is <code>(new-name (names) (expression))</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb10-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># R </span></span>
<span id="cb10-2">purchases <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> </span>
<span id="cb10-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(country) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> </span>
<span id="cb10-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarize</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">total =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sum</span>(amount <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> discount))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb11-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Python</span></span>
<span id="cb11-2">(purchases</span>
<span id="cb11-3">  .groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"country"</span>)</span>
<span id="cb11-4">  .<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">apply</span>(<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> df: (df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"amount"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"discount"</span>]).<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>()) </span>
<span id="cb11-5">  .reset_index()</span>
<span id="cb11-6">  .rename(columns<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>{<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"total"</span>})                            </span>
<span id="cb11-7">)</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb12-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Scheme</span></span>
<span id="cb12-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Version 1</span></span>
<span id="cb12-3">(-&gt; purchases</span>
<span id="cb12-4">    (dataframe-aggregate*</span>
<span id="cb12-5">     (country)</span>
<span id="cb12-6">     (total</span>
<span id="cb12-7">      (amount discount)</span>
<span id="cb12-8">      (sum (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (amt dis) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> amt dis)) amount discount)))))</span>
<span id="cb12-9"></span>
<span id="cb12-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Version 2</span></span>
<span id="cb12-11">(-&gt; purchases</span>
<span id="cb12-12">    (dataframe-modify* (diff (amount discount) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> amount discount)))</span>
<span id="cb12-13">    (dataframe-aggregate* (country) (total (diff) (sum diff))))</span></code></pre></div></div>
</section>
<section id="oh-and-maria-asked-me-to-remove-any-outliers." class="level2">
<h2 class="anchored" data-anchor-id="oh-and-maria-asked-me-to-remove-any-outliers.">“Oh, and Maria asked me to remove any outliers.”</h2>
<p>The Scheme version only works because the filter step is the first in the pipeline, i.e., the pipe is passing the same <code>purchases</code> that is referred to in <code>($ purchases 'amount)</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb13-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># R </span></span>
<span id="cb13-2">purchases <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(amount <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(amount) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> </span>
<span id="cb13-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(country) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> </span>
<span id="cb13-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarize</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">total =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sum</span>(amount <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> discount))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb14-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Python</span></span>
<span id="cb14-2">(purchases</span>
<span id="cb14-3">  .query(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"amount &lt;= amount.median() * 10"</span>)</span>
<span id="cb14-4">  .groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"country"</span>)</span>
<span id="cb14-5">  .<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">apply</span>(<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> df: (df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"amount"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"discount"</span>]).<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>())</span>
<span id="cb14-6">  .reset_index()</span>
<span id="cb14-7">  .rename(columns<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>{<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"total"</span>})</span>
<span id="cb14-8">)</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb15-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Scheme</span></span>
<span id="cb15-2">(-&gt; purchases</span>
<span id="cb15-3">    (dataframe-filter* (amount) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> amount (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> (median (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> purchases 'amount)))))</span>
<span id="cb15-4">    (dataframe-modify* (diff (amount discount) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> amount discount)))</span>
<span id="cb15-5">    (dataframe-aggregate* (country) (total (diff) (sum diff))))</span></code></pre></div></div>
</section>
<section id="i-probably-should-use-the-median-within-each-country." class="level2">
<h2 class="anchored" data-anchor-id="i-probably-should-use-the-median-within-each-country.">“I probably should use the median within each country.”</h2>
<p>In Version 1, the outlier filtering and discount subtraction happens within the hidden split-apply-combine approach in <code>dataframe-aggregate*</code>. In Version 2, the split-apply-combine is made explicit for outlier filtering. Personally, I find Version 2 more readable, but it should be avoided for large dataframes because it involves splitting twice (<code>dataframe-split</code> and <code>dataframe-aggregate*</code>). Of course, neither are as elegant as the <code>dplyr</code> version.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb16-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># R </span></span>
<span id="cb16-2">purchases <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb16-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(country) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span>                    </span>
<span id="cb16-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(amount <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(amount) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> </span>
<span id="cb16-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarize</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">total =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sum</span>(amount <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> discount))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb17-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Python</span></span>
<span id="cb17-2">(purchases</span>
<span id="cb17-3">  .groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"country"</span>)                                               </span>
<span id="cb17-4">  .<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">apply</span>(<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> df: df[df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"amount"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"amount"</span>].median() <span class="op" 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="cb17-5">  .reset_index(drop<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)                                           </span>
<span id="cb17-6">  .groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"country"</span>)</span>
<span id="cb17-7">  .<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">apply</span>(<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> df: (df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"amount"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"discount"</span>]).<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>())</span>
<span id="cb17-8">  .reset_index()</span>
<span id="cb17-9">  .rename(columns<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>{<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"total"</span>})</span>
<span id="cb17-10">)</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb18-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Scheme</span></span>
<span id="cb18-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Version 1</span></span>
<span id="cb18-3">(-&gt; purchases</span>
<span id="cb18-4">    (dataframe-aggregate*</span>
<span id="cb18-5">     (country)</span>
<span id="cb18-6">     (total</span>
<span id="cb18-7">      (amount discount)</span>
<span id="cb18-8">      (sum (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (amt dis)</span>
<span id="cb18-9">                  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>multi (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> amt (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> (median amount))) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb18-10">                    (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> multi (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> amt dis))))</span>
<span id="cb18-11">                amount</span>
<span id="cb18-12">                discount)))))</span>
<span id="cb18-13"></span>
<span id="cb18-14"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; Version 2</span></span>
<span id="cb18-15">(-&gt; purchases</span>
<span id="cb18-16">    (dataframe-split 'country)</span>
<span id="cb18-17">    (-&gt;&gt; (map</span>
<span id="cb18-18">          (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (dfx)</span>
<span id="cb18-19">            (dataframe-filter*</span>
<span id="cb18-20">             dfx (amount) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> amount (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> (median (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> dfx 'amount))))))))</span>
<span id="cb18-21">    (dataframe-bind-all)</span>
<span id="cb18-22">    (dataframe-modify* (diff (amount discount) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> amount discount)))</span>
<span id="cb18-23">    (dataframe-aggregate* (country) (total (diff) (sum diff)))</span>
<span id="cb18-24">    (dataframe-display))</span></code></pre></div></div>
</section>
<section id="conclusion" class="level2">
<h2 class="anchored" data-anchor-id="conclusion">Conclusion</h2>
<p>I’m clearly biased, but I think a case could be made that my <code>dataframe</code> library for Scheme is at least not more clunky than <code>pandas</code>.</p>


</section>

 ]]></description>
  <category>Scheme</category>
  <category>dataframe</category>
  <category>R</category>
  <category>dplyr</category>
  <category>Python</category>
  <category>pandas</category>
  <guid>https://www.travishinkelman.com/posts/clunky-pandas.html</guid>
  <pubDate>Wed, 27 Mar 2024 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Exploratory data analysis in Elixir</title>
  <link>https://www.travishinkelman.com/posts/eda-elixir.html</link>
  <description><![CDATA[ 




<p>I have been tinkering with lots of different programming languages (see <a href="../posts/programming-horizons/">here</a> and <a href="../posts/programming-horizons-revisited/">here</a>) over the last few years. Scheme is the only language so far that I have enjoyed enough to write a decent amount of code. <a href="https://elixir-lang.org/">Elixir</a> first caught my eye back in April 2020, but I’ve only recently tried to write more than ‘hello world’ with it. So far, I think it is great and I’m excited to learn more. I haven’t previously been a fan of code notebooks, but I think <a href="https://livebook.dev/">Livebook</a> is amazing.</p>
<p>I’m using Elixir on Ubuntu. There are lots of different ways to install Elixir on Linux. I opted to first install Erlang with <code>sudo apt install erlang</code>. Then I installed the <a href="https://elixir-lang.org/install.html#precompiled-package">Elixir precompiled package</a> for the version of Erlang that I just installed (get Erlang/OTP version by running <code>erl -s erlang halt</code>). I moved the unzipped folder to my home directory and added the following line to <code>.zshrc</code>: <code>export PATH="$PATH:/home/username/elixir-otp-25/bin"</code>.</p>
<p>I installed Livebook by running <code>mix escript.install hex livebook</code> in the terminal and added the following line to <code>.zshrc</code>: <code>export PATH="$PATH:/home/username/.mix/escripts"</code>. After running <code>source .zshrc</code>, I was able to launch Livebook with <code>livebook server</code>.</p>
<p>As with learning Scheme, I like to first try to recreate examples that I’ve written in other programming languages. Below, I’ve written Elixir code that corresponds to the Scheme examples in <a href="../posts/eda-scheme/">this blog post</a> based on the Texas housing dataset that is included as part of the <code>ggplot2</code> package for R. I wrote that post to try out my <code>dataframe</code> library for Scheme, but below I will focus on the comparison with R. I will highlight snippets of code in this post, but the full notebook is <a href="https://github.com/hinkelman/livebook/blob/main/txhousing.livemd">here</a>.</p>
<p>One of the great features of Livebook is that the user-friendly GUI elements create code that is then easy to edit. It dramatically lowers the learning curve for beginners. At the top of every notebook is a setup block that includes an <code>Add package</code> button that allows for searching of available packages and generates the following code.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb1-1"><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Mix</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>install<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb1-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:kino</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"~&gt; 0.16.1"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span>,</span>
<span id="cb1-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:kino_explorer</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"~&gt; 0.1.24"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span>,</span>
<span id="cb1-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:kino_vega_lite</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"~&gt; 0.1.13"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span>,</span>
<span id="cb1-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:req</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"~&gt; 0.5.15"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-6"><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div></div>
<p><code>Kino</code> is behind the magic of Livebook. <code>KinoExplorer</code> and <code>KinoVegaLite</code> provide nice tables for viewing dataframes and data visualizations, respectively. Those packages include <code>Explorer</code> and <code>VegaLite</code> as dependencies so they do not need to be installed separately. I’m using <code>req</code> to get data directly from a URL.</p>
<p><a href="https://hexdocs.pm/explorer/Explorer.html"><code>Explorer</code></a> is a dataframe library for Elixir. I love the choice to mostly follow <code>dplyr</code>, which is my favorite R package. We <code>require</code> these packages because they require compilation and include aliases with <code>as:</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb2-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">require</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Explorer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">DataFrame</span>, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">as:</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">DF</span></span>
<span id="cb2-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">require</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Explorer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Series</span>, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">as:</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Series</span></span></code></pre></div></div>
<p>In R, <code>read.csv</code> allows for reading directly from a URL. This Elixir code composes well, though. It didn’t occur to me at first (but should have) that I should be searching for how to do a <code>GET</code> request. <code>load_csv</code> is used here because there is already a representation of the CSV in memory. To read a file from disk, use <code>from_csv</code>. The <code>!</code> in <code>load_csv!</code> indicates that a problem with the file will raise an exception, which is arguably the preferred behavior for an interactive use case like this notebook.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb3-1">txhousing <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span></span>
<span id="cb3-2">  <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Req</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>get!<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://www.travishinkelman.com/data/txhousing.csv"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>body</span>
<span id="cb3-3">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">DF</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>load_csv!<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">nil_values:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"NA"</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div></div>
<p>This block of code is almost exactly the same as what you would write in <code>dplyr</code>. I love that Elixir has a pipe operator (and it even uses the same characters as the pipe operator in base R!). It looks a little weird that pipe operators are placed at the beginning of lines after many years of using pipes in R.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb4-1">df_agg_year <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span></span>
<span id="cb4-2">  txhousing</span>
<span id="cb4-3">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">DF</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>group_by<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"year"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-4">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">DF</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>summarise<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb4-5">    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">avg_sales:</span> mean<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>sales<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span>,</span>
<span id="cb4-6">    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">avg_volume:</span> mean<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>volume<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span>,</span>
<span id="cb4-7">    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">avg_median:</span> mean<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>median<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div></div>
<p>In <code>group_by</code>, the column <code>month</code> can be written as a string (<code>"month"</code>) or an atom (<code>:month</code>) but it can’t be bare (<code>month</code>). In <code>summarise</code> and <code>arrange</code>, the column names must be bare, not a string or atom. Without reading the documentation or source code, I would guess that <code>summarise</code> and <code>arrange</code> are macros and <code>group_by</code> is not.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb5-1">df_agg_month <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span></span>
<span id="cb5-2">  txhousing</span>
<span id="cb5-3">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">DF</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>group_by<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:month</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb5-4">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">DF</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>summarise<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb5-5">    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">avg_sales:</span> mean<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>sales<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span>,</span>
<span id="cb5-6">    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">avg_volume:</span> mean<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>volume<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span>,</span>
<span id="cb5-7">    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">avg_median:</span> mean<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>median<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb5-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb5-9">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">DF</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>sort_by<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>month<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div></div>
<p>One of the convenient features of <code>dplyr::mutate</code> is that expressions can perform calculations on columns that were created within that <code>mutate</code>. Here we need to move that last expression to its own <code>DF.mutate</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb6-1">txhousing</span>
<span id="cb6-2"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">DF</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>group_by<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"city"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"year"</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">DF</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>mutate<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb6-4">  <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">total_sales:</span> sum<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>sales<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span>,</span>
<span id="cb6-5">  <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">total_volume:</span> sum<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>volume<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-6"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># need a new mutate when working with newly calculated column</span></span>
<span id="cb6-8"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">DF</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>mutate<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">prop_sales:</span> sales <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> total_sales<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div></div>



 ]]></description>
  <category>Elixir</category>
  <category>Explorer</category>
  <guid>https://www.travishinkelman.com/posts/eda-elixir.html</guid>
  <pubDate>Sat, 08 Jul 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Data transformation in Scheme</title>
  <link>https://www.travishinkelman.com/posts/data-transformation-scheme.html</link>
  <description><![CDATA[ 




<p>I have done some recent work on my <a href="https://github.com/hinkelman/dataframe/"><code>dataframe</code></a> library for Scheme (R6RS) and thought I would run through the examples in the <a href="https://r4ds.hadley.nz/data-transform.html">Data Transformation chapter</a> of <a href="https://r4ds.hadley.nz/">R for Data Science</a> (R4DS). In this post, I won’t reproduce any of the R code and will provide limited commentary on the Scheme code (which is also available via this <a href="https://gist.github.com/hinkelman/0945b3c905dcd244809bbed81d2faeb1">gist</a>).</p>
<section id="setup" class="level3">
<h3 class="anchored" data-anchor-id="setup">Setup</h3>
<p>The <code>nycflights13::flights</code> dataset is used for all of the examples shown below. I’ve written it to a file and posted it <a href="../data/nycflights.tsv">here</a>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb1-1">(import (dataframe))</span>
<span id="cb1-2"></span>
<span id="cb1-3">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> flights </span>(tsv-&gt;dataframe <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"nycflights.tsv"</span>))</span></code></pre></div></div>
<p>The <code>flights</code> dataset has 336,776 rows and 19 columns. Datasets of this size strain the dataframe library and provide a suboptimal experience, especially compared to R. Skipped sections indicate that the <code>dataframe</code> library has no equivalent capabilities.</p>
</section>
<section id="introduction" class="level3">
<h3 class="anchored" data-anchor-id="introduction">3.1 Introduction</h3>
<p><em>3.1.3</em></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb2-1">(-&gt; flights</span>
<span id="cb2-2">    (dataframe-filter* (dest) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> dest <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IAH"</span>)) </span>
<span id="cb2-3">    (dataframe-aggregate*</span>
<span id="cb2-4">     (year month day)</span>
<span id="cb2-5">     (arr_delay (arr_delay) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">inexact</span> (mean arr_delay))))</span>
<span id="cb2-6">    (dataframe-display))</span></code></pre></div></div>
</section>
<section id="rows" class="level3">
<h3 class="anchored" data-anchor-id="rows">3.2 Rows</h3>
<p><em>3.2.1</em></p>
<p>Piping all of the output to a <code>dataframe-display</code> will often not show clearly the operation was successful. The one liners below show that the operation yielded the expected result. Need to remove <code>'na</code> from the <code>dep_delay</code> column or the <code>&gt;</code> operation will fail. The version with <code>dataframe-remove-na</code> is more readable, but requires two passes through the data.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb3-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; filter only version</span></span>
<span id="cb3-2">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> delayed-flights</span></span>
<span id="cb3-3">  (-&gt; flights</span>
<span id="cb3-4">      (dataframe-filter*</span>
<span id="cb3-5">       (dep_delay)</span>
<span id="cb3-6">       (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> (na? dep_delay))</span>
<span id="cb3-7">            (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> dep_delay <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">120</span>)))))</span>
<span id="cb3-8"></span>
<span id="cb3-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; remove na first</span></span>
<span id="cb3-10">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> delayed-flights</span></span>
<span id="cb3-11">  (-&gt; flights</span>
<span id="cb3-12">      (dataframe-remove-na 'dep_delay)</span>
<span id="cb3-13">      (dataframe-filter* (dep_delay) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> dep_delay <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">120</span>))))</span>
<span id="cb3-14"></span>
<span id="cb3-15">(apply <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">min</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> delayed-flights 'dep_delay))</span>
<span id="cb3-16"></span>
<span id="cb3-17">(-&gt; flights</span>
<span id="cb3-18">    (dataframe-remove-na 'month 'day)</span>
<span id="cb3-19">    (dataframe-filter* (month day) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> month <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> day <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)))</span>
<span id="cb3-20">    (dataframe-glimpse))</span>
<span id="cb3-21"></span>
<span id="cb3-22">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> jan-feb-flights</span></span>
<span id="cb3-23">  (-&gt; flights</span>
<span id="cb3-24">      (dataframe-remove-na 'month)</span>
<span id="cb3-25">      (dataframe-filter* (month) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">or</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> month <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> month <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)))))</span>
<span id="cb3-26"></span>
<span id="cb3-27">(remove-duplicates (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> jan-feb-flights 'month))</span>
<span id="cb3-28"></span>
<span id="cb3-29">(-&gt; flights</span>
<span id="cb3-30">    (dataframe-remove-na 'month)</span>
<span id="cb3-31">    (dataframe-filter* (month) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">member</span> month '(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)))</span>
<span id="cb3-32">    (dataframe-glimpse))</span></code></pre></div></div>
<p><em>3.2.3</em></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb4-1">(-&gt; flights</span>
<span id="cb4-2">    (dataframe-remove-na 'year 'month 'day 'dep_time)</span>
<span id="cb4-3">    (dataframe-sort* (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> year) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> month) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> day) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> dep_time))</span>
<span id="cb4-4">    (dataframe-glimpse))</span>
<span id="cb4-5"></span>
<span id="cb4-6">(-&gt; flights</span>
<span id="cb4-7">    (dataframe-remove-na 'dep_delay)</span>
<span id="cb4-8">    (dataframe-sort* (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> dep_delay))</span>
<span id="cb4-9">    (dataframe-glimpse))</span></code></pre></div></div>
<p><em>3.2.4</em></p>
<p><code>dplyr::distinct</code> has a parameter, <code>.keep_all</code>, that keeps all columns for the first occurrence of each unique combo. <code>dataframe-unique</code> does not have that functionality.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb5-1">(-&gt; flights</span>
<span id="cb5-2">    (dataframe-unique)</span>
<span id="cb5-3">    (dataframe-glimpse))</span>
<span id="cb5-4"></span>
<span id="cb5-5">(-&gt; flights</span>
<span id="cb5-6">    (dataframe-select* origin dest)</span>
<span id="cb5-7">    (dataframe-unique)</span>
<span id="cb5-8">    (dataframe-glimpse))</span></code></pre></div></div>
<p>The <code>dataframe</code> library does not include a procedure comparable to <code>dplyr::count</code>, but the same result can be obtained with <code>dataframe-aggregate*</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb6-1">(-&gt; flights</span>
<span id="cb6-2">    (dataframe-aggregate*</span>
<span id="cb6-3">     (origin dest)</span>
<span id="cb6-4">     (n (origin) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">length</span> origin)))</span>
<span id="cb6-5">    (dataframe-sort*</span>
<span id="cb6-6">     (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> n))</span>
<span id="cb6-7">    (dataframe-display))</span></code></pre></div></div>
</section>
<section id="columns" class="level3">
<h3 class="anchored" data-anchor-id="columns">3.3 Columns</h3>
<p><em>3.3.1</em></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb7-1">(-&gt; flights</span>
<span id="cb7-2">    (dataframe-remove-na 'dep_delay 'arr_delay 'distance 'air_time)</span>
<span id="cb7-3">    (dataframe-modify*</span>
<span id="cb7-4">     (gain (dep_delay arr_delay) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> dep_delay arr_delay))</span>
<span id="cb7-5">     (speed (distance air_time) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> distance air_time) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span>)))</span>
<span id="cb7-6">    (dataframe-glimpse))</span></code></pre></div></div>
<p><code>dataframe-modify*</code> has no equivalent to the <code>.before</code> and <code>.after</code> parameters of <code>dplyr::mutate</code>. Using a <code>dataframe-select</code> to get focal columns but this drops all other columns.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb8-1">(-&gt; flights</span>
<span id="cb8-2">    (dataframe-remove-na 'dep_delay 'arr_delay 'distance 'air_time)</span>
<span id="cb8-3">    (dataframe-modify*</span>
<span id="cb8-4">     (gain (dep_delay arr_delay) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> dep_delay arr_delay))</span>
<span id="cb8-5">     (speed (distance air_time) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">inexact</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> distance air_time) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span>))))</span>
<span id="cb8-6">    (dataframe-select* year month day gain speed)</span>
<span id="cb8-7">    (dataframe-display))</span></code></pre></div></div>
<p><em>3.3.2</em></p>
<p><code>dplyr::select</code> has many wonderful helper functions to do complicated select operations easily. <code>dataframe-select*</code> is very simple.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb9-1">(-&gt; flights</span>
<span id="cb9-2">    (dataframe-select* year month day)</span>
<span id="cb9-3">    (dataframe-display))</span></code></pre></div></div>
<p><em>3.3.3</em></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb10-1">(-&gt; flights</span>
<span id="cb10-2">    (dataframe-rename* (tailnum tail_num))</span>
<span id="cb10-3">    (dataframe-glimpse))</span></code></pre></div></div>
</section>
<section id="the-pipe" class="level3">
<h3 class="anchored" data-anchor-id="the-pipe">3.4 The Pipe</h3>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb11-1">(-&gt; flights</span>
<span id="cb11-2">    (dataframe-remove-na 'dest 'distance 'air_time)</span>
<span id="cb11-3">    (dataframe-filter* (dest) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> dest <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IAH"</span>))</span>
<span id="cb11-4">    (dataframe-modify*</span>
<span id="cb11-5">     (speed</span>
<span id="cb11-6">      (distance air_time)</span>
<span id="cb11-7">      (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">inexact</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> distance air_time) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span>))))</span>
<span id="cb11-8">    (dataframe-select*</span>
<span id="cb11-9">     year month day dep_time carrier flight speed)</span>
<span id="cb11-10">    (dataframe-sort*</span>
<span id="cb11-11">     (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> speed))</span>
<span id="cb11-12">    (dataframe-display))</span>
<span id="cb11-13"></span>
<span id="cb11-14">(dataframe-display</span>
<span id="cb11-15"> (dataframe-sort*</span>
<span id="cb11-16">  (dataframe-select*</span>
<span id="cb11-17">   (dataframe-modify*</span>
<span id="cb11-18">    (dataframe-filter*</span>
<span id="cb11-19">     (dataframe-remove-na flights 'dest 'distance 'air_time)</span>
<span id="cb11-20">     (dest) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> dest <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IAH"</span>))</span>
<span id="cb11-21">    (speed</span>
<span id="cb11-22">     (distance air_time)</span>
<span id="cb11-23">     (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">inexact</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> distance air_time) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span>))))</span>
<span id="cb11-24">   year month day dep_time carrier flight speed)</span>
<span id="cb11-25">  (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> speed)))</span>
<span id="cb11-26"></span>
<span id="cb11-27">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> flights1</span></span>
<span id="cb11-28">  (dataframe-filter*</span>
<span id="cb11-29">   (dataframe-remove-na flights 'dest 'distance 'air_time)</span>
<span id="cb11-30">   (dest distance air_time)</span>
<span id="cb11-31">   (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> dest <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IAH"</span>)))</span>
<span id="cb11-32"></span>
<span id="cb11-33">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> flights2</span></span>
<span id="cb11-34">  (dataframe-modify*</span>
<span id="cb11-35">   flights1</span>
<span id="cb11-36">   (speed</span>
<span id="cb11-37">    (distance air_time)</span>
<span id="cb11-38">    (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">inexact</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> distance air_time) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span>)))))</span>
<span id="cb11-39"></span>
<span id="cb11-40">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> flights3</span></span>
<span id="cb11-41">  (dataframe-select*</span>
<span id="cb11-42">   flights2</span>
<span id="cb11-43">   year month day dep_time carrier flight speed))</span>
<span id="cb11-44"></span>
<span id="cb11-45">(dataframe-display</span>
<span id="cb11-46"> (dataframe-sort* flights3 (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> speed)))</span></code></pre></div></div>
</section>
<section id="groups" class="level3">
<h3 class="anchored" data-anchor-id="groups">3.5 Groups</h3>
<p><em>3.5.2</em></p>
<p><code>dplyr::group_by</code> automatically sorts by grouping variables, but that step needs to be done explicitly in <code>dataframe-aggregate*</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb12-1">(-&gt; flights</span>
<span id="cb12-2">    (dataframe-aggregate*</span>
<span id="cb12-3">     (month)</span>
<span id="cb12-4">     (avg_delay (dep_delay) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">inexact</span> (mean dep_delay))))</span>
<span id="cb12-5">    (dataframe-sort*</span>
<span id="cb12-6">     (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> month))</span>
<span id="cb12-7">    (dataframe-display))</span>
<span id="cb12-8"></span>
<span id="cb12-9">(-&gt; flights</span>
<span id="cb12-10">    (dataframe-remove-na 'dep_delay)</span>
<span id="cb12-11">    (dataframe-aggregate*</span>
<span id="cb12-12">     (month)</span>
<span id="cb12-13">     (avg_delay (dep_delay) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">inexact</span> (mean dep_delay)))</span>
<span id="cb12-14">     (n (dep_delay) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">length</span> dep_delay)))</span>
<span id="cb12-15">    (dataframe-sort*</span>
<span id="cb12-16">     (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> month))</span>
<span id="cb12-17">    (dataframe-display))</span></code></pre></div></div>
<p><em>4.5.5</em></p>
<p><code>dataframe-aggregate*</code> struggles when splitting a large dataframe into many groups (in this case, 365). The operation to summarize monthly results (not shown) is reasonably quick. In this case, I didn’t bother to filter because I knew there were no missing values for <code>year</code>, <code>month</code>, and <code>day</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb13-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> daily_flights</span></span>
<span id="cb13-2">  (dataframe-aggregate*</span>
<span id="cb13-3">   flights</span>
<span id="cb13-4">   (year month day)</span>
<span id="cb13-5">   (n (dep_time) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">length</span> dep_time))))</span></code></pre></div></div>


</section>

 ]]></description>
  <category>Scheme</category>
  <category>dataframe</category>
  <category>R</category>
  <category>dplyr</category>
  <guid>https://www.travishinkelman.com/posts/data-transformation-scheme.html</guid>
  <pubDate>Fri, 07 Jul 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>From Python to NumPy: random walk example in R and Scheme</title>
  <link>https://www.travishinkelman.com/posts/from-python-to-numpy-random-walk.html</link>
  <description><![CDATA[ 




<p>As a learning exercise, I decided to translate examples from the book, <a href="https://www.labri.fr/perso/nrougier/from-python-to-numpy/">From Python to NumPy</a>, into R and Chez Scheme. This post describes the <a href="https://www.labri.fr/perso/nrougier/from-python-to-numpy/#simple-example">random walk example from Chapter 2</a>. All of the code is in <a href="https://github.com/hinkelman/from-python-to-numpy">this repository</a> so I will only highlight a few pieces of code below. For context, I am a long-time R programmer who only periodically pokes at Python and dabbles in Scheme for fun. Because performance is the primary motivation of vectorizing code with NumPy in Python, I will be loosely comparing timings between Python, R, and Chez Scheme. Take these timings with a large grain of salt. I don’t know how comparable the different timings are.</p>
<p>The simple example to motivate the book involves a 1D random walk. The book starts with a <code>for loop</code> example, reports a 7x speed up over the <code>for loop</code> by vectorizing the code with <code>itertools</code>, and reports a 500x improvement from <code>for loop</code> to NumPy (but, by my math, the reported timings show 1000x). On my machine, I also observe a 7x speed up from <code>for loop</code> to <code>itertools</code> but only a 80x jump from <code>for loop</code> to NumPy. The <code>for loop</code> in R has comparable peformance to the <code>for loop</code> in Python, but vectorized R was about 2x as fast as NumPy. Here are vectorized versions of the functions in Python (NumPy) and R:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Python</span></span>
<span id="cb1-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> random_walk_fastest(n<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000</span>):</span>
<span id="cb1-3">    steps <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.random.choice([<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], n)</span>
<span id="cb1-4">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> np.cumsum(steps)</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;"># R</span></span>
<span id="cb2-2">random_walk_v <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000</span>) {</span>
<span id="cb2-3">  steps <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sample</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> n, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">replace =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>)</span>
<span id="cb2-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">cumsum</span>(steps)</span>
<span id="cb2-5">}</span></code></pre></div></div>
<p>Chez Scheme doesn’t have the option to speed up code by vectorizing it, but Chez is known as one of the most performant Scheme implementations. I tried a couple of versions of the procedure in Chez. In one, I iterated over a vector with a <code>do loop</code>. In the other, I used recursion on a list. Both performed similarly at about 1.5x as fast as the vectorized R version. Here is the recursive version:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb3-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">random-help</span>)</span>
<span id="cb3-2">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; (random 2) returns 0 or 1</span></span>
<span id="cb3-3">  (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> (random <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>))</span>
<span id="cb3-4"></span>
<span id="cb3-5">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">random-walk-lst </span>n)</span>
<span id="cb3-6">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> loop (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>step <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb3-7">             <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>position (random-help)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb3-8">             <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>walk '()<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb3-9">    (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> step n)</span>
<span id="cb3-10">        (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">reverse</span> walk)</span>
<span id="cb3-11">        (loop (add1 step)</span>
<span id="cb3-12">              (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> position (random-help))</span>
<span id="cb3-13">              (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cons</span> position walk)))))</span></code></pre></div></div>
<p>In the next example, the author makes the point that the best NumPy performance often comes at the expense of readability. The example involves returning the starting index for all occurrences of a sub-sequence that are found in the random walk list. The book indicates that the NumPy version was 10x faster than pure Python (7x on my machine). In trying to identify the best way to implement this in R, I found this <a href="https://stat.ethz.ch/pipermail/r-help/2012-February/303756.html">mailing list thread</a> with numerous solutions that vary widely in speed. The fastest R version (of the ones that I tried) was nearly 8x faster than the next best solution. I implemented that same algorithm in Python (+ a little NumPy). It was nearly 4x as fast as the NumPy example from the book and comparably fast to the R version. Here is that algorithm in Python and R (apologies for the inconsistent naming between my R and Python files):</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb4-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Python</span></span>
<span id="cb4-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> find_crossing_3(seq, sub):</span>
<span id="cb4-3">    n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(seq)</span>
<span id="cb4-4">    m <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(sub)</span>
<span id="cb4-5">    candidate <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.arange(n<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>m)</span>
<span id="cb4-6">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(m):</span>
<span id="cb4-7">        candidate <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> candidate[sub[i] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> seq[candidate <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> i]]</span>
<span id="cb4-8">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> candidate</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb5-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># R</span></span>
<span id="cb5-2">find_crossing_2 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(seq, sub) {</span>
<span id="cb5-3">  n <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">length</span>(seq)</span>
<span id="cb5-4">  m <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">length</span>(sub)</span>
<span id="cb5-5">  candidate <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">seq_len</span>(n <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> m <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb5-6">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> (i <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">seq_len</span>(m)) {</span>
<span id="cb5-7">    candidate <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> candidate[sub[i] <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> seq[candidate <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> i <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]]</span>
<span id="cb5-8">  }</span>
<span id="cb5-9">  candidate</span>
<span id="cb5-10">}</span></code></pre></div></div>
<p>Unfortunately, it is not possible (as far as I understand) to reproduce this algorithm in Chez Scheme and my alternative was about 50x slower than the Python and R versions.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb6-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; https://stackoverflow.com/a/28034455</span></span>
<span id="cb6-2">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">first-n </span>lst n)</span>
<span id="cb6-3">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">zero?</span> n)            </span>
<span id="cb6-4">      '()                </span>
<span id="cb6-5">      (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cons</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> lst)         </span>
<span id="cb6-6">            (first-n (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cdr</span> lst)    </span>
<span id="cb6-7">                     (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> n <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)))))</span>
<span id="cb6-8"></span>
<span id="cb6-9">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">find-crossing-lst </span>seq sub)</span>
<span id="cb6-10">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> loop (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>index <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb6-11">             <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>lst seq<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb6-12">             <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>results '()<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb6-13">    (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">length</span> lst) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">length</span> sub))</span>
<span id="cb6-14">        (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">reverse</span> results)</span>
<span id="cb6-15">        (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">equal?</span> (first-n lst (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">length</span> sub)) sub)</span>
<span id="cb6-16">            (loop (add1 index) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cdr</span> lst) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cons</span> index results))</span>
<span id="cb6-17">            (loop (add1 index) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cdr</span> lst) results)))))</span></code></pre></div></div>
<p>After asking on the <a href="https://discord.gg/8zjfdtj4">Scheme Discord server</a>, oaktownsam provided the code below, which is 35x faster than my original version.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb7-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">same-head? </span>seq sub)</span>
<span id="cb7-2">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cond</span></span>
<span id="cb7-3">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null?</span> seq) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null?</span> sub)) <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb7-4">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null?</span> sub)                   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb7-5">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null?</span> seq)                   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#f</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb7-6">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">equal?</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> seq) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> sub))  (same-head? (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cdr</span> seq) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cdr</span> sub))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb7-7">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#f</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>))</span>
<span id="cb7-8"></span>
<span id="cb7-9">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">find-crossing-lst-2 </span>seq sub)</span>
<span id="cb7-10">  (<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">step </span>index seq results)</span>
<span id="cb7-11">    (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cond</span></span>
<span id="cb7-12">      <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null?</span> seq) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">reverse</span> results)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb7-13">      <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(same-head? seq sub) (step (add1 index) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cdr</span> seq) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cons</span> index results))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb7-14">      <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> (step (add1 index) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cdr</span> seq) results)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>))</span>
<span id="cb7-15">  (step <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> seq '()))</span></code></pre></div></div>



 ]]></description>
  <category>Python</category>
  <category>R</category>
  <category>Scheme</category>
  <guid>https://www.travishinkelman.com/posts/from-python-to-numpy-random-walk.html</guid>
  <pubDate>Sun, 21 Aug 2022 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Visualizing Scheme library procedures with an interactive network graph in R</title>
  <link>https://www.travishinkelman.com/posts/visualize-scheme-library.html</link>
  <description><![CDATA[ 




<p>As a learning exercise, I wrote a <a href="https://github.com/hinkelman/dataframe/"><code>dataframe</code></a> library for Scheme (R6RS). Because I was learning Scheme while I wrote <code>dataframe</code>, I did not prioritize performance. However, as I’ve tried to use the <code>dataframe</code> library (<a href="../posts/eda-scheme">exploratory data analysis</a>, <a href="../posts/spam-simulation-scheme/">spam simulation</a>, <a href="../posts/gapminder-base-r-scheme/">gapminder</a>), I’ve encountered performance pitfalls that make <code>dataframe</code> largely unusable for datasets with more than a few thousand rows. I have a rough idea of where the bottlenecks are, but I thought it would be a useful to take a step back and visualize the <code>dataframe</code> procedures as a network graph.</p>
<p>UPDATE: I improved <code>dataframe</code> such that performance is reasonable on datasets up to roughly one hundred thousand rows.</p>
<p>I had some experience with the R package, <a href="https://uptake.github.io/pkgnet/"><code>pkgnet</code></a>, which allows for exploring the structure of a package by building a graph representation. I had also spent a little time using the package, <a href="https://datastorm-open.github.io/visNetwork/"><code>visNetwork</code></a>, that <code>pkgnet</code> uses to build the function graph. Moreover, because code is data in Scheme, it is relatively straightforward to analyze Scheme code and I had briefly experimented with that in a <a href="../posts/viewing-source-code-r-chez-scheme">previous blog post</a>.</p>
<section id="prepare-data" class="level2">
<h2 class="anchored" data-anchor-id="prepare-data">Prepare Data</h2>
<p>All of the Scheme code to analyze the <code>dataframe</code> procedures is found <a href="https://github.com/hinkelman/dataframe/blob/master/network-graph/network-graph.ss">here</a>. Below I will walk through the main ideas.</p>
<p>First, let’s create a silly example of Scheme library code. <code>example</code> is the list that would be created as the result of reading a file called <code>example-library.sls</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb1-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> example</span></span>
<span id="cb1-2">  '(library (example-library)</span>
<span id="cb1-3">     (export exported-proc)</span>
<span id="cb1-4">     (import (rnrs))</span>
<span id="cb1-5">     (<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> exported-proc</span></span>
<span id="cb1-6">       (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case-lambda</span></span>
<span id="cb1-7">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(x1) (exported-proc-helper x1 <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb1-8">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(x1 x2) (exported-proc-helper x1 x2)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>))</span>
<span id="cb1-9">     (<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">exported-proc-helper </span>x1 x2)</span>
<span id="cb1-10">       (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>x-sum (sum2 x1 x2)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb1-11">         (map add1 (iota x-sum))))</span>
<span id="cb1-12">     (<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sum2 </span>x1 x2)</span>
<span id="cb1-13">       (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x1 x2))</span>
<span id="cb1-14">     (<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">add1 </span>x)</span>
<span id="cb1-15">       (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>))</span>
<span id="cb1-16">     (<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">iota </span>count)</span>
<span id="cb1-17">       (<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> start </span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span>
<span id="cb1-18">       (<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> step </span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb1-19">       (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> loop ((n <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) (r '()))</span>
<span id="cb1-20">         (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> n count)</span>
<span id="cb1-21">         (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">reverse</span> r)</span>
<span id="cb1-22">         (loop (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> n)</span>
<span id="cb1-23">               (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cons</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> start (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> n step)) r)))))))</span></code></pre></div></div>
<p>We can work with <code>example</code> in the same way as any other Scheme list.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb2-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> example)</span>
<span id="cb2-2">library</span>
<span id="cb2-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">length</span> example)</span>
<span id="cb2-4"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span></span></code></pre></div></div>
<p>The following two procedures are used to extract the procedure names from <code>example</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb3-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; get all procedure definitions</span></span>
<span id="cb3-2">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">get-defs </span>lst)</span>
<span id="cb3-3">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">filter</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (x)</span>
<span id="cb3-4">            (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">pair?</span> x)</span>
<span id="cb3-5">                 (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">or</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">symbol=?</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> x) 'define)</span>
<span id="cb3-6">                     (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">symbol=?</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> x) 'define-syntax))))</span>
<span id="cb3-7">          lst))</span>
<span id="cb3-8"></span>
<span id="cb3-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; name is the procedure name</span></span>
<span id="cb3-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; def is one element of the list from get-defs</span></span>
<span id="cb3-11">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">get-name </span>def)</span>
<span id="cb3-12">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">pair?</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cadr</span> def)) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">symbol=?</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> def) 'define-syntax)))</span>
<span id="cb3-13">      (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">caadr</span> def)</span>
<span id="cb3-14">      <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; cadr version for definitions using lambda, case-lambda, and define-syntax</span></span>
<span id="cb3-15">      (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cadr</span> def)))</span></code></pre></div></div>
<p>We map <code>get-name</code> across the list from <code>get-defs</code> to get our list of procedure names.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb4-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> defs </span>(get-defs example))</span>
<span id="cb4-2"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> names </span>(map get-name defs))</span>
<span id="cb4-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> names</span>
<span id="cb4-4">(exported-proc exported-proc-helper sum2 add1 iota)</span></code></pre></div></div>
<p>The procedure names are the nodes in our network graph. The connections between the procedures are the edges. <code>visNetwork</code> requires that the edge list is defined by ID numbers, not procedure names. Next we create a list of pairs with each procedure assigned an ID number.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb5-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> names-nums </span></span>
<span id="cb5-2">      (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (name num) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cons</span> name num)) names (enumerate names)))</span>
<span id="cb5-3">                                                          </span>
<span id="cb5-4"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> names-nums</span>
<span id="cb5-5">((exported-proc <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span>
<span id="cb5-6">  (exported-proc-helper <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb5-7">  (sum2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb5-8">  (add1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)</span>
<span id="cb5-9">  (iota <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>))</span></code></pre></div></div>
<p>Now that we have enumerated our procedures, we need to iterate through all of the procedure definitions to identify which other procedures are called from within each procedure. Even though recursion is great for working with nested data structures, the <code>get-edges</code> procedure is the first time that I had ever used deep recursion (i.e., recursing on both the <code>car</code> and <code>cdr</code> of a list).</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb6-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">get-edges </span>def names-nums)</span>
<span id="cb6-2">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let*</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>name (get-name def)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb6-3">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>num (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cdr</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">assoc</span> name names-nums))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb6-4">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>out (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> loop (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>body (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cddr</span> def)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb6-5">                         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>results '()<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb6-6">                (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cond</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null?</span> body)</span>
<span id="cb6-7">                       results<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb6-8">                      <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>(<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">pair?</span> body))</span>
<span id="cb6-9">                       (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>name-num (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">assoc</span> body names-nums)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb6-10">                         (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> name-num (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cons</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cdr</span> name-num) results) results))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb6-11">                      <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span></span>
<span id="cb6-12">                       (loop (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">car</span> body) (loop (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cdr</span> body) results))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb6-13">    (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (x) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cons</span> num x)) (remove-duplicates out))))</span></code></pre></div></div>
<p><code>get-edges</code> returns a list of pairs where the <code>car</code> is the ID of <code>def</code> and the <code>cdr</code> is the ID of the procedures called by <code>def</code>. Here is the output of <code>get-edges</code> when applied to <code>exported-proc-helper</code>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb7-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cadr</span> defs)</span>
<span id="cb7-2">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">exported-proc-helper </span>x1 x2)</span>
<span id="cb7-3">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>x-sum (sum2 x1 x2)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>) (map add1 (iota x-sum))))</span>
<span id="cb7-4"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (get-edges (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cadr</span> defs) names-nums)</span>
<span id="cb7-5">((<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>) (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>) (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>))</span></code></pre></div></div>
<p>That covers the main ideas in preparing the data. The rest of the <a href="https://github.com/hinkelman/dataframe/blob/master/network-graph/network-graph.ss">code</a> just applies those ideas across multiple files and writes the data for use by R.</p>
</section>
<section id="visualize-data" class="level2">
<h2 class="anchored" data-anchor-id="visualize-data">Visualize Data</h2>
<p>The network graph is visualized in a <a href="https://shiny.rstudio.com/">Shiny</a> app with <code>visNetwork</code>. The code for the app can be found in <a href="https://gist.github.com/hinkelman/df2422122a4a0588973dd2af443a1100">this gist</a>. The live app can be viewed <a href="https://hinkelman.shinyapps.io/dataframe-network-graph/">here</a>. [Note, it takes several seconds to build and display the graph in the Shiny app.] It requires remarkably little code to visualize the network graph. For example, this is all that is required for the server code in the Shiny app.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb8-1">output<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>networkGraph <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">renderVisNetwork</span>({</span>
<span id="cb8-2">    nodes <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span> </span>
<span id="cb8-3">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">visNetwork</span>(edges) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb8-4">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">visEdges</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">arrows =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"to"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span> </span>
<span id="cb8-5">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">visOptions</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">highlightNearest =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>, </span>
<span id="cb8-6">                    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">nodesIdSelection =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>)</span>
<span id="cb8-7">})</span></code></pre></div></div>
</section>
<section id="conclusions" class="level2">
<h2 class="anchored" data-anchor-id="conclusions">Conclusions</h2>
<p>Here are a couple of observations from the network graph:</p>
<ul>
<li>Unsurprisingly, a few procedures are called by a lot of other procedures, e.g., <code>make-dataframe</code>, <code>dataframe-slist</code>, <code>check-dataframe</code>.</li>
<li>A few procedures (<code>make-series</code>, <code>make-dataframe</code>, etc.) are created automatically as part of defining the record types. I added them to the list of procedure names by appending the list of exported procedure names to the list of extracted procedure names (and removing duplicates from the appended list).</li>
</ul>


</section>

 ]]></description>
  <category>Scheme</category>
  <category>dataframe</category>
  <category>R</category>
  <category>Shiny</category>
  <guid>https://www.travishinkelman.com/posts/visualize-scheme-library.html</guid>
  <pubDate>Sat, 05 Jun 2021 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Stochastic population model in R, Rcpp, and Fortran</title>
  <link>https://www.travishinkelman.com/posts/stochastic-population-model-r-fortran.html</link>
  <description><![CDATA[ 




<p>The stochastic logistic population model described in <a href="https://www.seascapemodels.org/rstats/2017/02/26/speeding-up-sims.html">this blog post</a> has become my default exercise when I’m exploring a new programming language (<a href="../posts/stochastic-population-model-r-racket/">Racket</a>, <a href="../posts/stochastic-population-model-fsharp/">F#</a>, <a href="../posts/stochastic-population-model-rust/">Rust</a>). I ended that Rust post by noting that I was interested in Rust as a modern alternative for scientific computing and thought it would be a good learning exercise to re-write small legacy Fortran programs in Rust. In the process of looking for Fortran programs to translate to Rust, though, I found myself becoming more interested in the idea of learning Fortran than Rust, particularly after learning about the efforts to improve the tooling around Fortran (e.g., <a href="https://ondrejcertik.com/blog/2021/03/resurrecting-fortran/">here</a> and <a href="https://youtu.be/JUHS-JFvs90">here</a>). So, here we are…exploring Fortran via the <a href="https://github.com/hinkelman/stochastic-population-model">stochastic population model exercise</a>.</p>
<section id="standalone-fortran-program" class="level3">
<h3 class="anchored" data-anchor-id="standalone-fortran-program">Standalone Fortran Program</h3>
<p>First, I wrote a <a href="https://github.com/hinkelman/stochastic-population-model/blob/main/R-Fortran/stochastic-logistic.f90">standalone Fortran program</a> of the stochastic population model. The main thing that tripped me up was reading arguments from the command line. I initialized a 1D array for holding the values of the arguments.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode fortran code-with-copy"><code class="sourceCode fortranfixed"><span id="cb1-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">character(len=20), dimension(5) :: args</span></span></code></pre></div></div>
<p>I initially missed the <code>len</code> argument for <code>character</code> and was confused by the results I was getting until I realized that the program was only reading the first character provided for each argument.</p>
<p>We can straightforwardly fill the <code>args</code> array with a loop.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode fortran code-with-copy"><code class="sourceCode fortranfixed"><span id="cb2-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span> i<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,command_argument_count()</span>
<span id="cb2-2">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">call</span> get_command_argument(i, args(i))</span>
<span id="cb2-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end do</span></span></code></pre></div></div>
<p>But the syntax for converting the arguments from strings to the correct types is unusual.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode fortran code-with-copy"><code class="sourceCode fortranfixed"><span id="cb3-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">read(</span>args(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>), <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">*)</span> t</span></code></pre></div></div>
<p><code>t</code> is the first value in <code>args</code> (indexed with <code>args(1)</code>). The <code>*</code> indicates the default format of the value, which the compiler infers is an <code>integer</code> because that is the type of <code>t</code>.</p>
</section>
<section id="fortran-subroutines" class="level3">
<h3 class="anchored" data-anchor-id="fortran-subroutines">Fortran Subroutines</h3>
<p>I also created a <a href="https://github.com/hinkelman/stochastic-population-model/blob/main/R-Fortran/stochastic-logistic-subroutines.f90">file</a> that only contains subroutines for calling from R. Two of the subroutines (<code>rstduniform</code> and <code>rnormal</code>) are mostly the same as from the main program, but the names are changed because the R help for the <code>.Fortran</code> function recommended not using underscores in the subroutine names and the type of several parameters is <code>double precision</code>, not <code>real</code>, for compatibility with R. One of the subroutines, <code>rnorm</code>, is only included as a test of <code>rnormal</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode fortran code-with-copy"><code class="sourceCode fortranfixed"><span id="cb4-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">subroutine</span> rnorm(reps, mu, sigma, arr)</span>
<span id="cb4-2">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">implicit</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">none</span></span>
<span id="cb4-3">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">integer</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">::</span> i</span>
<span id="cb4-4">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">integer</span>, <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">intent(in)</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">::</span> reps</span>
<span id="cb4-5">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double precision</span>, <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">intent(in)</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">::</span> mu, sigma</span>
<span id="cb4-6">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double precision</span>, <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">intent(inout)</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">::</span> arr(reps)</span>
<span id="cb4-7">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span> i<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,reps</span>
<span id="cb4-8">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">call</span> rnormal(mu, sigma, arr(i))</span>
<span id="cb4-9">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end do</span></span>
<span id="cb4-10"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end subroutine</span> rnorm</span></code></pre></div></div>
<p>The <code>arr</code> parameter is declared as <code>intent(inout)</code> because on the R side we will pass in a vector that is filled on the Fortran side and then returned again to R. There are performance pitfalls with this approach if you are passing large vectors back-and-forth between Fortran and R, but those can be partly mitigated with the use of the <a href="https://cran.r-project.org/web/packages/dotCall64/index.html">dotCall64 package</a>.</p>
<p>We compile this file into a shared object for use in R with</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb5-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">R</span> CMD SHLIB stochastic-logistic-subroutines.f90</span></code></pre></div></div>
</section>
<section id="calling-fortran-from-r" class="level3">
<h3 class="anchored" data-anchor-id="calling-fortran-from-r">Calling Fortran from R</h3>
<p>In the <a href="https://github.com/hinkelman/stochastic-population-model/blob/main/R-Fortran/stochastic-logistic.R">R code</a>, we load the shared object with</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb6-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dyn.load</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"stochastic-logistic-subroutines.so"</span>)</span></code></pre></div></div>
<p>To test that the <code>rnormal</code> subroutine is giving reasonable results, we call the <code>rnorm</code> subroutine as the first argument to <code>.Fortran</code>. In this example, we draw 1 million random variates from a normal distribution with a mean of 7.8 and standard deviation of 8.3.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb7-1"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> n <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000000</span>L</span>
<span id="cb7-2"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> rnorm_result <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">.Fortran</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"rnorm"</span>, n, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">7.8</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">8.3</span>, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">vector</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"numeric"</span>, n))</span>
<span id="cb7-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># .Fortran returns a list; 4th element of list in this case contains the vector</span></span>
<span id="cb7-4"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mean</span>(rnorm_result[[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>]])</span>
<span id="cb7-5">[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>] <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">7.798748</span></span>
<span id="cb7-6"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sd</span>(rnorm_result[[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>]])</span>
<span id="cb7-7">[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>] <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">8.302705</span></span></code></pre></div></div>
<p>Following the original blog post, we benchmark the R, Rcpp, and Fortran versions.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb8-1"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(microbenchmark)</span>
<span id="cb8-2"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">microbenchmark</span>(</span>
<span id="cb8-3">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Rcpp =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">logmodc</span>(t, yinit, r, k, thetasd),</span>
<span id="cb8-4">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Fortran =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">.Fortran</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"logmodf"</span>, t, yinit, r, k, thetasd, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">vector</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"numeric"</span>, t)),</span>
<span id="cb8-5">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">R =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">logmodr</span>(t, yinit, r, k, thetasd),</span>
<span id="cb8-6">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">times =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span>L</span>
<span id="cb8-7">  )</span>
<span id="cb8-8">Unit<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> microseconds</span>
<span id="cb8-9">    expr    min      lq     mean  median      uq     max neval</span>
<span id="cb8-10">    Rcpp <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">13.235</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">14.6260</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">17.11903</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">15.5280</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">16.8100</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">86.612</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span></span>
<span id="cb8-11"> Fortran <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">21.950</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">22.8965</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">26.76053</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">23.8760</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">25.3160</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">72.528</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span></span>
<span id="cb8-12">       R <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">56.994</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">58.8775</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">67.25860</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">59.9085</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">62.3655</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">243.965</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span></span></code></pre></div></div>
<p>The original blog post (from 2017) observed a 19x speed up of the Rcpp version over the R version. Here we only get a 4x improvement presumably related to <a href="https://blog.revolutionanalytics.com/2017/02/preview-r-340.html">performance</a> <a href="https://blog.revolutionanalytics.com/2018/04/r-350.html">improvements</a> in R. Our Fortran version is 2.5x faster than the R version.</p>
<p>Again, following the original blog post (with a slight modification), we benchmark running multiple simulations.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb9-1"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> rseq <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">seq</span>(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.1</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.2</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">length.out =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>)</span>
<span id="cb9-2"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">microbenchmark</span>(</span>
<span id="cb9-3">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Rcpp =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">lapply</span>(rseq, <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(x) <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">logmodc</span>(t, yinit, x, k, thetasd)),</span>
<span id="cb9-4">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Fortran =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">lapply</span>(rseq, <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(x){</span>
<span id="cb9-5">      <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">.Fortran</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"logmodf"</span>, t, yinit, x, k, thetasd, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">vector</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"numeric"</span>, t))}),</span>
<span id="cb9-6">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">R =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">lapply</span>(rseq, <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(x) <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">logmodr</span>(t, yinit, x, k, thetasd)),</span>
<span id="cb9-7">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">times =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span>L)</span>
<span id="cb9-8"></span>
<span id="cb9-9">Unit<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> microseconds</span>
<span id="cb9-10">    expr     min       lq     mean   median       uq      max neval</span>
<span id="cb9-11">    Rcpp <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">159.578</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">166.4295</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">214.4782</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">198.2240</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">202.9475</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">8265.555</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span></span>
<span id="cb9-12"> Fortran <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">233.397</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">239.9620</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">264.1335</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">256.8515</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">262.1665</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2994.857</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span></span>
<span id="cb9-13">       R <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">621.029</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">635.1115</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">676.0114</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">665.7525</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">674.2735</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2952.635</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span></span></code></pre></div></div>
<p>The relative performance gains for multiple simulations are similar to the single simulation.</p>
</section>
<section id="conclusion" class="level3">
<h3 class="anchored" data-anchor-id="conclusion">Conclusion</h3>
<p>This post doesn’t make a resounding case for using Fortran over C++ for speeding up simulations in R. The C++ code is shorter and runs faster. My C++ avoidance has centered on the complexity of the language. Perhaps there is a simpler subset of C++ that would go a long way towards speeding up my R code. However, <a href="https://www.moreisdifferent.com/2015/07/16/why-physicsts-still-use-fortran/">this post</a> makes the case that Fortran is still easier to learn than C++ for physics simulations.</p>


</section>

 ]]></description>
  <category>Fortran</category>
  <category>R</category>
  <guid>https://www.travishinkelman.com/posts/stochastic-population-model-r-fortran.html</guid>
  <pubDate>Sun, 09 May 2021 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Analyzing gapminder dataset with base R and Scheme</title>
  <link>https://www.travishinkelman.com/posts/gapminder-base-r-scheme.html</link>
  <description><![CDATA[ 




<p>I keep my eye out for blog posts illustrating data analysis tasks in R that I can use to test the functionality of my <a href="https://github.com/hinkelman/chez-stats"><code>chez-stats</code></a> and <a href="https://github.com/hinkelman/dataframe/"><code>dataframe</code></a> libraries for Scheme (R6RS). A <a href="https://appsilon.com/pandas-vs-dplyr/">post</a> comparing <a href="https://pandas.pydata.org/"><code>pandas</code></a> (Python) and <a href="https://dplyr.tidyverse.org/"><code>dplyr</code></a> (R) in a basic analysis of the gapminder dataset provides a nice little test case. In this post, I will also include base R code used to accomplish the same tasks as a contrast to both the Scheme code and the <code>dplyr</code> code from the other post.</p>
<section id="data-loading" class="level2">
<h2 class="anchored" data-anchor-id="data-loading">Data Loading</h2>
<p>The R package, <a href="https://cran.r-project.org/web/packages/gapminder/"><code>gapminder</code></a>, provides an excerpt of the data available at <a href="https://www.gapminder.org/">Gapminder.org</a>. I’ve written the data from that package to a CSV file (<a href="../data/gapminder.csv">available here</a>).</p>
<p><em>Base R</em></p>
<p>I’ve added a little function, <code>head10</code>, to simplify subsequent code. It is not necessary. By default, <code>head</code> provides six rows. I’ve changed it to 10 to match the default for <code>dataframe-display</code>. The main thing to note here is that because we are using base R, we don’t need to load any packages.</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="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> gapminder <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">read.csv</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gapminder.csv"</span>)</span>
<span id="cb1-2"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> head10 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(data) <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head</span>(data, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>)</span>
<span id="cb1-3"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head10</span>(gapminder)</span>
<span id="cb1-4"></span>
<span id="cb1-5">   continent     country year lifeExp      pop gdpPercap</span>
<span id="cb1-6"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>       Asia Afghanistan <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1952</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">28.801</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8425333</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">779.4453</span></span>
<span id="cb1-7"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>       Asia Afghanistan <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1957</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">30.332</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9240934</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">820.8530</span></span>
<span id="cb1-8"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>       Asia Afghanistan <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1962</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">31.997</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10267083</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">853.1007</span></span>
<span id="cb1-9"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>       Asia Afghanistan <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1967</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">34.020</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11537966</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">836.1971</span></span>
<span id="cb1-10"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>       Asia Afghanistan <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1972</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">36.088</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">13079460</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">739.9811</span></span>
<span id="cb1-11"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>       Asia Afghanistan <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1977</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">38.438</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">14880372</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">786.1134</span></span>
<span id="cb1-12"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>       Asia Afghanistan <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1982</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">39.854</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12881816</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">978.0114</span></span>
<span id="cb1-13"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>       Asia Afghanistan <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1987</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">40.822</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">13867957</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">852.3959</span></span>
<span id="cb1-14"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>       Asia Afghanistan <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1992</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">41.674</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">16317921</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">649.3414</span></span>
<span id="cb1-15"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>      Asia Afghanistan <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1997</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">41.763</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">22227415</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">635.3414</span></span></code></pre></div></div>
<p><em>Scheme</em></p>
<p>We need to first import the <code>dataframe</code> library. Otherwise, the code is similar.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb2-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (import (dataframe))</span>
<span id="cb2-2"></span>
<span id="cb2-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> gapminder </span>(csv-&gt;dataframe <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gapminder.csv"</span>))</span>
<span id="cb2-4"></span>
<span id="cb2-5"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (dataframe-display gapminder)</span>
<span id="cb2-6"></span>
<span id="cb2-7"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1704</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> cols</span>
<span id="cb2-8">  continent      country    year  lifeExp       pop  gdpPercap </span>
<span id="cb2-9">      &lt;str&gt;        &lt;str&gt;   &lt;num&gt;    &lt;num&gt;     &lt;num&gt;      &lt;num&gt; </span>
<span id="cb2-10">       Asia  Afghanistan   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1952</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">28.8010</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">8.425</span>E+6   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">779.4453</span> </span>
<span id="cb2-11">       Asia  Afghanistan   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1957</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">30.3320</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">9.241</span>E+6   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">820.8530</span> </span>
<span id="cb2-12">       Asia  Afghanistan   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1962</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">31.9970</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.027</span>E+7   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">853.1007</span> </span>
<span id="cb2-13">       Asia  Afghanistan   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1967</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">34.0200</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.154</span>E+7   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">836.1971</span> </span>
<span id="cb2-14">       Asia  Afghanistan   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1972</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">36.0880</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.308</span>E+7   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">739.9811</span> </span>
<span id="cb2-15">       Asia  Afghanistan   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1977</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">38.4380</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.488</span>E+7   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">786.1134</span> </span>
<span id="cb2-16">       Asia  Afghanistan   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1982</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">39.8540</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.288</span>E+7   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">978.0114</span> </span>
<span id="cb2-17">       Asia  Afghanistan   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1987</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">40.8220</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.387</span>E+7   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">852.3959</span> </span>
<span id="cb2-18">       Asia  Afghanistan   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1992</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">41.6740</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.632</span>E+7   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">649.3414</span> </span>
<span id="cb2-19">       Asia  Afghanistan   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1997</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">41.7630</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.223</span>E+7   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">635.3414</span> </span></code></pre></div></div>
</section>
<section id="filtering" class="level2">
<h2 class="anchored" data-anchor-id="filtering">Filtering</h2>
<section id="problem-1" class="level3">
<h3 class="anchored" data-anchor-id="problem-1">Problem 1</h3>
<p>Filter the dataset to retain only rows where <code>year</code> is <code>2007</code>.</p>
<p><em>Base R</em></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="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head10</span>(gapminder[gapminder<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>year <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;">2007</span>, ])</span>
<span id="cb3-2"></span>
<span id="cb3-3">    continent     country year lifeExp       pop  gdpPercap</span>
<span id="cb3-4"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span>       Asia Afghanistan <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">43.828</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31889923</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">974.5803</span></span>
<span id="cb3-5"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">24</span>     Europe     Albania <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">76.423</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3600523</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">5937.0295</span></span>
<span id="cb3-6"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">36</span>     Africa     Algeria <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">72.301</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">33333216</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6223.3675</span></span>
<span id="cb3-7"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">48</span>     Africa      Angola <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">42.731</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12420476</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4797.2313</span></span>
<span id="cb3-8"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span>   Americas   Argentina <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">75.320</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">40301927</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">12779.3796</span></span>
<span id="cb3-9"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">72</span>    Oceania   Australia <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">81.235</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20434176</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">34435.3674</span></span>
<span id="cb3-10"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">84</span>     Europe     Austria <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">79.829</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8199783</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">36126.4927</span></span>
<span id="cb3-11"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">96</span>       Asia     Bahrain <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">75.635</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">708573</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">29796.0483</span></span>
<span id="cb3-12"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">108</span>      Asia  Bangladesh <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">64.062</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">150448339</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1391.2538</span></span>
<span id="cb3-13"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">120</span>    Europe     Belgium <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">79.441</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10392226</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">33692.6051</span></span></code></pre></div></div>
<p><em>Scheme</em></p>
<p>This example introduces the thread-first operator (<code>-&gt;</code>), which takes the result of the previous procedure and passes it to the first argument of the next procedure. For data analysis, I strongly prefer the threading (or piping) approach over writing the code inside-out or creating lots of intermediate datasets.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb4-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (-&gt; gapminder</span>
<span id="cb4-2">      (dataframe-filter* (year) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> year <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>))</span>
<span id="cb4-3">      dataframe-display)</span>
<span id="cb4-4"></span>
<span id="cb4-5"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">142</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> cols</span>
<span id="cb4-6">  continent      country    year  lifeExp       pop  gdpPercap </span>
<span id="cb4-7">      &lt;str&gt;        &lt;str&gt;   &lt;num&gt;    &lt;num&gt;     &lt;num&gt;      &lt;num&gt; </span>
<span id="cb4-8">       Asia  Afghanistan   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">43.8280</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.189</span>E+7   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">974.5803</span> </span>
<span id="cb4-9">     Europe      Albania   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">76.4230</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.601</span>E+6  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">5937.0295</span> </span>
<span id="cb4-10">     Africa      Algeria   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">72.3010</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.333</span>E+7  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6223.3675</span> </span>
<span id="cb4-11">     Africa       Angola   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">42.7310</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.242</span>E+7  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4797.2313</span> </span>
<span id="cb4-12">   Americas    Argentina   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">75.3200</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.030</span>E+7 <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">12779.3796</span> </span>
<span id="cb4-13">    Oceania    Australia   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">81.2350</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.043</span>E+7 <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">34435.3674</span> </span>
<span id="cb4-14">     Europe      Austria   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">79.8290</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">8.200</span>E+6 <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">36126.4927</span> </span>
<span id="cb4-15">       Asia      Bahrain   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">75.6350</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">7.086</span>E+5 <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">29796.0483</span> </span>
<span id="cb4-16">       Asia   Bangladesh   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">64.0620</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.504</span>E+8  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1391.2538</span> </span>
<span id="cb4-17">     Europe      Belgium   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">79.4410</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.039</span>E+7 <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">33692.6051</span> </span></code></pre></div></div>
</section>
<section id="problem-2" class="level3">
<h3 class="anchored" data-anchor-id="problem-2">Problem 2</h3>
<p>Filter the dataset to retain only rows where <code>year</code> is <code>2007</code> and <code>continent</code> is <code>Americas</code>.</p>
<p><em>Base R</em></p>
<p>In this case, I’ve used <code>subset</code> rather than the more conventional <code>[</code> subsetting used in Problem 1. The advantage of <code>subset</code> is that I only need to type <code>gapminder</code> once instead of three times.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb5-1"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head10</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">subset</span>(gapminder, year <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;">2007</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> continent <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;">"Americas"</span>))</span>
<span id="cb5-2"></span>
<span id="cb5-3">    continent            country year lifeExp       pop gdpPercap</span>
<span id="cb5-4"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span>   Americas          Argentina <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">75.320</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">40301927</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">12779.380</span></span>
<span id="cb5-5"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">144</span>  Americas            Bolivia <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">65.554</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9119152</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3822.137</span></span>
<span id="cb5-6"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">180</span>  Americas             Brazil <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">72.390</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">190010647</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">9065.801</span></span>
<span id="cb5-7"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">252</span>  Americas             Canada <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">80.653</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">33390141</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">36319.235</span></span>
<span id="cb5-8"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">288</span>  Americas              Chile <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">78.553</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">16284741</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">13171.639</span></span>
<span id="cb5-9"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">312</span>  Americas           Colombia <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">72.889</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">44227550</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">7006.580</span></span>
<span id="cb5-10"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">360</span>  Americas         Costa Rica <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">78.782</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4133884</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">9645.061</span></span>
<span id="cb5-11"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">396</span>  Americas               Cuba <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">78.273</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11416987</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">8948.103</span></span>
<span id="cb5-12"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">444</span>  Americas Dominican Republic <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">72.235</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9319622</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6025.375</span></span>
<span id="cb5-13"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">456</span>  Americas            Ecuador <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">74.994</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">13755680</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6873.262</span></span></code></pre></div></div>
<p><em>Scheme</em></p>
<p><code>dataframe-filter*</code> was designed to avoid having to repeat the dataframe name in each sub-expression, i.e., <code>(= year 2007)</code> and <code>(string=? continent "Americas")</code>, but requires typing <code>year</code> and <code>continent</code> two times each in this example.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb6-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (-&gt; gapminder</span>
<span id="cb6-2">      (dataframe-filter*</span>
<span id="cb6-3">       (year continent)</span>
<span id="cb6-4">       (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> year <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>)</span>
<span id="cb6-5">            (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> continent <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Americas"</span>)))</span>
<span id="cb6-6">      dataframe-display)</span>
<span id="cb6-7"></span>
<span id="cb6-8"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">25</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> cols</span>
<span id="cb6-9">  continent             country    year  lifeExp       pop  gdpPercap </span>
<span id="cb6-10">      &lt;str&gt;               &lt;str&gt;   &lt;num&gt;    &lt;num&gt;     &lt;num&gt;      &lt;num&gt; </span>
<span id="cb6-11">   Americas           Argentina   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">75.3200</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.030</span>E+7 <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">12779.3796</span> </span>
<span id="cb6-12">   Americas             Bolivia   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">65.5540</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">9.119</span>E+6  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3822.1371</span> </span>
<span id="cb6-13">   Americas              Brazil   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">72.3900</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.900</span>E+8  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">9065.8008</span> </span>
<span id="cb6-14">   Americas              Canada   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">80.6530</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.339</span>E+7 <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">36319.2350</span> </span>
<span id="cb6-15">   Americas               Chile   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">78.5530</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.628</span>E+7 <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">13171.6389</span> </span>
<span id="cb6-16">   Americas            Colombia   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">72.8890</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.423</span>E+7  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">7006.5804</span> </span>
<span id="cb6-17">   Americas          Costa Rica   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">78.7820</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.134</span>E+6  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">9645.0614</span> </span>
<span id="cb6-18">   Americas                Cuba   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">78.2730</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.142</span>E+7  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">8948.1029</span> </span>
<span id="cb6-19">   Americas  Dominican Republic   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">72.2350</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">9.320</span>E+6  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6025.3748</span> </span>
<span id="cb6-20">   Americas             Ecuador   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">74.9940</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.376</span>E+7  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6873.2623</span> </span></code></pre></div></div>
</section>
<section id="problem-3" class="level3">
<h3 class="anchored" data-anchor-id="problem-3">Problem 3</h3>
<p>Filter the dataset to retain only rows where <code>year</code> is <code>2007</code> and <code>continent</code> is <code>Americas</code> and <code>country</code> is <code>United States</code>. This last filter is a little silly because the <code>country</code> condition makes the <code>continent</code> condition unnecessary, but the point is to show how code complexity increases with additional conditions.</p>
<p><em>Base R</em></p>
<p>Thanks to <code>subset</code>, adding additional conditions is straightforward with zero redundancy.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb7-1"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">subset</span>(gapminder, </span>
<span id="cb7-2">         year <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;">2007</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> </span>
<span id="cb7-3">           continent <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;">"Americas"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span></span>
<span id="cb7-4">           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;">"United States"</span>)</span>
<span id="cb7-5"></span>
<span id="cb7-6">     continent       country year lifeExp       pop gdpPercap</span>
<span id="cb7-7"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1620</span>  Americas United States <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">78.242</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">301139947</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">42951.65</span></span></code></pre></div></div>
<p><em>Scheme</em></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb8-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (-&gt; gapminder</span>
<span id="cb8-2">      (dataframe-filter*</span>
<span id="cb8-3">       (year continent country)</span>
<span id="cb8-4">       (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> year <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>)</span>
<span id="cb8-5">            (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> continent <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Americas"</span>)</span>
<span id="cb8-6">            (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">string=?</span> country <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"United States"</span>)))</span>
<span id="cb8-7">      dataframe-display)</span>
<span id="cb8-8"></span>
<span id="cb8-9"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> cols</span>
<span id="cb8-10">  continent        country    year  lifeExp       pop  gdpPercap </span>
<span id="cb8-11">      &lt;str&gt;          &lt;str&gt;   &lt;num&gt;    &lt;num&gt;     &lt;num&gt;      &lt;num&gt; </span>
<span id="cb8-12">   Americas  United States   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">78.2420</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.011</span>E+8   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">42951.65</span> </span></code></pre></div></div>
</section>
</section>
<section id="summary-statistics" class="level2">
<h2 class="anchored" data-anchor-id="summary-statistics">Summary Statistics</h2>
<section id="problem-1-1" class="level3">
<h3 class="anchored" data-anchor-id="problem-1-1">Problem 1</h3>
<p>Calculate the average life expectancy worldwide in 2007.</p>
<p><em>Base R</em></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb9-1"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mean</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">subset</span>(gapminder, year <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;">2007</span>)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>lifeExp)</span>
<span id="cb9-2">[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>] <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">67.00742</span></span></code></pre></div></div>
<p><em>Scheme</em></p>
<p>This example introduces the <code>$</code> operator, which was inspired by R, to extract the values of a column (e.g., <code>lifeExp</code>). The difference in verbosity between base R and Scheme in this example is related to the filtering step. Extracting a column and calculating the mean involve nearly the same number of characters.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb10-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (-&gt; gapminder</span>
<span id="cb10-2">      (dataframe-filter* (year) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> year <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>))</span>
<span id="cb10-3">      (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> 'lifeExp)</span>
<span id="cb10-4">      (mean))</span>
<span id="cb10-5"></span>
<span id="cb10-6"><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">67.00742253521126</span>    </span></code></pre></div></div>
</section>
<section id="problem-2-1" class="level3">
<h3 class="anchored" data-anchor-id="problem-2-1">Problem 2</h3>
<p>Calculate the average life expectancy for every continent in 2007.</p>
<p><em>Base R</em></p>
<p><code>aggregate</code> allows for use of the formula syntax (e.g., <code>lifeExp ~ continent</code>) to concisely describe the summarized value (<code>lifeExp</code>) and grouping variable(s).</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb11-1"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aggregate</span>(lifeExp <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> continent, </span>
<span id="cb11-2">           <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">subset</span>(gapminder, year <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;">2007</span>),</span>
<span id="cb11-3">           <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">FUN =</span> mean)</span>
<span id="cb11-4"></span>
<span id="cb11-5">  continent  lifeExp</span>
<span id="cb11-6"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>    Africa <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">54.80604</span></span>
<span id="cb11-7"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>  Americas <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">73.60812</span></span>
<span id="cb11-8"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>      Asia <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">70.72848</span></span>
<span id="cb11-9"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>    Europe <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">77.64860</span></span>
<span id="cb11-10"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>   Oceania <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">80.71950</span></span></code></pre></div></div>
<p><em>Scheme</em></p>
<p>One difference to note here is that <code>dataframe-aggregate</code> doesn’t automatically sort by the grouping variable. We would have to explicitly add that sorting step.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb12-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (-&gt; gapminder</span>
<span id="cb12-2">      (dataframe-filter* (year) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> year <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>))</span>
<span id="cb12-3">      (dataframe-aggregate*</span>
<span id="cb12-4">       (continent)</span>
<span id="cb12-5">       (mean-lifeExp (lifeExp) (mean lifeExp)))</span>
<span id="cb12-6">      (dataframe-display))</span>
<span id="cb12-7"></span>
<span id="cb12-8"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> cols</span>
<span id="cb12-9">  continent  mean-lifeExp </span>
<span id="cb12-10">      &lt;str&gt;         &lt;num&gt; </span>
<span id="cb12-11">       Asia       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">70.7285</span> </span>
<span id="cb12-12">     Europe       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">77.6486</span> </span>
<span id="cb12-13">     Africa       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">54.8060</span> </span>
<span id="cb12-14">   Americas       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">73.6081</span> </span>
<span id="cb12-15">    Oceania       <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">80.7195</span> </span></code></pre></div></div>
</section>
<section id="problem-3-1" class="level3">
<h3 class="anchored" data-anchor-id="problem-3-1">Problem 3</h3>
<p>Calculate the total population per continent in 2007 and sort the results in descending order of total population.</p>
<p><em>Base R</em></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb13-1"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> total_pop <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aggregate</span>(pop <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> continent, </span>
<span id="cb13-2">                        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">subset</span>(gapminder, year <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;">2007</span>),</span>
<span id="cb13-3">                        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">FUN =</span> sum)</span>
<span id="cb13-4"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> total_pop[<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">order</span>(<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>total_pop<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>pop),]</span>
<span id="cb13-5"></span>
<span id="cb13-6">  continent        pop</span>
<span id="cb13-7"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>      Asia <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3811953827</span></span>
<span id="cb13-8"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>    Africa  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">929539692</span></span>
<span id="cb13-9"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>  Americas  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">898871184</span></span>
<span id="cb13-10"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>    Europe  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">586098529</span></span>
<span id="cb13-11"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>   Oceania   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">24549947</span></span></code></pre></div></div>
<p><em>Scheme</em></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb14-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (-&gt; gapminder</span>
<span id="cb14-2">      (dataframe-filter* (year) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> year <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>))</span>
<span id="cb14-3">      (dataframe-aggregate*</span>
<span id="cb14-4">       (continent)</span>
<span id="cb14-5">       (total-pop (pop) (sum pop)))</span>
<span id="cb14-6">      (dataframe-sort* (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> total-pop))</span>
<span id="cb14-7">      (dataframe-display))</span>
<span id="cb14-8"></span>
<span id="cb14-9"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> cols</span>
<span id="cb14-10">  continent  total-pop </span>
<span id="cb14-11">      &lt;str&gt;      &lt;num&gt; </span>
<span id="cb14-12">       Asia   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.812</span>E+9 </span>
<span id="cb14-13">     Africa   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">9.295</span>E+8 </span>
<span id="cb14-14">   Americas   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">8.989</span>E+8 </span>
<span id="cb14-15">     Europe   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">5.861</span>E+8 </span>
<span id="cb14-16">    Oceania   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.455</span>E+7 </span></code></pre></div></div>
</section>
</section>
<section id="creating-derived-columns" class="level2">
<h2 class="anchored" data-anchor-id="creating-derived-columns">Creating Derived Columns</h2>
<section id="problem-1-2" class="level3">
<h3 class="anchored" data-anchor-id="problem-1-2">Problem 1</h3>
<p>Calculate the total GDP by multiplying <code>pop</code> and <code>gdpPercap</code>.</p>
<p><em>Base R</em></p>
<p>The help page for <code>transform</code> advises that it is only intended for interactive use. Alternatively, you could use: <code>gapminder$GPD = gapminder$pop * gapminder$gdpPercap</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb15-1"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head10</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">transform</span>(gapminder, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">GDP =</span> pop <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> gdpPercap))</span>
<span id="cb15-2"></span>
<span id="cb15-3">   continent     country year lifeExp      pop gdpPercap         GDP</span>
<span id="cb15-4"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>       Asia Afghanistan <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1952</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">28.801</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8425333</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">779.4453</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6567086330</span></span>
<span id="cb15-5"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>       Asia Afghanistan <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1957</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">30.332</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9240934</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">820.8530</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7585448670</span></span>
<span id="cb15-6"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>       Asia Afghanistan <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1962</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">31.997</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10267083</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">853.1007</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8758855797</span></span>
<span id="cb15-7"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>       Asia Afghanistan <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1967</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">34.020</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11537966</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">836.1971</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9648014150</span></span>
<span id="cb15-8"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>       Asia Afghanistan <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1972</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">36.088</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">13079460</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">739.9811</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9678553274</span></span>
<span id="cb15-9"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>       Asia Afghanistan <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1977</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">38.438</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">14880372</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">786.1134</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11697659231</span></span>
<span id="cb15-10"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>       Asia Afghanistan <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1982</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">39.854</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12881816</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">978.0114</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12598563401</span></span>
<span id="cb15-11"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>       Asia Afghanistan <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1987</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">40.822</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">13867957</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">852.3959</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11820990309</span></span>
<span id="cb15-12"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>       Asia Afghanistan <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1992</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">41.674</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">16317921</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">649.3414</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10595901589</span></span>
<span id="cb15-13"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>      Asia Afghanistan <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1997</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">41.763</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">22227415</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">635.3414</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">14121995875</span></span></code></pre></div></div>
<p><em>Scheme</em></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb16-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (-&gt; gapminder</span>
<span id="cb16-2">      (dataframe-modify*</span>
<span id="cb16-3">       (GDP (pop gdpPercap) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> pop gdpPercap)))</span>
<span id="cb16-4">      (dataframe-display))</span>
<span id="cb16-5"></span>
<span id="cb16-6"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1704</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span> cols</span>
<span id="cb16-7">  continent      country    year  lifeExp       pop  gdpPercap        GDP </span>
<span id="cb16-8">      &lt;str&gt;        &lt;str&gt;   &lt;num&gt;    &lt;num&gt;     &lt;num&gt;      &lt;num&gt;      &lt;num&gt; </span>
<span id="cb16-9">       Asia  Afghanistan   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1952</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">28.8010</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">8.425</span>E+6   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">779.4453</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6.567</span>E+09 </span>
<span id="cb16-10">       Asia  Afghanistan   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1957</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">30.3320</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">9.241</span>E+6   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">820.8530</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">7.585</span>E+09 </span>
<span id="cb16-11">       Asia  Afghanistan   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1962</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">31.9970</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.027</span>E+7   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">853.1007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">8.759</span>E+09 </span>
<span id="cb16-12">       Asia  Afghanistan   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1967</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">34.0200</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.154</span>E+7   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">836.1971</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">9.648</span>E+09 </span>
<span id="cb16-13">       Asia  Afghanistan   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1972</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">36.0880</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.308</span>E+7   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">739.9811</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">9.679</span>E+09 </span>
<span id="cb16-14">       Asia  Afghanistan   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1977</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">38.4380</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.488</span>E+7   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">786.1134</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.170</span>E+10 </span>
<span id="cb16-15">       Asia  Afghanistan   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1982</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">39.8540</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.288</span>E+7   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">978.0114</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.260</span>E+10 </span>
<span id="cb16-16">       Asia  Afghanistan   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1987</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">40.8220</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.387</span>E+7   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">852.3959</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.182</span>E+10 </span>
<span id="cb16-17">       Asia  Afghanistan   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1992</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">41.6740</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.632</span>E+7   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">649.3414</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.060</span>E+10 </span>
<span id="cb16-18">       Asia  Afghanistan   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1997</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">41.7630</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.223</span>E+7   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">635.3414</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.412</span>E+10 </span></code></pre></div></div>
</section>
<section id="problem-2-2" class="level3">
<h3 class="anchored" data-anchor-id="problem-2-2">Problem 2</h3>
<p>Find the top 10 countries in percentile of <code>gdpPercap</code>.</p>
<p><em>Base R</em></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb17-1"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> percentile <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(x){</span>
<span id="cb17-2">    rank_x <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rank</span>(x)</span>
<span id="cb17-3">    rank_x<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">max</span>(rank_x)</span>
<span id="cb17-4">  }</span>
<span id="cb17-5"></span>
<span id="cb17-6"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> gapminder2007 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">transform</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">subset</span>(gapminder, year <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;">2007</span>),</span>
<span id="cb17-7">                            <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">percentile =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">percentile</span>(gdpPercap))</span>
<span id="cb17-8"><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head10</span>(gapminder2007[<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">order</span>(<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>gapminder2007<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>percentile),])</span>
<span id="cb17-9"></span>
<span id="cb17-10">     continent          country year lifeExp       pop gdpPercap percentile</span>
<span id="cb17-11"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1152</span>    Europe           Norway <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">80.196</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4627926</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">49357.19</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.0000000</span></span>
<span id="cb17-12"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">864</span>       Asia           Kuwait <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">77.588</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2505559</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">47306.99</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9929577</span></span>
<span id="cb17-13"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1368</span>      Asia        Singapore <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">79.972</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4553009</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">47143.18</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9859155</span></span>
<span id="cb17-14"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1620</span>  Americas    United States <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">78.242</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">301139947</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">42951.65</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9788732</span></span>
<span id="cb17-15"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">756</span>     Europe          Ireland <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">78.885</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4109086</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">40676.00</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9718310</span></span>
<span id="cb17-16"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">672</span>       Asia Hong Kong, China <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">82.208</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6980412</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">39724.98</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9647887</span></span>
<span id="cb17-17"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1488</span>    Europe      Switzerland <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">81.701</span>   <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7554661</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">37506.42</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9577465</span></span>
<span id="cb17-18"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1092</span>    Europe      Netherlands <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">79.762</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">16570613</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">36797.93</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9507042</span></span>
<span id="cb17-19"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">252</span>   Americas           Canada <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">80.653</span>  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">33390141</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">36319.24</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9436620</span></span>
<span id="cb17-20"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">696</span>     Europe          Iceland <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">81.757</span>    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">301931</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">36180.79</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9366197</span></span></code></pre></div></div>
<p><em>Scheme</em></p>
<p>This example reveals a weak spot in the <code>dataframe</code> API. The issue is that <code>rank%</code> operates on a <code>list</code> whereas <code>dataframe-modify*</code> takes only scalars as inputs because the <code>expr</code> is mapped over all rows in a <code>dataframe</code>. The workaround to avoid the mapping is to specify that no columns (i.e., <code>()</code>) from the dataframe are used, then the list created in the subsequent expression (e.g., <code>(rank% ($ df 'gdpPercap))</code>) will be used as the column values.</p>
<p>Because the <code>dataframe</code> library only has thread-first (<code>-&gt;</code>) and thread-last (<code>-&gt;&gt;</code>) operators, we have to create the awkward <code>lambda</code> procedure to get the output of <code>dataframe-filter*</code> to the right place in <code>dataframe-modify*</code>. <a href="https://srfi.schemers.org/srfi-197/srfi-197.html">SRFI 197</a> provides a pipeline operator that requires that the location of the output of the previous procedure is explicitly specified with <code>_</code>, which would likely simplify this code. An earlier, simpler version of SRFI 197 was the source for <code>-&gt;</code> and <code>-&gt;&gt;</code> in the <code>dataframe</code> library.</p>
<p>We import only the <code>rank</code> procedure from <code>chez-stats</code> because there are name conflicts between <code>chez-stats</code> and <code>dataframe</code>. The conflicting procedures (e.g., <code>mean</code>, <code>median</code>, <code>sum</code>, etc.) in <code>dataframe</code> provide handling of missing values.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb18-1">(import (only (chez-stats) rank))</span>
<span id="cb18-2"></span>
<span id="cb18-3">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rank% </span>lst)</span>
<span id="cb18-4">  (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let*</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>rank-lst (rank lst 'mean)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb18-5">         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>max-rank (apply <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">max</span> rank-lst)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb18-6">    (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (x) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">inexact</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> x max-rank))) rank-lst)))</span>
<span id="cb18-7"></span>
<span id="cb18-8"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (-&gt; gapminder</span>
<span id="cb18-9">      (dataframe-filter* (year) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> year <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>))</span>
<span id="cb18-10">      (-&gt;&gt; ((<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (df)</span>
<span id="cb18-11">              (dataframe-modify*</span>
<span id="cb18-12">               df</span>
<span id="cb18-13">               (percentile () (rank% (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> df 'gdpPercap)))))))</span>
<span id="cb18-14">      (dataframe-sort* (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> gdpPercap))</span>
<span id="cb18-15">      (dataframe-display))</span>
<span id="cb18-16"></span>
<span id="cb18-17"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">142</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span> cols</span>
<span id="cb18-18">  continent           country   year  lifeExp       pop  gdpPercap  percentile </span>
<span id="cb18-19">     Europe            Norway  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">80.1960</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.628</span>E+6   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">49357.19</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.0000</span> </span>
<span id="cb18-20">       Asia            Kuwait  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">77.5880</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.506</span>E+6   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">47306.99</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9930</span> </span>
<span id="cb18-21">       Asia         Singapore  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">79.9720</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.553</span>E+6   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">47143.18</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9859</span> </span>
<span id="cb18-22">   Americas     United States  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">78.2420</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.011</span>E+8   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">42951.65</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9789</span> </span>
<span id="cb18-23">     Europe           Ireland  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">78.8850</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.109</span>E+6   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">40676.00</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9718</span> </span>
<span id="cb18-24">       Asia  Hong Kong, China  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">82.2080</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6.980</span>E+6   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">39724.98</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9648</span> </span>
<span id="cb18-25">     Europe       Switzerland  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">81.7010</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">7.555</span>E+6   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">37506.42</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9577</span> </span>
<span id="cb18-26">     Europe       Netherlands  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">79.7620</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.657</span>E+7   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">36797.93</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9507</span> </span>
<span id="cb18-27">   Americas            Canada  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">80.6530</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.339</span>E+7   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">36319.24</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9437</span> </span>
<span id="cb18-28">     Europe           Iceland  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>.  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">81.7570</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.019</span>E+5   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">36180.79</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9366</span> </span></code></pre></div></div>
<p>If we create an intermediate <code>dataframe</code>, we get simpler code.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb19-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> gapminder2007</span></span>
<span id="cb19-2">  (dataframe-filter* gapminder (year) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> year <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2007</span>)))</span>
<span id="cb19-3"></span>
<span id="cb19-4">(-&gt; (dataframe-modify*</span>
<span id="cb19-5">     gapminder2007</span>
<span id="cb19-6">     (percentile () (rank% (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> gapminder2007 'gdpPercap))))</span>
<span id="cb19-7">    (dataframe-sort* (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> gdpPercap))</span>
<span id="cb19-8">    (dataframe-display))</span></code></pre></div></div>
</section>
</section>
<section id="conclusion" class="level2">
<h2 class="anchored" data-anchor-id="conclusion">Conclusion</h2>
<p>The main outcome of writing this post was that it led me to completely rewrite <code>dataframe-display</code> because it previously didn’t handle large numbers well, which was made abundantly clear in working with the <code>gapminder</code> data. The new version of <code>dataframe-display</code> is much improved and I gained a greater appreciation for all of the decisions that go into how to print a representation of a data structure to the screen.</p>
<p>If you are not familiar with Scheme code, you might find it to be unacceptably verbose in the examples above and, especially, when compared to <code>dplyr</code> code. Because of Scheme’s macro system, <code>dataframe</code> could be written in a more terse style. But I made the decision early on to stick to relatively simple macro usage and write <code>dataframe</code> in a way that I thought would be familiar to Scheme programmers. And that often involves more verbose code. For example, nearly all of the <code>dataframe</code> procedures have <code>dataframe</code> in the name, e.g., <code>dataframe-filter*</code>*, <code>dataframe-modify*</code>, etc. This is following the example for hashtables, e.g., <code>hashtable-ref</code>, <code>hashtable-values</code>, etc. I also hope that experienced Scheme programmers can see that the <code>dataframe</code> macros mostly exist to reduce the number of times that <code>lambda</code> is written but the shape of the code should still feel familiar. While Scheme code might be more verbose in the small, I find it extremely expressive in the large because the core ideas compose so well.</p>


</section>

 ]]></description>
  <category>Scheme</category>
  <category>dataframe</category>
  <category>R</category>
  <guid>https://www.travishinkelman.com/posts/gapminder-base-r-scheme.html</guid>
  <pubDate>Fri, 30 Apr 2021 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Guess the number game in Fortran</title>
  <link>https://www.travishinkelman.com/posts/guess-number-fortran.html</link>
  <description><![CDATA[ 




<p>I recently came across <a href="https://opensource.com/article/21/4/compare-programming-languages">this blog post</a> on writing simple test programs in different programming languages as a way to get a feel for a language. At the bottom of the post, there were links to articles on implementations of a number guessing game in 13 different languages, <a href="https://opensource.com/article/21/1/fortran">including Fortran</a>. I was curious about the Fortran example because I’ve been interested in learning a little Fortran after hearing about efforts to improve the tooling around Fortran (e.g., <a href="https://ondrejcertik.com/blog/2021/03/resurrecting-fortran/">here</a> and <a href="https://youtu.be/JUHS-JFvs90">here</a>). Well, the Fortran example was written in Fortran 77 so I decided that re-writing it in modern Fortran would be a nice little exercise.</p>
<p>I’m not going to write about the Fortran 77 version. It is well described in the <a href="https://opensource.com/article/21/1/fortran">other article</a>. Before I show the code for the “modern” version, I will introduce a couple of subroutines that I plucked from <a href="https://masuday.github.io/fortran_tutorial/random.html">this random number tutorial</a>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode fortran code-with-copy"><code class="sourceCode fortranfixed"><span id="cb1-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">subroutine</span> random_stduniform(u)</span>
<span id="cb1-2">   <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">implicit</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">none</span></span>
<span id="cb1-3">   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">real</span>,<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">intent(out)</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">::</span> u</span>
<span id="cb1-4">   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">real</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">::</span> r</span>
<span id="cb1-5">   <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">call</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">random_number</span>(r)</span>
<span id="cb1-6">   u <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">-</span> r</span>
<span id="cb1-7"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end subroutine</span> random_stduniform</span>
<span id="cb1-8"></span>
<span id="cb1-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">! assuming a&lt;b</span></span>
<span id="cb1-10"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">subroutine</span> random_uniform(a,b,x)</span>
<span id="cb1-11">   <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">implicit</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">none</span></span>
<span id="cb1-12">   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">real</span>,<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">intent(in)</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">::</span> a,b</span>
<span id="cb1-13">   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">real</span>,<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">intent(out)</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">::</span> x</span>
<span id="cb1-14">   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">real</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">::</span> u</span>
<span id="cb1-15">   <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">call</span> random_stduniform(u)</span>
<span id="cb1-16">   x <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> (b <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">-</span> a) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">*</span> u <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">+</span> a</span>
<span id="cb1-17"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end subroutine</span> random_uniform</span></code></pre></div></div>
<p>The first thing to note is that Fortran has both subroutines and functions. I have only a fuzzy understanding of when you would choose one over the other. In this case, it seems that <code>random_stduniform</code> and <code>random_uniform</code> could have also been written as functions (but I didn’t try). Perhaps the fact that <code>random_number</code> is a subroutine makes it more intuitive to build subroutines on top of it. When calling a subroutine, you need to preface the statement with <code>call</code>, which is not required for functions. Also, in a subroutine, assignment is handled by passing the variable name as an argument. For example, in <code>random_stduniform</code>, the variable <code>r</code> is declared with type <code>real</code> and then assigned a value when passed to the <code>random_normal</code> subroutine.</p>
<p>One of the other unusual (to me) components of these subroutines is <code>implicit none</code>, which means that the types of variables need to be explicitly declared and not implicitly inferred from the variable names. Here is an <a href="https://medium.com/modern-fortran/implicit-none-and-carry-on-860a1a0f143b">argument</a> for embracing <code>implicit none</code> rather than seeking to change it in a future version of the Fortran Standard.</p>
<p>Armed with those two sub-routines, here is the full program for the number guessing game:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode fortran code-with-copy"><code class="sourceCode fortranfixed"><span id="cb2-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">program</span> guessnum</span>
<span id="cb2-2">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">implicit</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">none</span></span>
<span id="cb2-3"></span>
<span id="cb2-4">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">real</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">::</span> number</span>
<span id="cb2-5">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">integer</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">::</span> number_int, guess</span>
<span id="cb2-6"></span>
<span id="cb2-7">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">call</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">random_seed</span>()</span>
<span id="cb2-8">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">call</span> random_uniform(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.999</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">100.0</span>, number)</span>
<span id="cb2-9">  number_int <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>(number)</span>
<span id="cb2-10">  guess <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span></span>
<span id="cb2-11"></span>
<span id="cb2-12">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">print</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">*</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Guess a number between 1 and 100"</span></span>
<span id="cb2-13"></span>
<span id="cb2-14">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">while</span> (guess <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/=</span> number_int) </span>
<span id="cb2-15">      <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">read</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">*</span>, guess</span>
<span id="cb2-16">      <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (guess <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> number_int) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">then</span></span>
<span id="cb2-17">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">print</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">*</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"too low"</span></span>
<span id="cb2-18">      <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else if</span> (guess <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> number_int) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">then</span></span>
<span id="cb2-19">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">print</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">*</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"too high"</span></span>
<span id="cb2-20">      <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end if</span></span>
<span id="cb2-21">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end do</span> </span>
<span id="cb2-22"></span>
<span id="cb2-23">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">print</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">*</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"correct!"</span></span>
<span id="cb2-24"> </span>
<span id="cb2-25"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end program</span> guessnum</span></code></pre></div></div>
<p>After declaring the types of our variables, we set a random seed and generate a number from a random uniform distribution that is &gt; 0.999 and &lt;= 100. <code>random_uniform</code> assigns a real number to the variable <code>number</code> so we coerce it to an integer with <code>int</code>, which has the same effect as <code>floor</code> or <code>truncate</code> operators in other languages. <code>guess</code> is initialized at zero to get us into our <code>while</code> loop because <code>number_int</code> should never be equal to zero in this program.</p>
<p>We print the guessing instructions, enter the <code>while</code> loop, and read the input from the user. Then, we compare the user’s <code>guess</code> to <code>number_int</code>, give feedback, and read their next guess. When <code>guess</code> matches <code>number_int</code>, we break out of the <code>while</code> loop and print <code>correct!</code> before exiting the program.</p>
<p>If you have the GNU Fortran compiler installed, and the code above in a file called <code>guess.f90</code>, you can compile the program with <code>gfortran guess.f90 -o guess</code> and run the program with <code>./guess</code>. Here is example output from running the program:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb3-1"> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Guess</span> a number between 1 and 100</span>
<span id="cb3-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">50</span></span>
<span id="cb3-3"> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">too</span> high</span>
<span id="cb3-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">25</span></span>
<span id="cb3-5"> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">too</span> low</span>
<span id="cb3-6"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">37</span></span>
<span id="cb3-7"> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">too</span> low</span>
<span id="cb3-8"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">43</span></span>
<span id="cb3-9"> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">too</span> high</span>
<span id="cb3-10"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">40</span></span>
<span id="cb3-11"> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">too</span> high</span>
<span id="cb3-12"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">39</span></span>
<span id="cb3-13"> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">too</span> high</span>
<span id="cb3-14"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">38</span></span>
<span id="cb3-15"> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">correct!</span></span></code></pre></div></div>
<p>That was a fun first experience with Fortran. I’m happy to trade some verbosity for simplicity. I think the Fortran example is a lot easier to understand than the <a href="https://opensource.com/article/20/12/learn-rust">Rust example</a>. Despite working for many years as a scientific programmer (but never officially my job title), I had never considered learning Fortran. I assumed it was an ugly relict hanging on in legacy codebases, but I no longer think it is ugly and it even moved back into the top 20 of the <a href="https://www.tiobe.com/tiobe-index/">Tiobe index</a>.</p>



 ]]></description>
  <guid>https://www.travishinkelman.com/posts/guess-number-fortran.html</guid>
  <pubDate>Wed, 07 Apr 2021 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Spam simulation in Scheme</title>
  <link>https://www.travishinkelman.com/posts/spam-simulation-scheme.html</link>
  <description><![CDATA[ 




<p>I learned a lot about Scheme (R6RS) by writing a few libraries and I expect that there is more to learn by trying to use those libraries (e.g., <a href="../posts/eda-scheme/">EDA in Scheme</a>). A <a href="http://varianceexplained.org/r/spam-simulation/">blog post</a> about a stochastic simulation of spam comments in R caught my eye as an interesting example to test my <a href="https://github.com/hinkelman/dataframe/"><code>dataframe</code></a> library.</p>
<p>I was drawn to the spam simulation post because it describes using the <code>crossing</code> function from the <a href="https://tidyr.tidyverse.org/"><code>tidyr</code> package</a> as a convenient way to examine the parameter space of a simulation under the familar framework of a dataframe, which is an approach that I’ve used in my own work. One of the challenges for me in learning new programming languages is that my R experience has led me to primarily think in terms of dataframes.</p>
<p>The takeaway from implementing the spam simulation in Scheme is that my <code>dataframe</code> library is not well suited to this task. That is not entirely surprising. <code>dataframe</code> was written for ease of implementation, not performance. More importantly, for a simple simulation like this, plain Scheme code provides a more straightforward solution than the <code>dataframe</code> approach.</p>
<p>In this post, I will focus on explaining the Scheme code rather than describing the simulation. In short, the idea is that you can build up your intuition about a problem with simulations, which might eventually lead you to a more concise mathematical solution to the problem. The objective is to determine the number of spam comments after three days given that spammers follow a Poisson process.</p>
<section id="dataframe-approach" class="level3">
<h3 class="anchored" data-anchor-id="dataframe-approach">Dataframe approach</h3>
<p>First, let’s import the <code>dataframe</code> library and a couple of procedures from the <a href="https://github.com/hinkelman/chez-stats/"><code>chez-stats</code></a> library (after following installation instructions at the library repos). We import only the specific procedures from <code>chez-stats</code> because there are name conflicts between <code>chez-stats</code> and <code>dataframe</code>. The conflicting procedures (e.g., <code>mean</code>, <code>median</code>, <code>sum</code>, etc.) in <code>dataframe</code> provide handling of missing values.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb1-1">(import (dataframe)</span>
<span id="cb1-2">        (only (chez-stats)</span>
<span id="cb1-3">              random-exponential</span>
<span id="cb1-4">              repeat))</span></code></pre></div></div>
<p><code>dataframe-crossing</code> takes either dataframes or series and returns the cartesian product of the objects. The original post used 25,000 trials. We are only using 100 trials because the <a href="https://github.com/hinkelman/dataframe/issues/5">performance of dataframe-split (see below) is poor with large numbers of groups</a>. We are using the <code>-&gt;</code> operator to build up a chain of operations in a more readable way.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb2-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> sim-waiting</span></span>
<span id="cb2-2">  (-&gt; (dataframe-crossing (make-series 'trial (map add1 (iota <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>)))</span>
<span id="cb2-3">                          (make-series 'observation (map add1 (iota <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">300</span>))))))</span>
<span id="cb2-4"></span>
<span id="cb2-5"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (dataframe-display sim-waiting)</span>
<span id="cb2-6"></span>
<span id="cb2-7"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30000</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> cols</span>
<span id="cb2-8">   trial  observation </span>
<span id="cb2-9">   &lt;num&gt;        &lt;num&gt; </span>
<span id="cb2-10">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>. </span>
<span id="cb2-11">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>. </span>
<span id="cb2-12">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>. </span>
<span id="cb2-13">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>. </span>
<span id="cb2-14">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>. </span>
<span id="cb2-15">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>. </span>
<span id="cb2-16">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>. </span>
<span id="cb2-17">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>. </span>
<span id="cb2-18">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>. </span>
<span id="cb2-19">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.          <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>. </span></code></pre></div></div>
<p>We continue to build up the <code>sim-waiting</code> dataframe by adding a column with waiting times by drawing from an exponential distribution with the observation as the rate parameter (used by <code>rexp</code> in R). However, <code>random-exponential</code> from <code>chez-stats</code> takes the mean of the distribution as the parameter, which is equal to <code>1/rate</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb3-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> sim-waiting</span></span>
<span id="cb3-2">  (-&gt; (dataframe-crossing (make-series 'trial (map add1 (iota <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>)))</span>
<span id="cb3-3">                          (make-series 'observation (map add1 (iota <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">300</span>))))</span>
<span id="cb3-4">      (dataframe-modify*</span>
<span id="cb3-5">       (waiting (observation) (random-exponential (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> observation))))))</span>
<span id="cb3-6"></span>
<span id="cb3-7"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (dataframe-display sim-waiting)</span>
<span id="cb3-8"></span>
<span id="cb3-9"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30000</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> cols</span>
<span id="cb3-10">   trial  observation  waiting </span>
<span id="cb3-11">   &lt;num&gt;        &lt;num&gt;    &lt;num&gt; </span>
<span id="cb3-12">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.4662</span> </span>
<span id="cb3-13">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0535</span> </span>
<span id="cb3-14">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3442</span> </span>
<span id="cb3-15">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3174</span> </span>
<span id="cb3-16">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.8945</span> </span>
<span id="cb3-17">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1303</span> </span>
<span id="cb3-18">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0622</span> </span>
<span id="cb3-19">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1867</span> </span>
<span id="cb3-20">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1254</span> </span>
<span id="cb3-21">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.          <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0213</span> </span></code></pre></div></div>
<p>The next step uses the <code>split-apply-combine</code> strategy to return the cumulative sum of the <code>waiting</code> column for each <code>trial</code>. <code>-&gt;</code> pipes into the first argument of the next procedure whereas <code>-&gt;&gt;</code> pipes into the last. In the apply step, we add a new column for each dataframe that came out of <code>dataframe-split</code> with <code>(cumulative () (cumulative-sum ($ df 'waiting)))</code>. If a <code>dataframe-modify*</code> contains a list of the same length as the number of rows in the dataframe, then it is added to the dataframe as a column with the specified name, which is <code>cumulative</code> in this example.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb4-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> sim-waiting</span></span>
<span id="cb4-2">  (-&gt; (dataframe-crossing (make-series 'trial (map add1 (iota <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>)))</span>
<span id="cb4-3">                          (make-series 'observation (map add1 (iota <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">300</span>))))</span>
<span id="cb4-4">      (dataframe-modify*</span>
<span id="cb4-5">       (waiting (observation) (random-exponential (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> observation))))</span>
<span id="cb4-6">      (dataframe-split 'trial)</span>
<span id="cb4-7">      (-&gt;&gt; (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (df)</span>
<span id="cb4-8">              (dataframe-modify*</span>
<span id="cb4-9">               df</span>
<span id="cb4-10">           (cumulative () (cumulative-sum (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span> df 'waiting)))))))</span>
<span id="cb4-11">      (dataframe-bind-all)))</span>
<span id="cb4-12"></span>
<span id="cb4-13"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (dataframe-display sim-waiting)</span>
<span id="cb4-14"></span>
<span id="cb4-15"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30000</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> cols</span>
<span id="cb4-16">   trial  observation  waiting  cumulative </span>
<span id="cb4-17">   &lt;num&gt;        &lt;num&gt;    &lt;num&gt;       &lt;num&gt; </span>
<span id="cb4-18">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.8186</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.8186</span> </span>
<span id="cb4-19">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5609</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.3795</span> </span>
<span id="cb4-20">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.2155</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.5950</span> </span>
<span id="cb4-21">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1990</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.7940</span> </span>
<span id="cb4-22">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.2132</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.0072</span> </span>
<span id="cb4-23">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0494</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.0566</span> </span>
<span id="cb4-24">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1209</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.1775</span> </span>
<span id="cb4-25">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0454</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.2230</span> </span>
<span id="cb4-26">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.           <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0384</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.2614</span> </span>
<span id="cb4-27">      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>.          <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>.   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0183</span>      <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.2797</span> </span></code></pre></div></div>
<p>We cross <code>sim-waiting</code> with a new <code>time</code> column to find the number of spam comments within each <code>trial</code> and <code>time</code> combination. The <code>cumulative</code> column gives the total time that has elapsed. We are counting the number of rows where <code>cumulative</code> is less than <code>time</code> to determine the number of comments received in a specified <code>time</code>. The last step is to calculate the average number of spam comments for each time across all trials.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb5-1">(<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> average-over-time</span></span>
<span id="cb5-2">  (-&gt; sim-waiting</span>
<span id="cb5-3">      (dataframe-crossing (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cons</span> 'time (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (x) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> x <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.25</span>)) (iota <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">13</span>))))</span>
<span id="cb5-4">      (dataframe-modify*</span>
<span id="cb5-5">       (comment (cumulative time) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> cumulative time)))</span>
<span id="cb5-6">      (dataframe-aggregate*</span>
<span id="cb5-7">       (trial time)</span>
<span id="cb5-8">       (num-comments (comment) (sum comment)))</span>
<span id="cb5-9">      (dataframe-aggregate*</span>
<span id="cb5-10">       (time)</span>
<span id="cb5-11">       (average (num-comments) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">exact-&gt;inexact</span> (mean num-comments))))))</span>
<span id="cb5-12"></span>
<span id="cb5-13"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (dataframe-display average-over-time <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">13</span>)</span>
<span id="cb5-14"></span>
<span id="cb5-15"> dim: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">13</span> rows x <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> cols</span>
<span id="cb5-16">    time  average </span>
<span id="cb5-17">   &lt;num&gt;    &lt;num&gt; </span>
<span id="cb5-18">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0000</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0000</span> </span>
<span id="cb5-19">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.2500</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1400</span> </span>
<span id="cb5-20">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5000</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3900</span> </span>
<span id="cb5-21">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.7500</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.8100</span> </span>
<span id="cb5-22">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.0000</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.3000</span> </span>
<span id="cb5-23">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.2500</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.1100</span> </span>
<span id="cb5-24">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.5000</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.9000</span> </span>
<span id="cb5-25">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.7500</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.8700</span> </span>
<span id="cb5-26">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.0000</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">5.4000</span> </span>
<span id="cb5-27">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.2500</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">7.3600</span> </span>
<span id="cb5-28">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.5000</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">9.5500</span> </span>
<span id="cb5-29">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.7500</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">12.1200</span> </span>
<span id="cb5-30">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.0000</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">16.0000</span> </span></code></pre></div></div>
</section>
<section id="idiomatic-scheme-approach" class="level3 page-columns page-full">
<h3 class="anchored" data-anchor-id="idiomatic-scheme-approach">Idiomatic Scheme approach</h3>
<div class="page-columns page-full"><p>As I mentioned above, the <code>dataframe</code> approach is inefficient and more verbose than an idiomatic Scheme approach. One source of inefficiency  is generating 300 observations per trial when the average for three days is only 19. This inefficiency is not expensive in R because it is well optimized for these types of vectorized operations. However, in Scheme, we can write a simple recursive function that doesn’t bother to build up a list of all of the waiting times and stops as soon as the number of comments exceeding the waiting time is known.</p><div class="no-row-height column-margin column-container"><span class="margin-aside">The bigger inefficiency is the <code>dataframe</code> library, particularly <code>dataframe-split</code>.</span></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb6-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">get-num-events </span>max-obs max-time)</span>
<span id="cb6-2">    (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> loop (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>obs <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb6-3">               <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>time <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb6-4">               <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>events <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb6-5">      (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">or</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> obs max-obs) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> time max-time))</span>
<span id="cb6-6">          (sub1 events) <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;; sub1 to find num events less than max-time threshold</span></span>
<span id="cb6-7">          (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>exp-draw (random-exponential (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> obs))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>)</span>
<span id="cb6-8">            (loop (add1 obs) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> time exp-draw) (add1 events))))))</span>
<span id="cb6-9"></span>
<span id="cb6-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (get-num-events <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">300</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)</span>
<span id="cb6-11"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">16</span></span>
<span id="cb6-12"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (get-num-events <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">300</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)</span>
<span id="cb6-13"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span>
<span id="cb6-14"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (get-num-events <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">300</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)</span>
<span id="cb6-15"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">24</span></span>
<span id="cb6-16"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (get-num-events <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">300</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)</span>
<span id="cb6-17"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">28</span></span></code></pre></div></div>
<p>The <code>repeat</code> procedure from <code>chez-stats</code> uses recursion to repeat a thunk <code>n</code> times, which allows us to build up a set of replications.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb7-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> sim </span>(repeat <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1e5</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> () (get-num-events <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">300</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>))))</span>
<span id="cb7-2"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">inexact</span> (mean sim))</span>
<span id="cb7-3"><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">19.03991</span></span></code></pre></div></div>
<p>The last step is to vary the times used in the simulation.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode scheme code-with-copy"><code class="sourceCode scheme"><span id="cb8-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> max-times </span>(map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (x) (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> x <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.25</span>)) (iota <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">13</span>)))</span>
<span id="cb8-2"></span>
<span id="cb8-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> sim-times</span></span>
<span id="cb8-4">   (map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (mt)</span>
<span id="cb8-5">          (repeat <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1e5</span> (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> () (get-num-events <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">300</span> mt))))</span>
<span id="cb8-6">        max-times))</span>
<span id="cb8-7"></span>
<span id="cb8-8"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> (<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> sim-times-mean </span>(map (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> (x) (<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">inexact</span> (mean x))) sim-times))</span>
<span id="cb8-9"></span>
<span id="cb8-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> max-times</span>
<span id="cb8-11">(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.25</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.75</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.0</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.25</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.5</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.75</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.0</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.25</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.5</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.75</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.0</span>)</span>
<span id="cb8-12"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> sim-times-mean</span>
<span id="cb8-13">(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.28459</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.64931</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.11663</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.71885</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.48855</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.47136</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.74836</span></span>
<span id="cb8-14">     <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6.38984</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">8.48071</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">11.13153</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">14.64021</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">19.07148</span>)</span></code></pre></div></div>
<p>This approach uses 100,000 trials and is effectively instantaneous whereas only 50 trials in the <code>dataframe</code> approach took several seconds and hundreds of trials was likely to freeze Emacs. The <code>dataframe</code> library is not capable of working with hundreds of thousands of row. Fortunately, many data analysis projects involve datasets much smaller than that. More importantly, idiomatic Scheme code is well suited for simulations like this spam comments problem.</p>


</section>

 ]]></description>
  <category>Scheme</category>
  <category>dataframe</category>
  <guid>https://www.travishinkelman.com/posts/spam-simulation-scheme.html</guid>
  <pubDate>Sat, 12 Dec 2020 00:00:00 GMT</pubDate>
</item>
</channel>
</rss>
