<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" lang xml:lang> <head> <meta charset="utf-8" /> <meta name="generator" content="pandoc" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> <meta name="author" content="Thierry Onkelinx and Dirk Eddelbuettel" /> <title>Calculating SHA1 hashes with digest() and sha1()</title> <style> code{white-space: pre-wrap;} span.smallcaps{font-variant: small-caps;} div.columns{display: flex; gap: min(4vw, 1.5em);} div.column{flex: auto; overflow-x: auto;} div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} ul.task-list[class]{list-style: none;} ul.task-list li input[type="checkbox"] { font-size: inherit; width: 0.8em; margin: 0 0.8em 0.2em -1.6em; vertical-align: middle; } .display.math{display: block; text-align: center; margin: 0.5rem auto;} pre > code.sourceCode { white-space: pre; position: relative; } pre > code.sourceCode > span { line-height: 1.25; } pre > code.sourceCode > span:empty { height: 1.2em; } .sourceCode { overflow: visible; } code.sourceCode > span { color: inherit; text-decoration: inherit; } div.sourceCode { margin: 1em 0; } pre.sourceCode { margin: 0; } @media screen { div.sourceCode { overflow: auto; } } @media print { pre > code.sourceCode { white-space: pre-wrap; } pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; } } pre.numberSource code { counter-reset: source-line 0; } pre.numberSource code > span { position: relative; left: -4em; counter-increment: source-line; } pre.numberSource code > span > a:first-child::before { content: counter(source-line); position: relative; left: -1em; text-align: right; vertical-align: baseline; border: none; display: inline-block; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; padding: 0 4px; width: 4em; color: #aaaaaa; } pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; } div.sourceCode { } @media screen { pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; } } code span.al { color: #ff0000; font-weight: bold; } code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } code span.at { color: #7d9029; } code span.bn { color: #40a070; } code span.bu { color: #008000; } code span.cf { color: #007020; font-weight: bold; } code span.ch { color: #4070a0; } code span.cn { color: #880000; } code span.co { color: #60a0b0; font-style: italic; } code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } code span.do { color: #ba2121; font-style: italic; } code span.dt { color: #902000; } code span.dv { color: #40a070; } code span.er { color: #ff0000; font-weight: bold; } code span.ex { } code span.fl { color: #40a070; } code span.fu { color: #06287e; } code span.im { color: #008000; font-weight: bold; } code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } code span.kw { color: #007020; font-weight: bold; } code span.op { color: #666666; } code span.ot { color: #007020; } code span.pp { color: #bc7a00; } code span.sc { color: #4070a0; } code span.ss { color: #bb6688; } code span.st { color: #4070a0; } code span.va { color: #19177c; } code span.vs { color: #4070a0; } code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } </style> <style type="text/css"> body { max-width: 50rem; margin-left: auto; margin-right: auto; font-family: system-ui; } code { padding: 2px; border-radius: unset; } pre { background-color: unset; border: solid #aaa 1px; padding: 8px; } pre.numberSource { margin: 0; padding-left: 0; } div.sourceCode { overflow: visible; } pre, pre.sourceCode { overflow-x: auto; } pre>code { white-space: pre; overflow: visible; background-color: unset; padding: 0; } pre.sourceCode.numberSource { overflow-x: visible; } pre.sourceCode.numberSource>code { white-space: pre-wrap } pre.sourceCode.numberSource>code>span { left: 8px; text-indent: -4.6em; } .chunk-summary { text-align: right; } .chunk-summary+pre, .chunk-summary+div.sourceCode { margin-top: 2px; } nav > ul { border: .0625rem solid #444; border-radius: 4px; margin: 5px; padding: 5px; } nav ul { list-style-type: none; padding-inline-start: 1rem; } nav ul li { padding: 0; } nav ul ul { margin-top: 0; margin-bottom: 0; padding-top: 0; padding-bottom: 0; } nav code { background-color: unset; color: unset; } </style> </head> <body> <header id="title-block-header"> <h1 class="title">Calculating SHA1 hashes with digest() and sha1()</h1> <p class="author">Thierry Onkelinx and Dirk Eddelbuettel</p> <p class="date">Written Jan 2016, updated Jan 2018 and Oct 2020</p> </header> <!-- %\VignetteIndexEntry{sha1() versus digest()} %\VignetteEngine{simplermarkdown::mdweave_to_html} %\VignetteEncoding{UTF-8} --> <p>NB: This vignette is (still) work-in-progress and not yet complete.</p> <h2 id="short-intro-on-hashes">Short intro on hashes</h2> <p>TBD</p> <h2 id="difference-between-digest-and-sha1">Difference between <code>digest()</code> and <code>sha1()</code></h2> <p>R <a href="https://cran.r-project.org/doc/FAQ/R-FAQ.html#Why-doesn_0027t-R-think-these-numbers-are-equal_003f">FAQ 7.31</a> illustrates potential problems with floating point arithmetic. Mathematically the equality <span class="math inline">$x = \sqrt{x}^2$</span> should hold. But the precision of floating points numbers is finite. Hence some rounding is done, leading to numbers which are no longer identical.</p> <p>An illustration:</p> <div class="sourceCode" id="faq7_31"><pre class="sourceCode R"><code class="sourceCode r"><span id="faq7_31-1"><a href="#faq7_31-1" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="co"># FAQ 7.31</span></span> <span id="faq7_31-2"><a href="#faq7_31-2" aria-hidden="true" tabindex="-1"></a><span class="er">></span> a0 <span class="ot"><-</span> <span class="dv">2</span></span> <span id="faq7_31-3"><a href="#faq7_31-3" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> b <span class="ot"><-</span> <span class="fu">sqrt</span>(a0)</span> <span id="faq7_31-4"><a href="#faq7_31-4" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> a1 <span class="ot"><-</span> b <span class="sc">^</span> <span class="dv">2</span></span> <span id="faq7_31-5"><a href="#faq7_31-5" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="fu">identical</span>(a0, a1)</span> <span id="faq7_31-6"><a href="#faq7_31-6" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>] <span class="cn">FALSE</span></span> <span id="faq7_31-7"><a href="#faq7_31-7" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> a0 <span class="sc">-</span> a1</span> <span id="faq7_31-8"><a href="#faq7_31-8" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>] <span class="sc">-</span><span class="fl">4.440892e-16</span></span> <span id="faq7_31-9"><a href="#faq7_31-9" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> a <span class="ot"><-</span> <span class="fu">c</span>(a0, a1)</span> <span id="faq7_31-10"><a href="#faq7_31-10" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="co"># hexadecimal representation</span></span> <span id="faq7_31-11"><a href="#faq7_31-11" aria-hidden="true" tabindex="-1"></a><span class="er">></span> <span class="fu">sprintf</span>(<span class="st">"%a"</span>, a)</span> <span id="faq7_31-12"><a href="#faq7_31-12" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>] <span class="st">"0x1p+1"</span> <span class="st">"0x1.0000000000001p+1"</span></span></code></pre></div> <p>Although the difference is small, any difference will result in different hash when using the <code>digest()</code> function. However, the <code>sha1()</code> function tackles this problem by using the hexadecimal representation of the numbers and truncates that representation to a certain number of digits prior to calculating the hash function.</p> <div class="sourceCode" id="faq7_31digest"><pre class="sourceCode R"><code class="sourceCode r"><span id="faq7_31digest-1"><a href="#faq7_31digest-1" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="fu">library</span>(digest)</span> <span id="faq7_31digest-2"><a href="#faq7_31digest-2" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="co"># different hashes with digest</span></span> <span id="faq7_31digest-3"><a href="#faq7_31digest-3" aria-hidden="true" tabindex="-1"></a><span class="er">></span> <span class="fu">sapply</span>(a, digest, <span class="at">algo =</span> <span class="st">"sha1"</span>)</span> <span id="faq7_31digest-4"><a href="#faq7_31digest-4" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>] <span class="st">"315a5aa84aa6cfa4f3fb4b652a596770be0365e8"</span></span> <span id="faq7_31digest-5"><a href="#faq7_31digest-5" aria-hidden="true" tabindex="-1"></a>[<span class="dv">2</span>] <span class="st">"5e3999bf79c230f7430e97d7f30070a7eff5ec92"</span></span> <span id="faq7_31digest-6"><a href="#faq7_31digest-6" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="co"># same hash with sha1 with default digits (14)</span></span> <span id="faq7_31digest-7"><a href="#faq7_31digest-7" aria-hidden="true" tabindex="-1"></a><span class="er">></span> <span class="fu">sapply</span>(a, sha1)</span> <span id="faq7_31digest-8"><a href="#faq7_31digest-8" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>] <span class="st">"8a938d8f5fb9b8ccb6893aa1068babcc517f32d4"</span></span> <span id="faq7_31digest-9"><a href="#faq7_31digest-9" aria-hidden="true" tabindex="-1"></a>[<span class="dv">2</span>] <span class="st">"8a938d8f5fb9b8ccb6893aa1068babcc517f32d4"</span></span> <span id="faq7_31digest-10"><a href="#faq7_31digest-10" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="co"># larger digits can lead to different hashes</span></span> <span id="faq7_31digest-11"><a href="#faq7_31digest-11" aria-hidden="true" tabindex="-1"></a><span class="er">></span> <span class="fu">sapply</span>(a, sha1, <span class="at">digits =</span> <span class="dv">15</span>)</span> <span id="faq7_31digest-12"><a href="#faq7_31digest-12" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>] <span class="st">"98eb1dc9fada00b945d3ef01c77049ee5a4b7b9c"</span></span> <span id="faq7_31digest-13"><a href="#faq7_31digest-13" aria-hidden="true" tabindex="-1"></a>[<span class="dv">2</span>] <span class="st">"5a173e2445df1134908037f69ac005fbd8afee74"</span></span> <span id="faq7_31digest-14"><a href="#faq7_31digest-14" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="co"># decreasing the number of digits gives a stronger truncation</span></span> <span id="faq7_31digest-15"><a href="#faq7_31digest-15" aria-hidden="true" tabindex="-1"></a><span class="er">></span> <span class="co"># the hash will change when then truncation gives a different result</span></span> <span id="faq7_31digest-16"><a href="#faq7_31digest-16" aria-hidden="true" tabindex="-1"></a><span class="er">></span> <span class="co"># case where truncating gives same hexadecimal value</span></span> <span id="faq7_31digest-17"><a href="#faq7_31digest-17" aria-hidden="true" tabindex="-1"></a><span class="er">></span> <span class="fu">sapply</span>(a, sha1, <span class="at">digits =</span> <span class="dv">13</span>)</span> <span id="faq7_31digest-18"><a href="#faq7_31digest-18" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>] <span class="st">"43b3b465c975af322c85473190a9214b79b79bf6"</span></span> <span id="faq7_31digest-19"><a href="#faq7_31digest-19" aria-hidden="true" tabindex="-1"></a>[<span class="dv">2</span>] <span class="st">"43b3b465c975af322c85473190a9214b79b79bf6"</span></span> <span id="faq7_31digest-20"><a href="#faq7_31digest-20" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="fu">sapply</span>(a, sha1, <span class="at">digits =</span> <span class="dv">10</span>)</span> <span id="faq7_31digest-21"><a href="#faq7_31digest-21" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>] <span class="st">"6b537a9693c750ed535ca90527152f06e358aa3a"</span></span> <span id="faq7_31digest-22"><a href="#faq7_31digest-22" aria-hidden="true" tabindex="-1"></a>[<span class="dv">2</span>] <span class="st">"6b537a9693c750ed535ca90527152f06e358aa3a"</span></span> <span id="faq7_31digest-23"><a href="#faq7_31digest-23" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="co"># case where truncating gives different hexadecimal value</span></span> <span id="faq7_31digest-24"><a href="#faq7_31digest-24" aria-hidden="true" tabindex="-1"></a><span class="er">></span> <span class="fu">c</span>(<span class="fu">sha1</span>(pi), <span class="fu">sha1</span>(pi, <span class="at">digits =</span> <span class="dv">13</span>), <span class="fu">sha1</span>(pi, <span class="at">digits =</span> <span class="dv">10</span>))</span> <span id="faq7_31digest-25"><a href="#faq7_31digest-25" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>] <span class="st">"169388cf1ce60dc4e9904a22bc934c5db33d975b"</span></span> <span id="faq7_31digest-26"><a href="#faq7_31digest-26" aria-hidden="true" tabindex="-1"></a>[<span class="dv">2</span>] <span class="st">"20dc38536b6689d5f2d053f30efb09c44af78378"</span></span> <span id="faq7_31digest-27"><a href="#faq7_31digest-27" aria-hidden="true" tabindex="-1"></a>[<span class="dv">3</span>] <span class="st">"3a727417bd1807af2f0148cf3de69abff32c23ec"</span></span></code></pre></div> <p>The result of floating point arithematic on 32-bit and 64-bit can be slightly different. E.g. <code>print(pi ^ 11, 22)</code> returns <code>294204.01797389047</code> on 32-bit and <code>294204.01797389053</code> on 64-bit. Note that only the last 2 digits are different.</p> <table style="width:98%;"> <colgroup> <col style="width: 26%" /> <col style="width: 35%" /> <col style="width: 35%" /> </colgroup> <thead> <tr class="header"> <th style="text-align: left;">command</th> <th style="text-align: left;">32-bit</th> <th style="text-align: left;">64-bit</th> </tr> </thead> <tbody> <tr class="odd"> <td style="text-align: left;"><code>print(pi ^ 11, 22)</code></td> <td style="text-align: left;"><code>294204.01797389047</code></td> <td style="text-align: left;"><code>294204.01797389053</code></td> </tr> <tr class="even"> <td style="text-align: left;"><code>sprintf("%a", pi ^ 11)</code></td> <td style="text-align: left;"><code>"0x1.1f4f01267bf5fp+18"</code></td> <td style="text-align: left;"><code>"0x1.1f4f01267bf6p+18"</code></td> </tr> <tr class="odd"> <td style="text-align: left;"><code>digest(pi ^ 11, algo = "sha1")</code></td> <td style="text-align: left;"><code>"c5efc7f167df1bb402b27cf9b405d7cebfba339a"</code></td> <td style="text-align: left;"><code>"b61f6fea5e2a7952692cefe8bba86a00af3de713"</code></td> </tr> <tr class="even"> <td style="text-align: left;"><code>sha1(pi ^ 11, digits = 14)</code></td> <td style="text-align: left;"><code>"5c7740500b8f78ec2354ea6af58ea69634d9b7b1"</code></td> <td style="text-align: left;"><code>"4f3e296b9922a7ddece2183b1478d0685609a359"</code></td> </tr> <tr class="odd"> <td style="text-align: left;"><code>sha1(pi ^ 11, digits = 13)</code></td> <td style="text-align: left;"><code>"372289f87396b0877ccb4790cf40bcb5e658cad7"</code></td> <td style="text-align: left;"><code>"372289f87396b0877ccb4790cf40bcb5e658cad7"</code></td> </tr> <tr class="even"> <td style="text-align: left;"><code>sha1(pi ^ 11, digits = 10)</code></td> <td style="text-align: left;"><code>"c05965af43f9566bfb5622f335817f674abfc9e4"</code></td> <td style="text-align: left;"><code>"c05965af43f9566bfb5622f335817f674abfc9e4"</code></td> </tr> </tbody> </table> <h2 id="choosing-digest-or-sha1">Choosing <code>digest()</code> or <code>sha1()</code></h2> <p>TBD</p> <h2 id="creating-a-sha1-method-for-other-classes">Creating a sha1 method for other classes</h2> <h3 id="how-to">How to</h3> <ol type="1"> <li>Identify the relevant components for the hash.</li> <li>Determine the class of each relevant component and check if they are handled by <code>sha1()</code>. <ul> <li>Write a method for each component class not yet handled by <code>sha1</code>.</li> </ul></li> <li>Extract the relevant components.</li> <li>Combine the relevant components into a list. Not required in case of a single component.</li> <li>Apply <code>sha1()</code> on the (list of) relevant component(s).</li> <li>Turn this into a function with name sha1._classname_.</li> <li>sha1._classname_ needs exactly the same arguments as <code>sha1()</code></li> <li>Choose sensible defaults for the arguments <ul> <li><code>zapsmall = 7</code> is recommended.</li> <li><code>digits = 14</code> is recommended in case all numerics are data.</li> <li><code>digits = 4</code> is recommended in case some numerics stem from floating point arithmetic.</li> </ul></li> </ol> <h3 id="summary.lm">summary.lm</h3> <p>Let’s illustrate this using the summary of a simple linear regression. Suppose that we want a hash that takes into account the coefficients, their standard error and sigma.</p> <div class="sourceCode" id="sha1_lm_sum"><pre class="sourceCode R"><code class="sourceCode r"><span id="sha1_lm_sum-1"><a href="#sha1_lm_sum-1" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="co"># taken from the help file of lm.influence</span></span> <span id="sha1_lm_sum-2"><a href="#sha1_lm_sum-2" aria-hidden="true" tabindex="-1"></a><span class="er">></span> lm_SR <span class="ot"><-</span> <span class="fu">lm</span>(sr <span class="sc">~</span> pop15 <span class="sc">+</span> pop75 <span class="sc">+</span> dpi <span class="sc">+</span> ddpi, <span class="at">data =</span> LifeCycleSavings)</span> <span id="sha1_lm_sum-3"><a href="#sha1_lm_sum-3" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> lm_sum <span class="ot"><-</span> <span class="fu">summary</span>(lm_SR)</span> <span id="sha1_lm_sum-4"><a href="#sha1_lm_sum-4" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="fu">class</span>(lm_sum)</span> <span id="sha1_lm_sum-5"><a href="#sha1_lm_sum-5" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>] <span class="st">"summary.lm"</span></span> <span id="sha1_lm_sum-6"><a href="#sha1_lm_sum-6" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="co"># str() gives the structure of the lm object</span></span> <span id="sha1_lm_sum-7"><a href="#sha1_lm_sum-7" aria-hidden="true" tabindex="-1"></a><span class="er">></span> <span class="fu">str</span>(lm_sum)</span> <span id="sha1_lm_sum-8"><a href="#sha1_lm_sum-8" aria-hidden="true" tabindex="-1"></a>List of <span class="dv">11</span></span> <span id="sha1_lm_sum-9"><a href="#sha1_lm_sum-9" aria-hidden="true" tabindex="-1"></a> <span class="sc">$</span> call <span class="sc">:</span> language <span class="fu">lm</span>(<span class="at">formula =</span> sr <span class="sc">~</span> pop15 <span class="sc">+</span> pop75 <span class="sc">+</span> dpi <span class="sc">+</span> ddpi, <span class="at">data =</span> LifeCycleSavings)</span> <span id="sha1_lm_sum-10"><a href="#sha1_lm_sum-10" aria-hidden="true" tabindex="-1"></a> <span class="sc">$</span> terms <span class="sc">:</span>Classes <span class="st">'terms'</span>, <span class="st">'formula'</span> language sr <span class="sc">~</span> pop15 <span class="sc">+</span> pop75 <span class="sc">+</span> dpi <span class="sc">+</span> ddpi</span> <span id="sha1_lm_sum-11"><a href="#sha1_lm_sum-11" aria-hidden="true" tabindex="-1"></a> .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"variables"</span>)<span class="ot">=</span> language <span class="fu">list</span>(sr, pop15, pop75, dpi, ddpi)</span> <span id="sha1_lm_sum-12"><a href="#sha1_lm_sum-12" aria-hidden="true" tabindex="-1"></a> .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"factors"</span>)<span class="ot">=</span> int [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>, <span class="dv">1</span><span class="sc">:</span><span class="dv">4</span>] <span class="dv">0</span> <span class="dv">1</span> <span class="dv">0</span> <span class="dv">0</span> <span class="dv">0</span> <span class="dv">0</span> <span class="dv">0</span> <span class="dv">1</span> <span class="dv">0</span> <span class="dv">0</span> ...</span> <span id="sha1_lm_sum-13"><a href="#sha1_lm_sum-13" aria-hidden="true" tabindex="-1"></a> .. .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"dimnames"</span>)<span class="ot">=</span>List of <span class="dv">2</span></span> <span id="sha1_lm_sum-14"><a href="#sha1_lm_sum-14" aria-hidden="true" tabindex="-1"></a> .. .. .. ..<span class="sc">$</span> <span class="er">:</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="st">"sr"</span> <span class="st">"pop15"</span> <span class="st">"pop75"</span> <span class="st">"dpi"</span> ...</span> <span id="sha1_lm_sum-15"><a href="#sha1_lm_sum-15" aria-hidden="true" tabindex="-1"></a> .. .. .. ..<span class="sc">$</span> <span class="er">:</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">4</span>] <span class="st">"pop15"</span> <span class="st">"pop75"</span> <span class="st">"dpi"</span> <span class="st">"ddpi"</span></span> <span id="sha1_lm_sum-16"><a href="#sha1_lm_sum-16" aria-hidden="true" tabindex="-1"></a> .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"term.labels"</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">4</span>] <span class="st">"pop15"</span> <span class="st">"pop75"</span> <span class="st">"dpi"</span> <span class="st">"ddpi"</span></span> <span id="sha1_lm_sum-17"><a href="#sha1_lm_sum-17" aria-hidden="true" tabindex="-1"></a> .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"order"</span>)<span class="ot">=</span> int [<span class="dv">1</span><span class="sc">:</span><span class="dv">4</span>] <span class="dv">1</span> <span class="dv">1</span> <span class="dv">1</span> <span class="dv">1</span></span> <span id="sha1_lm_sum-18"><a href="#sha1_lm_sum-18" aria-hidden="true" tabindex="-1"></a> .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"intercept"</span>)<span class="ot">=</span> int <span class="dv">1</span></span> <span id="sha1_lm_sum-19"><a href="#sha1_lm_sum-19" aria-hidden="true" tabindex="-1"></a> .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"response"</span>)<span class="ot">=</span> int <span class="dv">1</span></span> <span id="sha1_lm_sum-20"><a href="#sha1_lm_sum-20" aria-hidden="true" tabindex="-1"></a> .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">".Environment"</span>)<span class="ot">=</span><span class="er"><</span>environment<span class="sc">:</span> R_GlobalEnv<span class="sc">></span> </span> <span id="sha1_lm_sum-21"><a href="#sha1_lm_sum-21" aria-hidden="true" tabindex="-1"></a> .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"predvars"</span>)<span class="ot">=</span> language <span class="fu">list</span>(sr, pop15, pop75, dpi, ddpi)</span> <span id="sha1_lm_sum-22"><a href="#sha1_lm_sum-22" aria-hidden="true" tabindex="-1"></a> .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"dataClasses"</span>)<span class="ot">=</span> Named chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="st">"numeric"</span> <span class="st">"numeric"</span> <span class="st">"numeric"</span> <span class="st">"numeric"</span> ...</span> <span id="sha1_lm_sum-23"><a href="#sha1_lm_sum-23" aria-hidden="true" tabindex="-1"></a> .. .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"names"</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="st">"sr"</span> <span class="st">"pop15"</span> <span class="st">"pop75"</span> <span class="st">"dpi"</span> ...</span> <span id="sha1_lm_sum-24"><a href="#sha1_lm_sum-24" aria-hidden="true" tabindex="-1"></a> <span class="sc">$</span> residuals <span class="sc">:</span> Named num [<span class="dv">1</span><span class="sc">:</span><span class="dv">50</span>] <span class="fl">0.864</span> <span class="fl">0.616</span> <span class="fl">2.219</span> <span class="sc">-</span><span class="fl">0.698</span> <span class="fl">3.553</span> ...</span> <span id="sha1_lm_sum-25"><a href="#sha1_lm_sum-25" aria-hidden="true" tabindex="-1"></a> ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"names"</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">50</span>] <span class="st">"Australia"</span> <span class="st">"Austria"</span> <span class="st">"Belgium"</span> <span class="st">"Bolivia"</span> ...</span> <span id="sha1_lm_sum-26"><a href="#sha1_lm_sum-26" aria-hidden="true" tabindex="-1"></a> <span class="sc">$</span> coefficients <span class="sc">:</span> num [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>, <span class="dv">1</span><span class="sc">:</span><span class="dv">4</span>] <span class="fl">28.566087</span> <span class="sc">-</span><span class="fl">0.461193</span> <span class="sc">-</span><span class="fl">1.691498</span> <span class="sc">-</span><span class="fl">0.000337</span> <span class="fl">0.409695</span> ...</span> <span id="sha1_lm_sum-27"><a href="#sha1_lm_sum-27" aria-hidden="true" tabindex="-1"></a> ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"dimnames"</span>)<span class="ot">=</span>List of <span class="dv">2</span></span> <span id="sha1_lm_sum-28"><a href="#sha1_lm_sum-28" aria-hidden="true" tabindex="-1"></a> .. ..<span class="sc">$</span> <span class="er">:</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="st">"(Intercept)"</span> <span class="st">"pop15"</span> <span class="st">"pop75"</span> <span class="st">"dpi"</span> ...</span> <span id="sha1_lm_sum-29"><a href="#sha1_lm_sum-29" aria-hidden="true" tabindex="-1"></a> .. ..<span class="sc">$</span> <span class="er">:</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">4</span>] <span class="st">"Estimate"</span> <span class="st">"Std. Error"</span> <span class="st">"t value"</span> <span class="st">"Pr(>|t|)"</span></span> <span id="sha1_lm_sum-30"><a href="#sha1_lm_sum-30" aria-hidden="true" tabindex="-1"></a> <span class="sc">$</span> aliased <span class="sc">:</span> Named logi [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="cn">FALSE</span> <span class="cn">FALSE</span> <span class="cn">FALSE</span> <span class="cn">FALSE</span> <span class="cn">FALSE</span></span> <span id="sha1_lm_sum-31"><a href="#sha1_lm_sum-31" aria-hidden="true" tabindex="-1"></a> ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"names"</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="st">"(Intercept)"</span> <span class="st">"pop15"</span> <span class="st">"pop75"</span> <span class="st">"dpi"</span> ...</span> <span id="sha1_lm_sum-32"><a href="#sha1_lm_sum-32" aria-hidden="true" tabindex="-1"></a> <span class="sc">$</span> sigma <span class="sc">:</span> num <span class="fl">3.8</span></span> <span id="sha1_lm_sum-33"><a href="#sha1_lm_sum-33" aria-hidden="true" tabindex="-1"></a> <span class="sc">$</span> df <span class="sc">:</span> int [<span class="dv">1</span><span class="sc">:</span><span class="dv">3</span>] <span class="dv">5</span> <span class="dv">45</span> <span class="dv">5</span></span> <span id="sha1_lm_sum-34"><a href="#sha1_lm_sum-34" aria-hidden="true" tabindex="-1"></a> <span class="sc">$</span> r.squared <span class="sc">:</span> num <span class="fl">0.338</span></span> <span id="sha1_lm_sum-35"><a href="#sha1_lm_sum-35" aria-hidden="true" tabindex="-1"></a> <span class="sc">$</span> adj.r.squared<span class="sc">:</span> num <span class="fl">0.28</span></span> <span id="sha1_lm_sum-36"><a href="#sha1_lm_sum-36" aria-hidden="true" tabindex="-1"></a> <span class="sc">$</span> fstatistic <span class="sc">:</span> Named num [<span class="dv">1</span><span class="sc">:</span><span class="dv">3</span>] <span class="fl">5.76</span> <span class="dv">4</span> <span class="dv">45</span></span> <span id="sha1_lm_sum-37"><a href="#sha1_lm_sum-37" aria-hidden="true" tabindex="-1"></a> ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"names"</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">3</span>] <span class="st">"value"</span> <span class="st">"numdf"</span> <span class="st">"dendf"</span></span> <span id="sha1_lm_sum-38"><a href="#sha1_lm_sum-38" aria-hidden="true" tabindex="-1"></a> <span class="sc">$</span> cov.unscaled <span class="sc">:</span> num [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>, <span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="fl">3.74</span> <span class="sc">-</span><span class="fl">7.24e-02</span> <span class="sc">-</span><span class="fl">4.46e-01</span> <span class="sc">-</span><span class="fl">7.86e-05</span> <span class="sc">-</span><span class="fl">1.88e-02</span> ...</span> <span id="sha1_lm_sum-39"><a href="#sha1_lm_sum-39" aria-hidden="true" tabindex="-1"></a> ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"dimnames"</span>)<span class="ot">=</span>List of <span class="dv">2</span></span> <span id="sha1_lm_sum-40"><a href="#sha1_lm_sum-40" aria-hidden="true" tabindex="-1"></a> .. ..<span class="sc">$</span> <span class="er">:</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="st">"(Intercept)"</span> <span class="st">"pop15"</span> <span class="st">"pop75"</span> <span class="st">"dpi"</span> ...</span> <span id="sha1_lm_sum-41"><a href="#sha1_lm_sum-41" aria-hidden="true" tabindex="-1"></a> .. ..<span class="sc">$</span> <span class="er">:</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="st">"(Intercept)"</span> <span class="st">"pop15"</span> <span class="st">"pop75"</span> <span class="st">"dpi"</span> ...</span> <span id="sha1_lm_sum-42"><a href="#sha1_lm_sum-42" aria-hidden="true" tabindex="-1"></a> <span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"class"</span>)<span class="ot">=</span> chr <span class="st">"summary.lm"</span></span> <span id="sha1_lm_sum-43"><a href="#sha1_lm_sum-43" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="co"># extract the coefficients and their standard error</span></span> <span id="sha1_lm_sum-44"><a href="#sha1_lm_sum-44" aria-hidden="true" tabindex="-1"></a><span class="er">></span> coef_sum <span class="ot"><-</span> <span class="fu">coef</span>(lm_sum)[, <span class="fu">c</span>(<span class="st">"Estimate"</span>, <span class="st">"Std. Error"</span>)]</span> <span id="sha1_lm_sum-45"><a href="#sha1_lm_sum-45" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="co"># extract sigma</span></span> <span id="sha1_lm_sum-46"><a href="#sha1_lm_sum-46" aria-hidden="true" tabindex="-1"></a><span class="er">></span> sigma <span class="ot"><-</span> lm_sum<span class="sc">$</span>sigma</span> <span id="sha1_lm_sum-47"><a href="#sha1_lm_sum-47" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="co"># check the class of each component</span></span> <span id="sha1_lm_sum-48"><a href="#sha1_lm_sum-48" aria-hidden="true" tabindex="-1"></a><span class="er">></span> <span class="fu">class</span>(coef_sum)</span> <span id="sha1_lm_sum-49"><a href="#sha1_lm_sum-49" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>] <span class="st">"matrix"</span> <span class="st">"array"</span> </span> <span id="sha1_lm_sum-50"><a href="#sha1_lm_sum-50" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="fu">class</span>(sigma)</span> <span id="sha1_lm_sum-51"><a href="#sha1_lm_sum-51" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>] <span class="st">"numeric"</span></span> <span id="sha1_lm_sum-52"><a href="#sha1_lm_sum-52" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="co"># sha1() has methods for both matrix and numeric</span></span> <span id="sha1_lm_sum-53"><a href="#sha1_lm_sum-53" aria-hidden="true" tabindex="-1"></a><span class="er">></span> <span class="co"># because the values originate from floating point arithmetic it is better to use a low number of digits</span></span> <span id="sha1_lm_sum-54"><a href="#sha1_lm_sum-54" aria-hidden="true" tabindex="-1"></a><span class="er">></span> <span class="fu">sha1</span>(coef_sum, <span class="at">digits =</span> <span class="dv">4</span>)</span> <span id="sha1_lm_sum-55"><a href="#sha1_lm_sum-55" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>] <span class="st">"3f0b0c552f94d753fcc8deb4d3e9fc11a83197af"</span></span> <span id="sha1_lm_sum-56"><a href="#sha1_lm_sum-56" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="fu">sha1</span>(sigma, <span class="at">digits =</span> <span class="dv">4</span>)</span> <span id="sha1_lm_sum-57"><a href="#sha1_lm_sum-57" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>] <span class="st">"cbc83d1791ef1eeadd824ea9a038891b5889056b"</span></span> <span id="sha1_lm_sum-58"><a href="#sha1_lm_sum-58" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="co"># we want a single hash</span></span> <span id="sha1_lm_sum-59"><a href="#sha1_lm_sum-59" aria-hidden="true" tabindex="-1"></a><span class="er">></span> <span class="co"># combining the components in a list is a solution that works</span></span> <span id="sha1_lm_sum-60"><a href="#sha1_lm_sum-60" aria-hidden="true" tabindex="-1"></a><span class="er">></span> <span class="fu">sha1</span>(<span class="fu">list</span>(coef_sum, sigma), <span class="at">digits =</span> <span class="dv">4</span>)</span> <span id="sha1_lm_sum-61"><a href="#sha1_lm_sum-61" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>] <span class="st">"476d27265365cd41662eedf059b335d38a221cc2"</span></span> <span id="sha1_lm_sum-62"><a href="#sha1_lm_sum-62" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="co"># now turn everything into an S3 method</span></span> <span id="sha1_lm_sum-63"><a href="#sha1_lm_sum-63" aria-hidden="true" tabindex="-1"></a><span class="er">></span> <span class="co"># - a function with name "sha1.classname"</span></span> <span id="sha1_lm_sum-64"><a href="#sha1_lm_sum-64" aria-hidden="true" tabindex="-1"></a><span class="er">></span> <span class="co"># - must have the same arguments as sha1()</span></span> <span id="sha1_lm_sum-65"><a href="#sha1_lm_sum-65" aria-hidden="true" tabindex="-1"></a><span class="er">></span> sha1.summary.lm <span class="ot"><-</span> <span class="cf">function</span>(x, <span class="at">digits =</span> <span class="dv">4</span>, <span class="at">zapsmall =</span> <span class="dv">7</span>){</span> <span id="sha1_lm_sum-66"><a href="#sha1_lm_sum-66" aria-hidden="true" tabindex="-1"></a><span class="sc">+</span> coef_sum <span class="ot"><-</span> <span class="fu">coef</span>(x)[, <span class="fu">c</span>(<span class="st">"Estimate"</span>, <span class="st">"Std. Error"</span>)]</span> <span id="sha1_lm_sum-67"><a href="#sha1_lm_sum-67" aria-hidden="true" tabindex="-1"></a><span class="sc">+</span> sigma <span class="ot"><-</span> x<span class="sc">$</span>sigma</span> <span id="sha1_lm_sum-68"><a href="#sha1_lm_sum-68" aria-hidden="true" tabindex="-1"></a><span class="sc">+</span> combined <span class="ot"><-</span> <span class="fu">list</span>(coef_sum, sigma)</span> <span id="sha1_lm_sum-69"><a href="#sha1_lm_sum-69" aria-hidden="true" tabindex="-1"></a><span class="sc">+</span> <span class="fu">sha1</span>(combined, <span class="at">digits =</span> digits, <span class="at">zapsmall =</span> zapsmall)</span> <span id="sha1_lm_sum-70"><a href="#sha1_lm_sum-70" aria-hidden="true" tabindex="-1"></a><span class="sc">+</span> }</span> <span id="sha1_lm_sum-71"><a href="#sha1_lm_sum-71" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="fu">sha1</span>(lm_sum)</span> <span id="sha1_lm_sum-72"><a href="#sha1_lm_sum-72" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>] <span class="st">"476d27265365cd41662eedf059b335d38a221cc2"</span></span> <span id="sha1_lm_sum-73"><a href="#sha1_lm_sum-73" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="co"># try an altered dataset</span></span> <span id="sha1_lm_sum-74"><a href="#sha1_lm_sum-74" aria-hidden="true" tabindex="-1"></a><span class="er">></span> LCS2 <span class="ot"><-</span> LifeCycleSavings[<span class="fu">rownames</span>(LifeCycleSavings) <span class="sc">!=</span> <span class="st">"Zambia"</span>, ]</span> <span id="sha1_lm_sum-75"><a href="#sha1_lm_sum-75" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> lm_SR2 <span class="ot"><-</span> <span class="fu">lm</span>(sr <span class="sc">~</span> pop15 <span class="sc">+</span> pop75 <span class="sc">+</span> dpi <span class="sc">+</span> ddpi, <span class="at">data =</span> LCS2)</span> <span id="sha1_lm_sum-76"><a href="#sha1_lm_sum-76" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="fu">sha1</span>(<span class="fu">summary</span>(lm_SR2))</span> <span id="sha1_lm_sum-77"><a href="#sha1_lm_sum-77" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>] <span class="st">"90beb028833bf0542997fde7c3f19e5b9fdfeef4"</span></span></code></pre></div> <h3 id="lm">lm</h3> <p>Let’s illustrate this using the summary of a simple linear regression. Suppose that we want a hash that takes into account the coefficients, their standard error and sigma.</p> <div class="sourceCode" id="sha1_lm"><pre class="sourceCode R"><code class="sourceCode r"><span id="sha1_lm-1"><a href="#sha1_lm-1" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="fu">class</span>(lm_SR)</span> <span id="sha1_lm-2"><a href="#sha1_lm-2" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>] <span class="st">"lm"</span></span> <span id="sha1_lm-3"><a href="#sha1_lm-3" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="co"># str() gives the structure of the lm object</span></span> <span id="sha1_lm-4"><a href="#sha1_lm-4" aria-hidden="true" tabindex="-1"></a><span class="er">></span> <span class="fu">str</span>(lm_SR)</span> <span id="sha1_lm-5"><a href="#sha1_lm-5" aria-hidden="true" tabindex="-1"></a>List of <span class="dv">12</span></span> <span id="sha1_lm-6"><a href="#sha1_lm-6" aria-hidden="true" tabindex="-1"></a> <span class="sc">$</span> coefficients <span class="sc">:</span> Named num [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="fl">28.566087</span> <span class="sc">-</span><span class="fl">0.461193</span> <span class="sc">-</span><span class="fl">1.691498</span> <span class="sc">-</span><span class="fl">0.000337</span> <span class="fl">0.409695</span></span> <span id="sha1_lm-7"><a href="#sha1_lm-7" aria-hidden="true" tabindex="-1"></a> ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"names"</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="st">"(Intercept)"</span> <span class="st">"pop15"</span> <span class="st">"pop75"</span> <span class="st">"dpi"</span> ...</span> <span id="sha1_lm-8"><a href="#sha1_lm-8" aria-hidden="true" tabindex="-1"></a> <span class="sc">$</span> residuals <span class="sc">:</span> Named num [<span class="dv">1</span><span class="sc">:</span><span class="dv">50</span>] <span class="fl">0.864</span> <span class="fl">0.616</span> <span class="fl">2.219</span> <span class="sc">-</span><span class="fl">0.698</span> <span class="fl">3.553</span> ...</span> <span id="sha1_lm-9"><a href="#sha1_lm-9" aria-hidden="true" tabindex="-1"></a> ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"names"</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">50</span>] <span class="st">"Australia"</span> <span class="st">"Austria"</span> <span class="st">"Belgium"</span> <span class="st">"Bolivia"</span> ...</span> <span id="sha1_lm-10"><a href="#sha1_lm-10" aria-hidden="true" tabindex="-1"></a> <span class="sc">$</span> effects <span class="sc">:</span> Named num [<span class="dv">1</span><span class="sc">:</span><span class="dv">50</span>] <span class="sc">-</span><span class="fl">68.38</span> <span class="sc">-</span><span class="fl">14.29</span> <span class="fl">7.3</span> <span class="sc">-</span><span class="fl">3.52</span> <span class="sc">-</span><span class="fl">7.94</span> ...</span> <span id="sha1_lm-11"><a href="#sha1_lm-11" aria-hidden="true" tabindex="-1"></a> ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"names"</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">50</span>] <span class="st">"(Intercept)"</span> <span class="st">"pop15"</span> <span class="st">"pop75"</span> <span class="st">"dpi"</span> ...</span> <span id="sha1_lm-12"><a href="#sha1_lm-12" aria-hidden="true" tabindex="-1"></a> <span class="sc">$</span> rank <span class="sc">:</span> int <span class="dv">5</span></span> <span id="sha1_lm-13"><a href="#sha1_lm-13" aria-hidden="true" tabindex="-1"></a> <span class="sc">$</span> fitted.values<span class="sc">:</span> Named num [<span class="dv">1</span><span class="sc">:</span><span class="dv">50</span>] <span class="fl">10.57</span> <span class="fl">11.45</span> <span class="fl">10.95</span> <span class="fl">6.45</span> <span class="fl">9.33</span> ...</span> <span id="sha1_lm-14"><a href="#sha1_lm-14" aria-hidden="true" tabindex="-1"></a> ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"names"</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">50</span>] <span class="st">"Australia"</span> <span class="st">"Austria"</span> <span class="st">"Belgium"</span> <span class="st">"Bolivia"</span> ...</span> <span id="sha1_lm-15"><a href="#sha1_lm-15" aria-hidden="true" tabindex="-1"></a> <span class="sc">$</span> assign <span class="sc">:</span> int [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="dv">0</span> <span class="dv">1</span> <span class="dv">2</span> <span class="dv">3</span> <span class="dv">4</span></span> <span id="sha1_lm-16"><a href="#sha1_lm-16" aria-hidden="true" tabindex="-1"></a> <span class="sc">$</span> qr <span class="sc">:</span>List of <span class="dv">5</span></span> <span id="sha1_lm-17"><a href="#sha1_lm-17" aria-hidden="true" tabindex="-1"></a> ..<span class="sc">$</span> qr <span class="sc">:</span> num [<span class="dv">1</span><span class="sc">:</span><span class="dv">50</span>, <span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="sc">-</span><span class="fl">7.071</span> <span class="fl">0.141</span> <span class="fl">0.141</span> <span class="fl">0.141</span> <span class="fl">0.141</span> ...</span> <span id="sha1_lm-18"><a href="#sha1_lm-18" aria-hidden="true" tabindex="-1"></a> .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"dimnames"</span>)<span class="ot">=</span>List of <span class="dv">2</span></span> <span id="sha1_lm-19"><a href="#sha1_lm-19" aria-hidden="true" tabindex="-1"></a> .. .. ..<span class="sc">$</span> <span class="er">:</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">50</span>] <span class="st">"Australia"</span> <span class="st">"Austria"</span> <span class="st">"Belgium"</span> <span class="st">"Bolivia"</span> ...</span> <span id="sha1_lm-20"><a href="#sha1_lm-20" aria-hidden="true" tabindex="-1"></a> .. .. ..<span class="sc">$</span> <span class="er">:</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="st">"(Intercept)"</span> <span class="st">"pop15"</span> <span class="st">"pop75"</span> <span class="st">"dpi"</span> ...</span> <span id="sha1_lm-21"><a href="#sha1_lm-21" aria-hidden="true" tabindex="-1"></a> .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"assign"</span>)<span class="ot">=</span> int [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="dv">0</span> <span class="dv">1</span> <span class="dv">2</span> <span class="dv">3</span> <span class="dv">4</span></span> <span id="sha1_lm-22"><a href="#sha1_lm-22" aria-hidden="true" tabindex="-1"></a> ..<span class="sc">$</span> qraux<span class="sc">:</span> num [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="fl">1.14</span> <span class="fl">1.17</span> <span class="fl">1.16</span> <span class="fl">1.15</span> <span class="fl">1.05</span></span> <span id="sha1_lm-23"><a href="#sha1_lm-23" aria-hidden="true" tabindex="-1"></a> ..<span class="sc">$</span> pivot<span class="sc">:</span> int [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="dv">1</span> <span class="dv">2</span> <span class="dv">3</span> <span class="dv">4</span> <span class="dv">5</span></span> <span id="sha1_lm-24"><a href="#sha1_lm-24" aria-hidden="true" tabindex="-1"></a> ..<span class="sc">$</span> tol <span class="sc">:</span> num <span class="fl">1e-07</span></span> <span id="sha1_lm-25"><a href="#sha1_lm-25" aria-hidden="true" tabindex="-1"></a> ..<span class="sc">$</span> rank <span class="sc">:</span> int <span class="dv">5</span></span> <span id="sha1_lm-26"><a href="#sha1_lm-26" aria-hidden="true" tabindex="-1"></a> ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"class"</span>)<span class="ot">=</span> chr <span class="st">"qr"</span></span> <span id="sha1_lm-27"><a href="#sha1_lm-27" aria-hidden="true" tabindex="-1"></a> <span class="sc">$</span> df.residual <span class="sc">:</span> int <span class="dv">45</span></span> <span id="sha1_lm-28"><a href="#sha1_lm-28" aria-hidden="true" tabindex="-1"></a> <span class="sc">$</span> xlevels <span class="sc">:</span> Named <span class="fu">list</span>()</span> <span id="sha1_lm-29"><a href="#sha1_lm-29" aria-hidden="true" tabindex="-1"></a> <span class="sc">$</span> call <span class="sc">:</span> language <span class="fu">lm</span>(<span class="at">formula =</span> sr <span class="sc">~</span> pop15 <span class="sc">+</span> pop75 <span class="sc">+</span> dpi <span class="sc">+</span> ddpi, <span class="at">data =</span> LifeCycleSavings)</span> <span id="sha1_lm-30"><a href="#sha1_lm-30" aria-hidden="true" tabindex="-1"></a> <span class="sc">$</span> terms <span class="sc">:</span>Classes <span class="st">'terms'</span>, <span class="st">'formula'</span> language sr <span class="sc">~</span> pop15 <span class="sc">+</span> pop75 <span class="sc">+</span> dpi <span class="sc">+</span> ddpi</span> <span id="sha1_lm-31"><a href="#sha1_lm-31" aria-hidden="true" tabindex="-1"></a> .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"variables"</span>)<span class="ot">=</span> language <span class="fu">list</span>(sr, pop15, pop75, dpi, ddpi)</span> <span id="sha1_lm-32"><a href="#sha1_lm-32" aria-hidden="true" tabindex="-1"></a> .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"factors"</span>)<span class="ot">=</span> int [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>, <span class="dv">1</span><span class="sc">:</span><span class="dv">4</span>] <span class="dv">0</span> <span class="dv">1</span> <span class="dv">0</span> <span class="dv">0</span> <span class="dv">0</span> <span class="dv">0</span> <span class="dv">0</span> <span class="dv">1</span> <span class="dv">0</span> <span class="dv">0</span> ...</span> <span id="sha1_lm-33"><a href="#sha1_lm-33" aria-hidden="true" tabindex="-1"></a> .. .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"dimnames"</span>)<span class="ot">=</span>List of <span class="dv">2</span></span> <span id="sha1_lm-34"><a href="#sha1_lm-34" aria-hidden="true" tabindex="-1"></a> .. .. .. ..<span class="sc">$</span> <span class="er">:</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="st">"sr"</span> <span class="st">"pop15"</span> <span class="st">"pop75"</span> <span class="st">"dpi"</span> ...</span> <span id="sha1_lm-35"><a href="#sha1_lm-35" aria-hidden="true" tabindex="-1"></a> .. .. .. ..<span class="sc">$</span> <span class="er">:</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">4</span>] <span class="st">"pop15"</span> <span class="st">"pop75"</span> <span class="st">"dpi"</span> <span class="st">"ddpi"</span></span> <span id="sha1_lm-36"><a href="#sha1_lm-36" aria-hidden="true" tabindex="-1"></a> .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"term.labels"</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">4</span>] <span class="st">"pop15"</span> <span class="st">"pop75"</span> <span class="st">"dpi"</span> <span class="st">"ddpi"</span></span> <span id="sha1_lm-37"><a href="#sha1_lm-37" aria-hidden="true" tabindex="-1"></a> .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"order"</span>)<span class="ot">=</span> int [<span class="dv">1</span><span class="sc">:</span><span class="dv">4</span>] <span class="dv">1</span> <span class="dv">1</span> <span class="dv">1</span> <span class="dv">1</span></span> <span id="sha1_lm-38"><a href="#sha1_lm-38" aria-hidden="true" tabindex="-1"></a> .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"intercept"</span>)<span class="ot">=</span> int <span class="dv">1</span></span> <span id="sha1_lm-39"><a href="#sha1_lm-39" aria-hidden="true" tabindex="-1"></a> .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"response"</span>)<span class="ot">=</span> int <span class="dv">1</span></span> <span id="sha1_lm-40"><a href="#sha1_lm-40" aria-hidden="true" tabindex="-1"></a> .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">".Environment"</span>)<span class="ot">=</span><span class="er"><</span>environment<span class="sc">:</span> R_GlobalEnv<span class="sc">></span> </span> <span id="sha1_lm-41"><a href="#sha1_lm-41" aria-hidden="true" tabindex="-1"></a> .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"predvars"</span>)<span class="ot">=</span> language <span class="fu">list</span>(sr, pop15, pop75, dpi, ddpi)</span> <span id="sha1_lm-42"><a href="#sha1_lm-42" aria-hidden="true" tabindex="-1"></a> .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"dataClasses"</span>)<span class="ot">=</span> Named chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="st">"numeric"</span> <span class="st">"numeric"</span> <span class="st">"numeric"</span> <span class="st">"numeric"</span> ...</span> <span id="sha1_lm-43"><a href="#sha1_lm-43" aria-hidden="true" tabindex="-1"></a> .. .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"names"</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="st">"sr"</span> <span class="st">"pop15"</span> <span class="st">"pop75"</span> <span class="st">"dpi"</span> ...</span> <span id="sha1_lm-44"><a href="#sha1_lm-44" aria-hidden="true" tabindex="-1"></a> <span class="sc">$</span> model <span class="sc">:</span><span class="st">'data.frame'</span><span class="sc">:</span> <span class="dv">50</span> obs. of <span class="dv">5</span> variables<span class="sc">:</span></span> <span id="sha1_lm-45"><a href="#sha1_lm-45" aria-hidden="true" tabindex="-1"></a> ..<span class="sc">$</span> sr <span class="sc">:</span> num [<span class="dv">1</span><span class="sc">:</span><span class="dv">50</span>] <span class="fl">11.43</span> <span class="fl">12.07</span> <span class="fl">13.17</span> <span class="fl">5.75</span> <span class="fl">12.88</span> ...</span> <span id="sha1_lm-46"><a href="#sha1_lm-46" aria-hidden="true" tabindex="-1"></a> ..<span class="sc">$</span> pop15<span class="sc">:</span> num [<span class="dv">1</span><span class="sc">:</span><span class="dv">50</span>] <span class="fl">29.4</span> <span class="fl">23.3</span> <span class="fl">23.8</span> <span class="fl">41.9</span> <span class="fl">42.2</span> ...</span> <span id="sha1_lm-47"><a href="#sha1_lm-47" aria-hidden="true" tabindex="-1"></a> ..<span class="sc">$</span> pop75<span class="sc">:</span> num [<span class="dv">1</span><span class="sc">:</span><span class="dv">50</span>] <span class="fl">2.87</span> <span class="fl">4.41</span> <span class="fl">4.43</span> <span class="fl">1.67</span> <span class="fl">0.83</span> <span class="fl">2.85</span> <span class="fl">1.34</span> <span class="fl">0.67</span> <span class="fl">1.06</span> <span class="fl">1.14</span> ...</span> <span id="sha1_lm-48"><a href="#sha1_lm-48" aria-hidden="true" tabindex="-1"></a> ..<span class="sc">$</span> dpi <span class="sc">:</span> num [<span class="dv">1</span><span class="sc">:</span><span class="dv">50</span>] <span class="dv">2330</span> <span class="dv">1508</span> <span class="dv">2108</span> <span class="dv">189</span> <span class="dv">728</span> ...</span> <span id="sha1_lm-49"><a href="#sha1_lm-49" aria-hidden="true" tabindex="-1"></a> ..<span class="sc">$</span> ddpi <span class="sc">:</span> num [<span class="dv">1</span><span class="sc">:</span><span class="dv">50</span>] <span class="fl">2.87</span> <span class="fl">3.93</span> <span class="fl">3.82</span> <span class="fl">0.22</span> <span class="fl">4.56</span> <span class="fl">2.43</span> <span class="fl">2.67</span> <span class="fl">6.51</span> <span class="fl">3.08</span> <span class="fl">2.8</span> ...</span> <span id="sha1_lm-50"><a href="#sha1_lm-50" aria-hidden="true" tabindex="-1"></a> ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"terms"</span>)<span class="ot">=</span>Classes <span class="st">'terms'</span>, <span class="st">'formula'</span> language sr <span class="sc">~</span> pop15 <span class="sc">+</span> pop75 <span class="sc">+</span> dpi <span class="sc">+</span> ddpi</span> <span id="sha1_lm-51"><a href="#sha1_lm-51" aria-hidden="true" tabindex="-1"></a> .. .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"variables"</span>)<span class="ot">=</span> language <span class="fu">list</span>(sr, pop15, pop75, dpi, ddpi)</span> <span id="sha1_lm-52"><a href="#sha1_lm-52" aria-hidden="true" tabindex="-1"></a> .. .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"factors"</span>)<span class="ot">=</span> int [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>, <span class="dv">1</span><span class="sc">:</span><span class="dv">4</span>] <span class="dv">0</span> <span class="dv">1</span> <span class="dv">0</span> <span class="dv">0</span> <span class="dv">0</span> <span class="dv">0</span> <span class="dv">0</span> <span class="dv">1</span> <span class="dv">0</span> <span class="dv">0</span> ...</span> <span id="sha1_lm-53"><a href="#sha1_lm-53" aria-hidden="true" tabindex="-1"></a> .. .. .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"dimnames"</span>)<span class="ot">=</span>List of <span class="dv">2</span></span> <span id="sha1_lm-54"><a href="#sha1_lm-54" aria-hidden="true" tabindex="-1"></a> .. .. .. .. ..<span class="sc">$</span> <span class="er">:</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="st">"sr"</span> <span class="st">"pop15"</span> <span class="st">"pop75"</span> <span class="st">"dpi"</span> ...</span> <span id="sha1_lm-55"><a href="#sha1_lm-55" aria-hidden="true" tabindex="-1"></a> .. .. .. .. ..<span class="sc">$</span> <span class="er">:</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">4</span>] <span class="st">"pop15"</span> <span class="st">"pop75"</span> <span class="st">"dpi"</span> <span class="st">"ddpi"</span></span> <span id="sha1_lm-56"><a href="#sha1_lm-56" aria-hidden="true" tabindex="-1"></a> .. .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"term.labels"</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">4</span>] <span class="st">"pop15"</span> <span class="st">"pop75"</span> <span class="st">"dpi"</span> <span class="st">"ddpi"</span></span> <span id="sha1_lm-57"><a href="#sha1_lm-57" aria-hidden="true" tabindex="-1"></a> .. .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"order"</span>)<span class="ot">=</span> int [<span class="dv">1</span><span class="sc">:</span><span class="dv">4</span>] <span class="dv">1</span> <span class="dv">1</span> <span class="dv">1</span> <span class="dv">1</span></span> <span id="sha1_lm-58"><a href="#sha1_lm-58" aria-hidden="true" tabindex="-1"></a> .. .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"intercept"</span>)<span class="ot">=</span> int <span class="dv">1</span></span> <span id="sha1_lm-59"><a href="#sha1_lm-59" aria-hidden="true" tabindex="-1"></a> .. .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"response"</span>)<span class="ot">=</span> int <span class="dv">1</span></span> <span id="sha1_lm-60"><a href="#sha1_lm-60" aria-hidden="true" tabindex="-1"></a> .. .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">".Environment"</span>)<span class="ot">=</span><span class="er"><</span>environment<span class="sc">:</span> R_GlobalEnv<span class="sc">></span> </span> <span id="sha1_lm-61"><a href="#sha1_lm-61" aria-hidden="true" tabindex="-1"></a> .. .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"predvars"</span>)<span class="ot">=</span> language <span class="fu">list</span>(sr, pop15, pop75, dpi, ddpi)</span> <span id="sha1_lm-62"><a href="#sha1_lm-62" aria-hidden="true" tabindex="-1"></a> .. .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"dataClasses"</span>)<span class="ot">=</span> Named chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="st">"numeric"</span> <span class="st">"numeric"</span> <span class="st">"numeric"</span> <span class="st">"numeric"</span> ...</span> <span id="sha1_lm-63"><a href="#sha1_lm-63" aria-hidden="true" tabindex="-1"></a> .. .. .. ..<span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"names"</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="st">"sr"</span> <span class="st">"pop15"</span> <span class="st">"pop75"</span> <span class="st">"dpi"</span> ...</span> <span id="sha1_lm-64"><a href="#sha1_lm-64" aria-hidden="true" tabindex="-1"></a> <span class="sc">-</span> <span class="fu">attr</span>(<span class="sc">*</span>, <span class="st">"class"</span>)<span class="ot">=</span> chr <span class="st">"lm"</span></span> <span id="sha1_lm-65"><a href="#sha1_lm-65" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="co"># extract the model and the terms</span></span> <span id="sha1_lm-66"><a href="#sha1_lm-66" aria-hidden="true" tabindex="-1"></a><span class="er">></span> lm_model <span class="ot"><-</span> lm_SR<span class="sc">$</span>model</span> <span id="sha1_lm-67"><a href="#sha1_lm-67" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> lm_terms <span class="ot"><-</span> lm_SR<span class="sc">$</span>terms</span> <span id="sha1_lm-68"><a href="#sha1_lm-68" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="co"># check their class</span></span> <span id="sha1_lm-69"><a href="#sha1_lm-69" aria-hidden="true" tabindex="-1"></a><span class="er">></span> <span class="fu">class</span>(lm_model) <span class="co"># handled by sha1()</span></span> <span id="sha1_lm-70"><a href="#sha1_lm-70" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>] <span class="st">"data.frame"</span></span> <span id="sha1_lm-71"><a href="#sha1_lm-71" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="fu">class</span>(lm_terms) <span class="co"># not handled by sha1()</span></span> <span id="sha1_lm-72"><a href="#sha1_lm-72" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>] <span class="st">"terms"</span> <span class="st">"formula"</span></span> <span id="sha1_lm-73"><a href="#sha1_lm-73" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="co"># define a method for formula</span></span> <span id="sha1_lm-74"><a href="#sha1_lm-74" aria-hidden="true" tabindex="-1"></a><span class="er">></span> sha1.formula <span class="ot"><-</span> <span class="cf">function</span>(x, <span class="at">digits =</span> <span class="dv">14</span>, <span class="at">zapsmall =</span> <span class="dv">7</span>, ..., <span class="at">algo =</span> <span class="st">"sha1"</span>){</span> <span id="sha1_lm-75"><a href="#sha1_lm-75" aria-hidden="true" tabindex="-1"></a><span class="sc">+</span> <span class="fu">sha1</span>(<span class="fu">as.character</span>(x), <span class="at">digits =</span> digits, <span class="at">zapsmall =</span> zapsmall, <span class="at">algo =</span> algo)</span> <span id="sha1_lm-76"><a href="#sha1_lm-76" aria-hidden="true" tabindex="-1"></a><span class="sc">+</span> }</span> <span id="sha1_lm-77"><a href="#sha1_lm-77" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="fu">sha1</span>(lm_terms)</span> <span id="sha1_lm-78"><a href="#sha1_lm-78" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>] <span class="st">"2737d209720aa7d1c0555050ad06ebe89f3850cd"</span></span> <span id="sha1_lm-79"><a href="#sha1_lm-79" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="fu">sha1</span>(lm_model)</span> <span id="sha1_lm-80"><a href="#sha1_lm-80" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>] <span class="st">"27b7dd9e3e09b9577da6947b8473b63a1d0b6eb4"</span></span> <span id="sha1_lm-81"><a href="#sha1_lm-81" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="co"># define a method for lm</span></span> <span id="sha1_lm-82"><a href="#sha1_lm-82" aria-hidden="true" tabindex="-1"></a><span class="er">></span> sha1.lm <span class="ot"><-</span> <span class="cf">function</span>(x, <span class="at">digits =</span> <span class="dv">14</span>, <span class="at">zapsmall =</span> <span class="dv">7</span>, ..., <span class="at">algo =</span> <span class="st">"sha1"</span>){</span> <span id="sha1_lm-83"><a href="#sha1_lm-83" aria-hidden="true" tabindex="-1"></a><span class="sc">+</span> lm_model <span class="ot"><-</span> x<span class="sc">$</span>model</span> <span id="sha1_lm-84"><a href="#sha1_lm-84" aria-hidden="true" tabindex="-1"></a><span class="sc">+</span> lm_terms <span class="ot"><-</span> x<span class="sc">$</span>terms</span> <span id="sha1_lm-85"><a href="#sha1_lm-85" aria-hidden="true" tabindex="-1"></a><span class="sc">+</span> combined <span class="ot"><-</span> <span class="fu">list</span>(lm_model, lm_terms)</span> <span id="sha1_lm-86"><a href="#sha1_lm-86" aria-hidden="true" tabindex="-1"></a><span class="sc">+</span> <span class="fu">sha1</span>(combined, <span class="at">digits =</span> digits, <span class="at">zapsmall =</span> zapsmall, ..., <span class="at">algo =</span> algo)</span> <span id="sha1_lm-87"><a href="#sha1_lm-87" aria-hidden="true" tabindex="-1"></a><span class="sc">+</span> }</span> <span id="sha1_lm-88"><a href="#sha1_lm-88" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="fu">sha1</span>(lm_SR)</span> <span id="sha1_lm-89"><a href="#sha1_lm-89" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>] <span class="st">"7eda2a9d58e458c8e782e40ce140d62b836b2a2f"</span></span> <span id="sha1_lm-90"><a href="#sha1_lm-90" aria-hidden="true" tabindex="-1"></a><span class="sc">></span> <span class="fu">sha1</span>(lm_SR2)</span> <span id="sha1_lm-91"><a href="#sha1_lm-91" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>] <span class="st">"4d3abdb1f17bd12fdf9d9b91a2ad04c07824fe4a"</span></span></code></pre></div> <h2 id="using-hashes-to-track-changes-in-analysis">Using hashes to track changes in analysis</h2> <p>Use case</p> <ul> <li><p>automated analysis</p></li> <li><p>update frequency of the data might be lower than the frequency of automated analysis</p></li> <li><p>similar analyses on many datasets (e.g. many species in ecology)</p></li> <li><p>analyses that require a lot of computing time</p> <ul> <li>not rerunning an analysis because nothing has changed saves enough resources to compensate the overhead of tracking changes</li> </ul></li> <li><p>Bundle all relevant information on an analysis in a class</p> <ul> <li>data</li> <li>method</li> <li>formula</li> <li>other metadata</li> <li>resulting model</li> </ul></li> <li><p>calculate <code>sha1()</code></p> <p>file fingerprint ~ <code>sha1()</code> on the stable parts</p> <p>status fingerprint ~ <code>sha1()</code> on the parts that result for the model</p></li> </ul> <ol type="1"> <li>Prepare analysis objects</li> <li>Store each analysis object in a rda file which uses the file fingerprint as filename <ul> <li>File will already exist when no change in analysis</li> <li>Don’t overwrite existing files</li> </ul></li> <li>Loop over all rda files <ul> <li>Do nothing if the analysis was run</li> <li>Otherwise run the analysis and update the status and status fingerprint</li> </ul></li> </ol> </body> </html>