2025-01-12 04:36:52 +08:00

538 lines
69 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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">&gt;</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">&gt;</span> a0 <span class="ot">&lt;-</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">&gt;</span> b <span class="ot">&lt;-</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">&gt;</span> a1 <span class="ot">&lt;-</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">&gt;</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">&gt;</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">&gt;</span> a <span class="ot">&lt;-</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">&gt;</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">&gt;</span> <span class="fu">sprintf</span>(<span class="st">&quot;%a&quot;</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">&quot;0x1p+1&quot;</span> <span class="st">&quot;0x1.0000000000001p+1&quot;</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">&gt;</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">&gt;</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">&gt;</span> <span class="fu">sapply</span>(a, digest, <span class="at">algo =</span> <span class="st">&quot;sha1&quot;</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">&quot;315a5aa84aa6cfa4f3fb4b652a596770be0365e8&quot;</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">&quot;5e3999bf79c230f7430e97d7f30070a7eff5ec92&quot;</span></span>
<span id="faq7_31digest-6"><a href="#faq7_31digest-6" aria-hidden="true" tabindex="-1"></a><span class="sc">&gt;</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">&gt;</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">&quot;8a938d8f5fb9b8ccb6893aa1068babcc517f32d4&quot;</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">&quot;8a938d8f5fb9b8ccb6893aa1068babcc517f32d4&quot;</span></span>
<span id="faq7_31digest-10"><a href="#faq7_31digest-10" aria-hidden="true" tabindex="-1"></a><span class="sc">&gt;</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">&gt;</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">&quot;98eb1dc9fada00b945d3ef01c77049ee5a4b7b9c&quot;</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">&quot;5a173e2445df1134908037f69ac005fbd8afee74&quot;</span></span>
<span id="faq7_31digest-14"><a href="#faq7_31digest-14" aria-hidden="true" tabindex="-1"></a><span class="sc">&gt;</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">&gt;</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">&gt;</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">&gt;</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">&quot;43b3b465c975af322c85473190a9214b79b79bf6&quot;</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">&quot;43b3b465c975af322c85473190a9214b79b79bf6&quot;</span></span>
<span id="faq7_31digest-20"><a href="#faq7_31digest-20" aria-hidden="true" tabindex="-1"></a><span class="sc">&gt;</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">&quot;6b537a9693c750ed535ca90527152f06e358aa3a&quot;</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">&quot;6b537a9693c750ed535ca90527152f06e358aa3a&quot;</span></span>
<span id="faq7_31digest-23"><a href="#faq7_31digest-23" aria-hidden="true" tabindex="-1"></a><span class="sc">&gt;</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">&gt;</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">&quot;169388cf1ce60dc4e9904a22bc934c5db33d975b&quot;</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">&quot;20dc38536b6689d5f2d053f30efb09c44af78378&quot;</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">&quot;3a727417bd1807af2f0148cf3de69abff32c23ec&quot;</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(&quot;%a&quot;, pi ^ 11)</code></td>
<td style="text-align: left;"><code>&quot;0x1.1f4f01267bf5fp+18&quot;</code></td>
<td style="text-align: left;"><code>&quot;0x1.1f4f01267bf6p+18&quot;</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>digest(pi ^ 11, algo = &quot;sha1&quot;)</code></td>
<td style="text-align: left;"><code>&quot;c5efc7f167df1bb402b27cf9b405d7cebfba339a&quot;</code></td>
<td style="text-align: left;"><code>&quot;b61f6fea5e2a7952692cefe8bba86a00af3de713&quot;</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>&quot;5c7740500b8f78ec2354ea6af58ea69634d9b7b1&quot;</code></td>
<td style="text-align: left;"><code>&quot;4f3e296b9922a7ddece2183b1478d0685609a359&quot;</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>&quot;372289f87396b0877ccb4790cf40bcb5e658cad7&quot;</code></td>
<td style="text-align: left;"><code>&quot;372289f87396b0877ccb4790cf40bcb5e658cad7&quot;</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>&quot;c05965af43f9566bfb5622f335817f674abfc9e4&quot;</code></td>
<td style="text-align: left;"><code>&quot;c05965af43f9566bfb5622f335817f674abfc9e4&quot;</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>Lets 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">&gt;</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">&gt;</span> lm_SR <span class="ot">&lt;-</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">&gt;</span> lm_sum <span class="ot">&lt;-</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">&gt;</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">&quot;summary.lm&quot;</span></span>
<span id="sha1_lm_sum-6"><a href="#sha1_lm_sum-6" aria-hidden="true" tabindex="-1"></a><span class="sc">&gt;</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">&gt;</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">&#39;terms&#39;</span>, <span class="st">&#39;formula&#39;</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">&quot;variables&quot;</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">&quot;factors&quot;</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">&quot;dimnames&quot;</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">&quot;sr&quot;</span> <span class="st">&quot;pop15&quot;</span> <span class="st">&quot;pop75&quot;</span> <span class="st">&quot;dpi&quot;</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">&quot;pop15&quot;</span> <span class="st">&quot;pop75&quot;</span> <span class="st">&quot;dpi&quot;</span> <span class="st">&quot;ddpi&quot;</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">&quot;term.labels&quot;</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">4</span>] <span class="st">&quot;pop15&quot;</span> <span class="st">&quot;pop75&quot;</span> <span class="st">&quot;dpi&quot;</span> <span class="st">&quot;ddpi&quot;</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">&quot;order&quot;</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">&quot;intercept&quot;</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">&quot;response&quot;</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">&quot;.Environment&quot;</span>)<span class="ot">=</span><span class="er">&lt;</span>environment<span class="sc">:</span> R_GlobalEnv<span class="sc">&gt;</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">&quot;predvars&quot;</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">&quot;dataClasses&quot;</span>)<span class="ot">=</span> Named chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="st">&quot;numeric&quot;</span> <span class="st">&quot;numeric&quot;</span> <span class="st">&quot;numeric&quot;</span> <span class="st">&quot;numeric&quot;</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">&quot;names&quot;</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="st">&quot;sr&quot;</span> <span class="st">&quot;pop15&quot;</span> <span class="st">&quot;pop75&quot;</span> <span class="st">&quot;dpi&quot;</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">&quot;names&quot;</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">50</span>] <span class="st">&quot;Australia&quot;</span> <span class="st">&quot;Austria&quot;</span> <span class="st">&quot;Belgium&quot;</span> <span class="st">&quot;Bolivia&quot;</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">&quot;dimnames&quot;</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">&quot;(Intercept)&quot;</span> <span class="st">&quot;pop15&quot;</span> <span class="st">&quot;pop75&quot;</span> <span class="st">&quot;dpi&quot;</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">&quot;Estimate&quot;</span> <span class="st">&quot;Std. Error&quot;</span> <span class="st">&quot;t value&quot;</span> <span class="st">&quot;Pr(&gt;|t|)&quot;</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">&quot;names&quot;</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="st">&quot;(Intercept)&quot;</span> <span class="st">&quot;pop15&quot;</span> <span class="st">&quot;pop75&quot;</span> <span class="st">&quot;dpi&quot;</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">&quot;names&quot;</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">3</span>] <span class="st">&quot;value&quot;</span> <span class="st">&quot;numdf&quot;</span> <span class="st">&quot;dendf&quot;</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">&quot;dimnames&quot;</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">&quot;(Intercept)&quot;</span> <span class="st">&quot;pop15&quot;</span> <span class="st">&quot;pop75&quot;</span> <span class="st">&quot;dpi&quot;</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">&quot;(Intercept)&quot;</span> <span class="st">&quot;pop15&quot;</span> <span class="st">&quot;pop75&quot;</span> <span class="st">&quot;dpi&quot;</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">&quot;class&quot;</span>)<span class="ot">=</span> chr <span class="st">&quot;summary.lm&quot;</span></span>
<span id="sha1_lm_sum-43"><a href="#sha1_lm_sum-43" aria-hidden="true" tabindex="-1"></a><span class="sc">&gt;</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">&gt;</span> coef_sum <span class="ot">&lt;-</span> <span class="fu">coef</span>(lm_sum)[, <span class="fu">c</span>(<span class="st">&quot;Estimate&quot;</span>, <span class="st">&quot;Std. Error&quot;</span>)]</span>
<span id="sha1_lm_sum-45"><a href="#sha1_lm_sum-45" aria-hidden="true" tabindex="-1"></a><span class="sc">&gt;</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">&gt;</span> sigma <span class="ot">&lt;-</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">&gt;</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">&gt;</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">&quot;matrix&quot;</span> <span class="st">&quot;array&quot;</span> </span>
<span id="sha1_lm_sum-50"><a href="#sha1_lm_sum-50" aria-hidden="true" tabindex="-1"></a><span class="sc">&gt;</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">&quot;numeric&quot;</span></span>
<span id="sha1_lm_sum-52"><a href="#sha1_lm_sum-52" aria-hidden="true" tabindex="-1"></a><span class="sc">&gt;</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">&gt;</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">&gt;</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">&quot;3f0b0c552f94d753fcc8deb4d3e9fc11a83197af&quot;</span></span>
<span id="sha1_lm_sum-56"><a href="#sha1_lm_sum-56" aria-hidden="true" tabindex="-1"></a><span class="sc">&gt;</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">&quot;cbc83d1791ef1eeadd824ea9a038891b5889056b&quot;</span></span>
<span id="sha1_lm_sum-58"><a href="#sha1_lm_sum-58" aria-hidden="true" tabindex="-1"></a><span class="sc">&gt;</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">&gt;</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">&gt;</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">&quot;476d27265365cd41662eedf059b335d38a221cc2&quot;</span></span>
<span id="sha1_lm_sum-62"><a href="#sha1_lm_sum-62" aria-hidden="true" tabindex="-1"></a><span class="sc">&gt;</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">&gt;</span> <span class="co"># - a function with name &quot;sha1.classname&quot;</span></span>
<span id="sha1_lm_sum-64"><a href="#sha1_lm_sum-64" aria-hidden="true" tabindex="-1"></a><span class="er">&gt;</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">&gt;</span> sha1.summary.lm <span class="ot">&lt;-</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">&lt;-</span> <span class="fu">coef</span>(x)[, <span class="fu">c</span>(<span class="st">&quot;Estimate&quot;</span>, <span class="st">&quot;Std. Error&quot;</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">&lt;-</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">&lt;-</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">&gt;</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">&quot;476d27265365cd41662eedf059b335d38a221cc2&quot;</span></span>
<span id="sha1_lm_sum-73"><a href="#sha1_lm_sum-73" aria-hidden="true" tabindex="-1"></a><span class="sc">&gt;</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">&gt;</span> LCS2 <span class="ot">&lt;-</span> LifeCycleSavings[<span class="fu">rownames</span>(LifeCycleSavings) <span class="sc">!=</span> <span class="st">&quot;Zambia&quot;</span>, ]</span>
<span id="sha1_lm_sum-75"><a href="#sha1_lm_sum-75" aria-hidden="true" tabindex="-1"></a><span class="sc">&gt;</span> lm_SR2 <span class="ot">&lt;-</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">&gt;</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">&quot;90beb028833bf0542997fde7c3f19e5b9fdfeef4&quot;</span></span></code></pre></div>
<h3 id="lm">lm</h3>
<p>Lets 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">&gt;</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">&quot;lm&quot;</span></span>
<span id="sha1_lm-3"><a href="#sha1_lm-3" aria-hidden="true" tabindex="-1"></a><span class="sc">&gt;</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">&gt;</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">&quot;names&quot;</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="st">&quot;(Intercept)&quot;</span> <span class="st">&quot;pop15&quot;</span> <span class="st">&quot;pop75&quot;</span> <span class="st">&quot;dpi&quot;</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">&quot;names&quot;</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">50</span>] <span class="st">&quot;Australia&quot;</span> <span class="st">&quot;Austria&quot;</span> <span class="st">&quot;Belgium&quot;</span> <span class="st">&quot;Bolivia&quot;</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">&quot;names&quot;</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">50</span>] <span class="st">&quot;(Intercept)&quot;</span> <span class="st">&quot;pop15&quot;</span> <span class="st">&quot;pop75&quot;</span> <span class="st">&quot;dpi&quot;</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">&quot;names&quot;</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">50</span>] <span class="st">&quot;Australia&quot;</span> <span class="st">&quot;Austria&quot;</span> <span class="st">&quot;Belgium&quot;</span> <span class="st">&quot;Bolivia&quot;</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">&quot;dimnames&quot;</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">&quot;Australia&quot;</span> <span class="st">&quot;Austria&quot;</span> <span class="st">&quot;Belgium&quot;</span> <span class="st">&quot;Bolivia&quot;</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">&quot;(Intercept)&quot;</span> <span class="st">&quot;pop15&quot;</span> <span class="st">&quot;pop75&quot;</span> <span class="st">&quot;dpi&quot;</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">&quot;assign&quot;</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">&quot;class&quot;</span>)<span class="ot">=</span> chr <span class="st">&quot;qr&quot;</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">&#39;terms&#39;</span>, <span class="st">&#39;formula&#39;</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">&quot;variables&quot;</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">&quot;factors&quot;</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">&quot;dimnames&quot;</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">&quot;sr&quot;</span> <span class="st">&quot;pop15&quot;</span> <span class="st">&quot;pop75&quot;</span> <span class="st">&quot;dpi&quot;</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">&quot;pop15&quot;</span> <span class="st">&quot;pop75&quot;</span> <span class="st">&quot;dpi&quot;</span> <span class="st">&quot;ddpi&quot;</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">&quot;term.labels&quot;</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">4</span>] <span class="st">&quot;pop15&quot;</span> <span class="st">&quot;pop75&quot;</span> <span class="st">&quot;dpi&quot;</span> <span class="st">&quot;ddpi&quot;</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">&quot;order&quot;</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">&quot;intercept&quot;</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">&quot;response&quot;</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">&quot;.Environment&quot;</span>)<span class="ot">=</span><span class="er">&lt;</span>environment<span class="sc">:</span> R_GlobalEnv<span class="sc">&gt;</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">&quot;predvars&quot;</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">&quot;dataClasses&quot;</span>)<span class="ot">=</span> Named chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="st">&quot;numeric&quot;</span> <span class="st">&quot;numeric&quot;</span> <span class="st">&quot;numeric&quot;</span> <span class="st">&quot;numeric&quot;</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">&quot;names&quot;</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="st">&quot;sr&quot;</span> <span class="st">&quot;pop15&quot;</span> <span class="st">&quot;pop75&quot;</span> <span class="st">&quot;dpi&quot;</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">&#39;data.frame&#39;</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">&quot;terms&quot;</span>)<span class="ot">=</span>Classes <span class="st">&#39;terms&#39;</span>, <span class="st">&#39;formula&#39;</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">&quot;variables&quot;</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">&quot;factors&quot;</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">&quot;dimnames&quot;</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">&quot;sr&quot;</span> <span class="st">&quot;pop15&quot;</span> <span class="st">&quot;pop75&quot;</span> <span class="st">&quot;dpi&quot;</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">&quot;pop15&quot;</span> <span class="st">&quot;pop75&quot;</span> <span class="st">&quot;dpi&quot;</span> <span class="st">&quot;ddpi&quot;</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">&quot;term.labels&quot;</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">4</span>] <span class="st">&quot;pop15&quot;</span> <span class="st">&quot;pop75&quot;</span> <span class="st">&quot;dpi&quot;</span> <span class="st">&quot;ddpi&quot;</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">&quot;order&quot;</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">&quot;intercept&quot;</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">&quot;response&quot;</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">&quot;.Environment&quot;</span>)<span class="ot">=</span><span class="er">&lt;</span>environment<span class="sc">:</span> R_GlobalEnv<span class="sc">&gt;</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">&quot;predvars&quot;</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">&quot;dataClasses&quot;</span>)<span class="ot">=</span> Named chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="st">&quot;numeric&quot;</span> <span class="st">&quot;numeric&quot;</span> <span class="st">&quot;numeric&quot;</span> <span class="st">&quot;numeric&quot;</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">&quot;names&quot;</span>)<span class="ot">=</span> chr [<span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>] <span class="st">&quot;sr&quot;</span> <span class="st">&quot;pop15&quot;</span> <span class="st">&quot;pop75&quot;</span> <span class="st">&quot;dpi&quot;</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">&quot;class&quot;</span>)<span class="ot">=</span> chr <span class="st">&quot;lm&quot;</span></span>
<span id="sha1_lm-65"><a href="#sha1_lm-65" aria-hidden="true" tabindex="-1"></a><span class="sc">&gt;</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">&gt;</span> lm_model <span class="ot">&lt;-</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">&gt;</span> lm_terms <span class="ot">&lt;-</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">&gt;</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">&gt;</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">&quot;data.frame&quot;</span></span>
<span id="sha1_lm-71"><a href="#sha1_lm-71" aria-hidden="true" tabindex="-1"></a><span class="sc">&gt;</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">&quot;terms&quot;</span> <span class="st">&quot;formula&quot;</span></span>
<span id="sha1_lm-73"><a href="#sha1_lm-73" aria-hidden="true" tabindex="-1"></a><span class="sc">&gt;</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">&gt;</span> sha1.formula <span class="ot">&lt;-</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">&quot;sha1&quot;</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">&gt;</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">&quot;2737d209720aa7d1c0555050ad06ebe89f3850cd&quot;</span></span>
<span id="sha1_lm-79"><a href="#sha1_lm-79" aria-hidden="true" tabindex="-1"></a><span class="sc">&gt;</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">&quot;27b7dd9e3e09b9577da6947b8473b63a1d0b6eb4&quot;</span></span>
<span id="sha1_lm-81"><a href="#sha1_lm-81" aria-hidden="true" tabindex="-1"></a><span class="sc">&gt;</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">&gt;</span> sha1.lm <span class="ot">&lt;-</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">&quot;sha1&quot;</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">&lt;-</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">&lt;-</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">&lt;-</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">&gt;</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">&quot;7eda2a9d58e458c8e782e40ce140d62b836b2a2f&quot;</span></span>
<span id="sha1_lm-90"><a href="#sha1_lm-90" aria-hidden="true" tabindex="-1"></a><span class="sc">&gt;</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">&quot;4d3abdb1f17bd12fdf9d9b91a2ad04c07824fe4a&quot;</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>Dont 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>