1
0
caret-and-bigstatsr-workshop/slides.html

408 lines
165 KiB
HTML
Raw Permalink Normal View History

2025-01-11 04:05:22 +00:00
<!DOCTYPE html><html lang="en-US"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,height=device-height,initial-scale=1.0"><meta name="apple-mobile-web-app-capable" content="yes"><meta http-equiv="X-UA-Compatible" content="ie=edge"><meta property="og:type" content="website"><meta name="twitter:card" content="summary"><style>@media screen{body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>button,body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>button,body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-info-container button,body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-note-container button{-webkit-tap-highlight-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border:0;color:inherit;cursor:pointer;font-size:inherit;opacity:.8;outline:none;padding:0;transition:opacity .2s linear}body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>button:disabled,body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>button:disabled,body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-info-container button:disabled,body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-note-container button:disabled{cursor:not-allowed;opacity:.15!important}body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>button:hover,body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>button:hover,body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-info-container button:hover,body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-note-container button:hover{opacity:1}body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>button:hover:active,body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>button:hover:active,body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-info-container button:hover:active,body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-note-container button:hover:active{opacity:.6}body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>button:hover:not(:disabled),body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>button:hover:not(:disabled),body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-info-container button:hover:not(:disabled),body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-note-container button:hover:not(:disabled){transition:none}body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=prev],body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=prev],body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-info-container button.bespoke-marp-presenter-info-page-prev{background:transparent url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSI1IiBkPSJNNjggOTAgMjggNTBsNDAtNDAiLz48L3N2Zz4=") no-repeat 50%;background-size:contain;overflow:hidden;text-indent:100%;white-space:nowrap}body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=next],body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=next],body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-info-container button.bespoke-marp-presenter-info-page-next{background:transparent url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc
/*!
* Marp default theme.
*
* @theme default
* @author Yuki Hattori
*
* @auto-scaling true
* @size 16:9 1280px 720px
* @size 4:3 960px 720px
*/div#p>svg>foreignObject>section{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;word-wrap:break-word;background-color:#fff;color:#24292f;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;font-size:16px;line-height:1.5;margin:0}div#p>svg>foreignObject>section{--marpit-root-font-size:16px}div#p>svg>foreignObject>section h1:hover .anchor .octicon-link:before,div#p>svg>foreignObject>section h2:hover .anchor .octicon-link:before,div#p>svg>foreignObject>section h3:hover .anchor .octicon-link:before,div#p>svg>foreignObject>section h4:hover .anchor .octicon-link:before,div#p>svg>foreignObject>section h5:hover .anchor .octicon-link:before,div#p>svg>foreignObject>section h6:hover .anchor .octicon-link:before{background-color:currentColor;content:" ";display:inline-block;height:16px;-webkit-mask-image:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 0 0 1.06 1.06l1.25-1.25a2 2 0 1 1 2.83 2.83l-2.5 2.5a2 2 0 0 1-2.83 0 .75.75 0 0 0-1.06 1.06 3.5 3.5 0 0 0 4.95 0l2.5-2.5a3.5 3.5 0 0 0-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 0 1 0-2.83l2.5-2.5a2 2 0 0 1 2.83 0 .75.75 0 0 0 1.06-1.06 3.5 3.5 0 0 0-4.95 0l-2.5 2.5a3.5 3.5 0 0 0 4.95 4.95l1.25-1.25a.75.75 0 0 0-1.06-1.06l-1.25 1.25a2 2 0 0 1-2.83 0z"/></svg>');mask-image:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 0 0 1.06 1.06l1.25-1.25a2 2 0 1 1 2.83 2.83l-2.5 2.5a2 2 0 0 1-2.83 0 .75.75 0 0 0-1.06 1.06 3.5 3.5 0 0 0 4.95 0l2.5-2.5a3.5 3.5 0 0 0-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 0 1 0-2.83l2.5-2.5a2 2 0 0 1 2.83 0 .75.75 0 0 0 1.06-1.06 3.5 3.5 0 0 0-4.95 0l-2.5 2.5a3.5 3.5 0 0 0 4.95 4.95l1.25-1.25a.75.75 0 0 0-1.06-1.06l-1.25 1.25a2 2 0 0 1-2.83 0z"/></svg>');width:16px}div#p>svg>foreignObject>section details,div#p>svg>foreignObject>section figcaption,div#p>svg>foreignObject>section figure{display:block}div#p>svg>foreignObject>section summary{display:list-item}div#p>svg>foreignObject>section [hidden]{display:none!important}div#p>svg>foreignObject>section a{background-color:transparent;color:#0969da;text-decoration:none}div#p>svg>foreignObject>section a:active,div#p>svg>foreignObject>section a:hover{outline-width:0}div#p>svg>foreignObject>section abbr[title]{border-bottom:none;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}div#p>svg>foreignObject>section b,div#p>svg>foreignObject>section strong{font-weight:600}div#p>svg>foreignObject>section dfn{font-style:italic}div#p>svg>foreignObject>section h1{border-bottom:1px solid #d8dee4;font-size:2em;font-weight:600;margin:.67em 0;padding-bottom:.3em}div#p>svg>foreignObject>section mark{background-color:#fff8c5;color:#24292f}div#p>svg>foreignObject>section small{font-size:90%}div#p>svg>foreignObject>section sub,div#p>svg>foreignObject>section sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}div#p>svg>foreignObject>section sub{bottom:-.25em}div#p>svg>foreignObject>section sup{top:-.5em}div#p>svg>foreignObject>section img{background-color:#fff;border-style:none;box-sizing:content-box;max-width:100%}div#p>svg>foreignObject>section code,div#p>svg>foreignObject>section kbd,div#p>svg>foreignObject>section pre,div#p>svg>foreignObject>section samp{font-family:monospace,monospace;font-size:1em}div#p>svg>foreignObject>section figure{margin:1em 40px}div#p>svg>foreignObject>section hr{background:transparent;background-color:#d0d7de;border:0;box-sizing:content-box;height:.25em;margin:24px 0;overflow:hidden;padding:0}div#p>svg>foreignObject>section input{font:inherit;font-family:inherit;font-size:inherit;line-height:inherit;margin:0;overflow:visible}div#p>svg>foreignObject>section [type=button],div#p>svg>foreignObject>section [type=reset],div#p>svg>foreignObject>section [type=submit]{-webkit-appearance:button}div#p>svg>foreignObject>section [type=button]::-moz-focus-inner,div#p>svg>foreig
/* content:""; */display:table}div#p>svg>foreignObject>section:after{clear:both}div#p>svg>foreignObject>section>:first-child{margin-top:0!important}div#p>svg>foreignObject>section>:last-child{margin-bottom:0!important}div#p>svg>foreignObject>section a:not([href]){color:inherit;text-decoration:none}div#p>svg>foreignObject>section .absent{color:#cf222e}div#p>svg>foreignObject>section .anchor{float:left;line-height:1;margin-left:-20px;padding-right:4px}div#p>svg>foreignObject>section .anchor:focus{outline:none}div#p>svg>foreignObject>section blockquote,div#p>svg>foreignObject>section details,div#p>svg>foreignObject>section dl,div#p>svg>foreignObject>section ol,div#p>svg>foreignObject>section p,div#p>svg>foreignObject>section pre,div#p>svg>foreignObject>section table,div#p>svg>foreignObject>section ul{margin-bottom:16px;margin-top:0}div#p>svg>foreignObject>section blockquote>:first-child{margin-top:0}div#p>svg>foreignObject>section blockquote>:last-child{margin-bottom:0}div#p>svg>foreignObject>section sup>a:before{content:"["}div#p>svg>foreignObject>section sup>a:after{content:"]"}div#p>svg>foreignObject>section h1 .octicon-link,div#p>svg>foreignObject>section h2 .octicon-link,div#p>svg>foreignObject>section h3 .octicon-link,div#p>svg>foreignObject>section h4 .octicon-link,div#p>svg>foreignObject>section h5 .octicon-link,div#p>svg>foreignObject>section h6 .octicon-link{color:#24292f;vertical-align:middle;visibility:hidden}div#p>svg>foreignObject>section h1:hover .anchor,div#p>svg>foreignObject>section h2:hover .anchor,div#p>svg>foreignObject>section h3:hover .anchor,div#p>svg>foreignObject>section h4:hover .anchor,div#p>svg>foreignObject>section h5:hover .anchor,div#p>svg>foreignObject>section h6:hover .anchor{text-decoration:none}div#p>svg>foreignObject>section h1:hover .anchor .octicon-link,div#p>svg>foreignObject>section h2:hover .anchor .octicon-link,div#p>svg>foreignObject>section h3:hover .anchor .octicon-link,div#p>svg>foreignObject>section h4:hover .anchor .octicon-link,div#p>svg>foreignObject>section h5:hover .anchor .octicon-link,div#p>svg>foreignObject>section h6:hover .anchor .octicon-link{visibility:visible}div#p>svg>foreignObject>section h1 code,div#p>svg>foreignObject>section h1 tt,div#p>svg>foreignObject>section h2 code,div#p>svg>foreignObject>section h2 tt,div#p>svg>foreignObject>section h3 code,div#p>svg>foreignObject>section h3 tt,div#p>svg>foreignObject>section h4 code,div#p>svg>foreignObject>section h4 tt,div#p>svg>foreignObject>section h5 code,div#p>svg>foreignObject>section h5 tt,div#p>svg>foreignObject>section h6 code,div#p>svg>foreignObject>section h6 tt{font-size:inherit;padding:0 .2em}div#p>svg>foreignObject>section ol.no-list,div#p>svg>foreignObject>section ul.no-list{list-style-type:none;padding:0}div#p>svg>foreignObject>section ol[type="1"]{list-style-type:decimal}div#p>svg>foreignObject>section ol[type=a]{list-style-type:lower-alpha}div#p>svg>foreignObject>section ol[type=i]{list-style-type:lower-roman}div#p>svg>foreignObject>section div>ol:not([type]){list-style-type:decimal}div#p>svg>foreignObject>section ol ol,div#p>svg>foreignObject>section ol ul,div#p>svg>foreignObject>section ul ol,div#p>svg>foreignObject>section ul ul{margin-bottom:0;margin-top:0}div#p>svg>foreignObject>section li>p{margin-top:16px}div#p>svg>foreignObject>section li+li{margin-top:.25em}div#p>svg>foreignObject>section dl{padding:0}div#p>svg>foreignObject>section dl dt{font-size:1em;font-style:italic;font-weight:600;margin-top:16px;padding:0}div#p>svg>foreignObject>section dl dd{margin-bottom:16px;padding:0 16px}div#p>svg>foreignObject>section table th{font-weight:600}div#p>svg>foreignObject>section table td,div#p>svg>foreignObject>section table th{border:1px solid #d0d7de;padding:6px 13px}div#p>svg>foreignObject>section table tr{background-color:#fff;border-top:1px solid #d8dee4}div#p>svg>foreignObject>section table tr:nth-child(2n){background-color:#f6f8fa}div#p>svg>foreignObject>section table img{background-color:transparent}div#p>svg>foreignObject>section img[align=right]{padding-left:20px}div#p>svg>foreignObject>se
<p><img src="R_Logo.png" alt="" style="width:150px;" /></p>
<h1><code>caret</code> &amp; <code>bigstatsR</code> Workshop</h1>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="2" data-theme="default" style="--theme:default;">
<h1>Required Libraries</h1>
<pre><code class="language-r"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-comment"># &quot;bigstatsR&quot; and related packages.</span>
install.packages(<span class="hljs-string">&quot;bigstatsr&quot;</span>)
install.packages(<span class="hljs-string">&quot;bigreadr&quot;</span>)
install.packages(<span class="hljs-string">&quot;data.table&quot;</span>)
<span class="hljs-comment"># &quot;impute&quot; library.</span>
install.packages(<span class="hljs-string">&quot;BiocManager&quot;</span>)
BiocManager::install(<span class="hljs-string">&quot;impute&quot;</span>)
<span class="hljs-comment"># &quot;caret&quot; library and sample models.</span>
install.packages(<span class="hljs-string">&quot;caret&quot;</span>)
install.packages(<span class="hljs-string">&quot;glmnet&quot;</span>)
</span></span></foreignObject></svg></code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="3" data-theme="default" style="--theme:default;">
<h1>Getting Started</h1>
<ul>
<li>
<p>All files used in the workshop can be downloaded here:</p>
<ul>
<li><a href="https://cloud.ami.sc/s/gABPQGrrLa6cCiy">https://cloud.ami.sc/s/gABPQGrrLa6cCiy</a></li>
</ul>
</li>
<li>
<p>Throughout the workshop, you will need to fill out the missing code in the scripts, marked as <code>(...)</code>.</p>
</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="4" data-theme="default" style="--theme:default;">
<p><img src="R_Logo.png" alt="" style="width:150px;" /></p>
<h1><code>bigstatsR</code> Package</h1>
<blockquote>
<p>Provides functions for fast statistical analysis of large-scale data encoded as matrices. The package can handle matrices that are too large to fit in memory thanks to memory-mapping to binary files on disk.</p>
</blockquote>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="5" data-theme="default" style="--theme:default;">
<h1>Reading Files with <code>bigstatsR</code> [1]</h1>
<pre><code class="language-r"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-comment"># Read only the first row of the file.</span>
<span class="hljs-comment"># This allows us to obtain the number of columns.</span>
first_row &lt;- fread2(<span class="hljs-string">&quot;Test_Genotype_Data.csv&quot;</span>,
nrows = <span class="hljs-number">1</span>)
col_num &lt;- ncol(first_row)
<span class="hljs-comment"># Read the entire file using big_read.</span>
gen_data &lt;- big_read(<span class="hljs-string">&quot;Test_Genotype_Data.csv&quot;</span>, <span class="hljs-comment"># Our large data file.</span>
select = <span class="hljs-number">1</span>:col_num, <span class="hljs-comment"># The number of columns we want to read.</span>
backingfile = <span class="hljs-string">&quot;Data&quot;</span>, <span class="hljs-comment"># Path to the backing file.</span>
progress = <span class="hljs-literal">TRUE</span>, <span class="hljs-comment"># Show progress.</span>
type = <span class="hljs-string">&quot;double&quot;</span>) <span class="hljs-comment"># Data type of the contents.</span>
</span></span></foreignObject></svg></code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="6" data-theme="default" style="--theme:default;">
<h1>Reading Files with <code>bigstatsR</code> [2]</h1>
<ul>
<li>Our file will be read as a Filebacked Big Matrix (FBM).</li>
<li>After executing the code, we should see the following:</li>
</ul>
<pre><code class="language-r"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap>&gt; gen_data
A Filebacked Big Matrix of type <span class="hljs-string">&#x27;double&#x27;</span> with <span class="hljs-number">1000</span> rows and <span class="hljs-number">1000</span> columns.
</span></span></foreignObject></svg></code></pre>
<ul>
<li>Be careful to remove the backing files before trying to re-read the same file.</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="7" data-theme="default" style="--theme:default;">
<h1>Working with FBMs [1]</h1>
<ul>
<li>We can interact with FBMs <em>in a similar manner</em> as we do with normal dataframes.</li>
</ul>
<pre><code class="language-r"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-comment"># Examine the data.</span>
gen_data
gen_data[<span class="hljs-number">1</span>:<span class="hljs-number">10</span>, <span class="hljs-number">1</span>:<span class="hljs-number">10</span>]
str(gen_data)
</span></span></foreignObject></svg></code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="8" data-theme="default" style="--theme:default;">
<h1>Working with FBMs [2]</h1>
<ul>
<li>Functions need to be applied differently.</li>
<li>Say we wanted to find out the number of missing values in our data.</li>
<li>The following approach does not work anymore:</li>
</ul>
<pre><code class="language-r"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-comment"># Will not work!</span>
<span class="hljs-built_in">sum</span>(<span class="hljs-built_in">is.na</span>(gen_data))
</span></span></foreignObject></svg></code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="9" data-theme="default" style="--theme:default;">
<h1>Applying Functions [1]</h1>
<ul>
<li>In order for the function to be applied, we need to define it separately and use <code>big_apply</code>.</li>
<li>Our function <strong>must</strong> take the following as arguments:
<ul>
<li>An FBM object: <code>X</code></li>
<li>A vector of indices: <code>ind</code></li>
</ul>
</li>
</ul>
<pre><code class="language-r"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-comment"># Function for checking the number of missing values in the dataframe.</span>
check_na &lt;- <span class="hljs-keyword">function</span>(X, ind) {
<span class="hljs-built_in">sum</span>(<span class="hljs-built_in">is.na</span>(X[, ind]))
}
</span></span></foreignObject></svg></code></pre>
<ul>
<li><code>big_apply</code> will take care of splitting our data into subsets, applying our function to each subset, and combining the results.</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="10" data-theme="default" style="--theme:default;">
<h1>Applying Functions [2]</h1>
<ul>
<li>Now, we can find the number of missing values in our dataset.</li>
</ul>
<pre><code class="language-r"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-comment"># Check how many missing values we have.</span>
big_apply(gen_data, <span class="hljs-comment"># FBM to which we want to apply the function.</span>
a.FUN = check_na, <span class="hljs-comment"># The function that we want to apply.</span>
a.combine = <span class="hljs-string">&quot;+&quot;</span>, <span class="hljs-comment"># How the results of each subset should be combined.</span>
ncores = <span class="hljs-number">2</span>) <span class="hljs-comment"># Number of CPU cores to use.</span>
</span></span></foreignObject></svg></code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="11" data-theme="default" style="--theme:default;">
<h1>Applying Functions [3]</h1>
<ul>
<li>If we <em>really</em> want to, we can manually create subsets and apply functions using a <code>for</code> loop.</li>
<li>First, we must get the indices for each subset:</li>
</ul>
<pre><code class="language-r"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-comment"># Subset the dataframe into sets of 100 columns.</span>
sub_idx &lt;- split(<span class="hljs-number">1</span>:col_num, <span class="hljs-built_in">ceiling</span>(<span class="hljs-built_in">seq_along</span>(<span class="hljs-number">1</span>:col_num) / <span class="hljs-number">100</span>))
</span></span></foreignObject></svg></code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="12" data-theme="default" style="--theme:default;">
<h1>Applying Functions [4]</h1>
<ul>
<li>Now, we can extract our subsets and apply our function:</li>
</ul>
<pre><code class="language-r"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-keyword">for</span> (i <span class="hljs-keyword">in</span> <span class="hljs-number">1</span>:<span class="hljs-built_in">length</span>(sub_idx)) {
<span class="hljs-comment"># Display current subset being evaluated.</span>
print(i)
<span class="hljs-comment"># Get the Genotype Data for the current subset.</span>
gen_subset &lt;- gen_data[, sub_idx[[i]]]
<span class="hljs-comment"># Impute missing data using KNN clustering.</span>
gen_imputed &lt;- <span class="hljs-built_in">round</span>(
t(impute::impute.knn(t(gen_subset), k = <span class="hljs-number">50</span>, rowmax = <span class="hljs-number">1</span>, colmax = <span class="hljs-number">1</span>)$data), <span class="hljs-number">0</span>)
<span class="hljs-comment"># &quot;Write back&quot; imputed data to the FBM.</span>
gen_data[, sub_idx[[i]]] &lt;- gen_imputed
}
</span></span></foreignObject></svg></code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="13" data-theme="default" style="--theme:default;">
<h1>Applying Functions [5]</h1>
<ul>
<li>Check that the <code>impute</code> function worked:</li>
</ul>
<pre><code class="language-r"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-comment"># Now, verify there are no missing values anymore.</span>
big_apply(gen_data,
a.FUN = check_na,
a.combine = <span class="hljs-string">&quot;+&quot;</span>,
ncores = <span class="hljs-number">2</span>)
</span></span></foreignObject></svg></code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="14" data-theme="default" style="--theme:default;">
<h1>Saving FBMs</h1>
<ul>
<li>How do we save our modified data back to a <code>.csv</code> file? Easy, use <code>big_write</code>:</li>
</ul>
<pre><code class="language-r"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-comment"># Write the newly-imputed data to a new file.</span>
big_write(gen_data, <span class="hljs-comment"># Our FBM object.</span>
<span class="hljs-string">&quot;Test_Genotype_Data_Imputed.csv&quot;</span>, <span class="hljs-comment"># Name of the file.</span>
every_nrow = <span class="hljs-number">100</span>, <span class="hljs-comment"># How many rows do we want to save at once.</span>
progress = <span class="hljs-built_in">interactive</span>()) <span class="hljs-comment"># Show a fancy progress bar.</span>
</span></span></foreignObject></svg></code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="15" data-theme="default" style="--theme:default;">
<h1>Removing Backing Files</h1>
<ul>
<li><code>big_read</code> will create backing files that are of no use after we saved our file.</li>
<li>They can be safely removed:</li>
</ul>
<pre><code class="language-r"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-comment"># Remove backing files.</span>
system(<span class="hljs-string">&quot;rm *.bk&quot;</span>)
system(<span class="hljs-string">&quot;rm *.rds&quot;</span>)
</span></span></foreignObject></svg></code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="16" data-theme="default" style="--theme:default;">
<p><img src="R_Logo.png" alt="" style="width:150px;" /></p>
<h1><code>caret</code> Package</h1>
<blockquote>
<p>Short for Classification And REgression Training. It is a set of functions that attempt to streamline the process for creating predictive models. The package started off as a way to provide a uniform interface for modeling functions, as well as a way to standardize common tasks (such parameter tuning and variable importance).</p>
</blockquote>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="17" data-theme="default" style="--theme:default;">
<h1>Loading Data</h1>
<ul>
<li>First, let's load our newly-imputed Genotype Data:</li>
</ul>
<pre><code class="language-r"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-comment">## Data Loading [Predictors]</span>
<span class="hljs-comment"># Genotype Data</span>
gen_path &lt;- <span class="hljs-string">&quot;Test_Genotype_Data_Imputed.csv&quot;</span>
gen_data &lt;- fread(gen_path, sep = <span class="hljs-string">&quot;,&quot;</span>, header = <span class="hljs-literal">FALSE</span>)
</span></span></foreignObject></svg></code></pre>
<ul>
<li>Let's load our Phenotype Data as well:</li>
</ul>
<pre><code class="language-r"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-comment">## Data Loading [Traits]</span>
<span class="hljs-comment"># Phenotype Data</span>
phn_path &lt;- <span class="hljs-string">&quot;Test_Phenotype_Data.csv&quot;</span>
phn_data &lt;- fread(phn_path, sep = <span class="hljs-string">&quot;,&quot;</span>, header = <span class="hljs-literal">FALSE</span>)
</span></span></foreignObject></svg></code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="18" data-theme="default" style="--theme:default;">
<h1>Data Overview</h1>
<ul>
<li>Our Genotype Data is a large matrix of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>0</mn></mrow><annotation encoding="application/x-tex">0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">0</span></span></span></span>s and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn></mrow><annotation encoding="application/x-tex">1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span>s:</li>
</ul>
<pre><code class="language-r"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-comment"># Preview of Genotype Data.</span>
str(gen_data)
gen_data[<span class="hljs-number">1</span>:<span class="hljs-number">10</span>, <span class="hljs-number">1</span>:<span class="hljs-number">10</span>]
</span></span></foreignObject></svg></code></pre>
<ul>
<li>Our Phenotype Data, which we want to predict, is a single column of <code>Plant Height (cm)</code> measurements:</li>
</ul>
<pre><code class="language-r"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-comment"># Preview of Phenotype Data.</span>
str(phn_data)
phn_data[<span class="hljs-number">1</span>:<span class="hljs-number">10</span>, <span class="hljs-number">1</span>]
</span></span></foreignObject></svg></code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="19" data-theme="default" style="--theme:default;">
<h1>The <code>createDataPartition</code> Function [1]</h1>
<ul>
<li>We can easily split our data into training and testing sets as follows:</li>
</ul>
<pre><code class="language-r"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-comment"># We want 80% of our data for training and 20% for testing.</span>
<span class="hljs-comment"># Get the indices for the rows to be used in the training data.</span>
train_index &lt;- createDataPartition(
phn_data$V1, <span class="hljs-comment"># Our Phenotype Data.</span>
p = <span class="hljs-number">0.8</span>, <span class="hljs-comment"># Percentage of data to be used for training.</span>
<span class="hljs-built_in">list</span> = <span class="hljs-literal">FALSE</span>) <span class="hljs-comment"># To return a matrix instead of a list.</span>
<span class="hljs-comment"># Check out which rows will be used for training.</span>
train_index
</span></span></foreignObject></svg></code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="20" data-theme="default" style="--theme:default;">
<h1>The <code>createDataPartition</code> Function [2]</h1>
<ul>
<li>Now that we know which indices will be used for training, we can extract the corresponding data:</li>
</ul>
<pre><code class="language-r"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-comment"># The values used as predictors [x].</span>
x_train &lt;- gen_data[train_index,]
x_test &lt;- gen_data[-train_index,]
<span class="hljs-comment"># The values to be predicted [y].</span>
y_train &lt;- phn_data[train_index,]
y_test &lt;- phn_data[-train_index,]
</span></span></foreignObject></svg></code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="21" data-theme="default" style="--theme:default;">
<h1>Model Training and Tuning [1]</h1>
<blockquote>
<p><img src="R_Logo.png" alt="" style="width:50px;" /> <code>glmnet</code></p>
<hr />
<p>Fits generalized linear and similar models via penalized maximum likelihood. The regularization path is computed for the lasso or elastic net penalty at a grid of values (on the log scale) for the regularization parameter <code>lambda</code>.</p>
</blockquote>
<br />
<ul>
<li>We can perform this tuning automatically with <code>caret</code>. Let's first create a custom parameter grid:</li>
</ul>
<pre><code class="language-r"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-comment"># Define a custom tuning grid.</span>
tune_grid &lt;- expand.grid(alpha = seq(<span class="hljs-number">0.0001</span>, <span class="hljs-number">1</span>, <span class="hljs-built_in">length</span> = <span class="hljs-number">5</span>), <span class="hljs-comment"># Values to try for &quot;alpha&quot;.</span>
lambda = <span class="hljs-number">5</span>) <span class="hljs-comment"># Values to try for &quot;lambda&quot;.</span>
</span></span></foreignObject></svg></code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="22" data-theme="default" style="--theme:default;">
<h1>Model Training and Tuning [2]</h1>
<ul>
<li>The <code>trainControl</code> function allows us to further customize how our model is made:</li>
</ul>
<pre><code class="language-r"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-comment"># Parameter tuning.</span>
param_tune &lt;- trainControl(method = <span class="hljs-string">&quot;repeatedcv&quot;</span>, <span class="hljs-comment"># Method to be used for resampling.</span>
number = <span class="hljs-number">2</span>, <span class="hljs-comment"># Numebr of folds (subsets) for cross-validation.</span>
repeats = <span class="hljs-number">5</span>, <span class="hljs-comment"># Number of iterations for cross-validation.</span>
trim = <span class="hljs-literal">TRUE</span>, <span class="hljs-comment"># Reduces memory consumption.</span>
search = <span class="hljs-string">&quot;grid&quot;</span>, <span class="hljs-comment"># How the tuning grid should be made.</span>
verboseIter = <span class="hljs-literal">TRUE</span>) <span class="hljs-comment"># To display additional information.</span>
</span></span></foreignObject></svg></code></pre>
<ul>
<li>Other methods are available, such as a single cross-validation (<code>cv</code>), a leave-one-out cross-validation (<code>LOOCV</code>), or <code>none</code>, which will only train a single model.</li>
<li>It is also possible to specify a <code>random</code> tuning grid.</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="23" data-theme="default" style="--theme:default;">
<h1>Model Training and Tuning [3]</h1>
<ul>
<li>Now, we can finally train our model:</li>
</ul>
<pre><code class="language-r"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-comment"># Train a model.</span>
glmnet_model &lt;- train(x_train, <span class="hljs-comment"># Our predictors.</span>
y_train$V1, <span class="hljs-comment"># What we want to predict.</span>
method = <span class="hljs-string">&quot;glmnet&quot;</span>, <span class="hljs-comment"># The model we want to use.</span>
metric = <span class="hljs-string">&quot;MAE&quot;</span>, <span class="hljs-comment"># What metric should we use to pick the best model.</span>
tuneGrid = tune_grid, <span class="hljs-comment"># Our custom tuning grid.</span>
trControl = param_tune) <span class="hljs-comment"># Our custom tuning method.</span>
</span></span></foreignObject></svg></code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="24" data-theme="default" style="--theme:default;">
<h1>Model Evaluation [1]</h1>
<pre><code class="language-r"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap>&gt; glmnet
<span class="hljs-number">800</span> samples
<span class="hljs-number">1000</span> predictors
No pre-processing
Resampling: Cross-Validated (<span class="hljs-number">2</span> fold, repeated <span class="hljs-number">5</span> times)
Summary of sample sizes: <span class="hljs-number">400</span>, <span class="hljs-number">400</span>, <span class="hljs-number">400</span>, <span class="hljs-number">400</span>, <span class="hljs-number">400</span>, <span class="hljs-number">400</span>, ...
Resampling results across tuning parameters:
alpha RMSE Rsquared MAE
<span class="hljs-number">0.000100</span> <span class="hljs-number">61.23760</span> <span class="hljs-number">0.002033470</span> <span class="hljs-number">52.85568</span>
<span class="hljs-number">0.250075</span> <span class="hljs-number">61.83544</span> <span class="hljs-number">0.002543141</span> <span class="hljs-number">52.85747</span>
<span class="hljs-number">0.500050</span> <span class="hljs-number">60.02843</span> <span class="hljs-number">0.002118089</span> <span class="hljs-number">52.03982</span>
<span class="hljs-number">0.750025</span> <span class="hljs-number">59.16487</span> <span class="hljs-number">0.001651774</span> <span class="hljs-number">51.61048</span>
<span class="hljs-number">1.000000</span> <span class="hljs-number">58.81907</span> <span class="hljs-number">0.002781994</span> <span class="hljs-number">51.40225</span>
Tuning parameter <span class="hljs-string">&#x27;lambda&#x27;</span> was held constant at a value of <span class="hljs-number">5</span>
MAE was used to select the optimal model using the smallest value.
The final values used <span class="hljs-keyword">for</span> the model were alpha = <span class="hljs-number">1</span> and lambda = <span class="hljs-number">5.</span>
</span></span></foreignObject></svg></code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="25" data-theme="default" style="--theme:default;">
<h1>Model Evaluation [2]</h1>
<ul>
<li>Now, let's predict on our testing data:</li>
</ul>
<pre><code class="language-r"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-comment"># Predict on testing data.</span>
glmnet_prediction &lt;- predict(glmnet_model, x_test)
<span class="hljs-comment"># Check prediction accuracy.</span>
postResample(pred = glmnet_prediction, <span class="hljs-comment"># Our predicted values.</span>
obs = y_test$V1) <span class="hljs-comment"># Our expected vaues.</span>
</span></span></foreignObject></svg></code></pre>
<ul>
<li>This gives us a nice summary of the prediction:</li>
</ul>
<pre><code class="language-text"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap> RMSE Rsquared MAE
5.649786e+01 6.306793e-06 4.883650e+01
</span></span></foreignObject></svg></code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="26" data-theme="default" style="--theme:default;">
<h1>More Models</h1>
<ul>
<li><code>caret</code> supports <em>a lot</em> of models (last time I checked, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>238</mn></mrow><annotation encoding="application/x-tex">238</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">238</span></span></span></span>).</li>
<li>More examples are given in the file for you to try:
<ul>
<li><code>earth</code></li>
<li><code>keras</code></li>
<li><code>xgboost</code></li>
</ul>
</li>
<li>You can also define your own models as well.</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="27" data-theme="default" style="--theme:default;">
<p><img src="Models.png" alt="" style="width:650px;" /></p>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="28" data-theme="default" style="--theme:default;">
<h1>References</h1>
<ul>
<li>
<p><code>bigstatsR</code> Package:</p>
<p>[1] <a href="https://github.com/privefl/bigstatsr">https://github.com/privefl/bigstatsr</a><br />
[2] <a href="https://privefl.github.io/bigstatsr/articles/read-FBM-from-file.html">https://privefl.github.io/bigstatsr/articles/read-FBM-from-file.html</a></p>
</li>
<li>
<p><code>caret</code> Package:</p>
<p>[1] <a href="https://topepo.github.io/caret/">https://topepo.github.io/caret/</a><br />
[2] <a href="https://topepo.github.io/caret/available-models.html">https://topepo.github.io/caret/available-models.html</a></p>
</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="29" data-theme="default" style="--theme:default;">
<h1>Thank You!</h1>
</section>
<script>!function(){"use strict";const t="marpitSVGPolyfill:setZoomFactor,",e=Symbol();let r,o;function n(n){const i="object"==typeof n&&n.target||document,a="object"==typeof n?n.zoom:n;window[e]||(Object.defineProperty(window,e,{configurable:!0,value:!0}),window.addEventListener("message",(({data:e,origin:r})=>{if(r===window.origin)try{if(e&&"string"==typeof e&&e.startsWith(t)){const[,t]=e.split(","),r=Number.parseFloat(t);Number.isNaN(r)||(o=r)}}catch(t){console.error(t)}})));let l=!1;Array.from(i.querySelectorAll("svg[data-marpit-svg]"),(t=>{var e,n,i,s;t.style.transform||(t.style.transform="translateZ(0)");const c=a||o||t.currentScale||1;r!==c&&(r=c,l=c);const d=t.getBoundingClientRect(),{length:f}=t.children;for(let r=0;r<f;r+=1){const o=t.children[r];if(o.getScreenCTM){const t=o.getScreenCTM();if(t){const r=null!==(n=null===(e=o.x)||void 0===e?void 0:e.baseVal.value)&&void 0!==n?n:0,a=null!==(s=null===(i=o.y)||void 0===i?void 0:i.baseVal.value)&&void 0!==s?s:0,l=o.children.length;for(let e=0;e<l;e+=1){const n=o.children[e];if("SECTION"===n.tagName){const{style:e}=n;e.transformOrigin||(e.transformOrigin=`${-r}px ${-a}px`),e.transform=`scale(${c}) matrix(${t.a}, ${t.b}, ${t.c}, ${t.d}, ${t.e-d.left}, ${t.f-d.top}) translateZ(0.0001px)`;break}}}}}})),!1!==l&&Array.from(i.querySelectorAll("iframe"),(({contentWindow:e})=>{null==e||e.postMessage(`${t}${l}`,"null"===window.origin?"*":window.origin)}))}r=1,o=void 0;const i=(t,e,r)=>{if(t.getAttribute(e)!==r)return t.setAttribute(e,r),!0};function a({once:t=!1,target:e=document}={}){const r="Apple Computer, Inc."===navigator.vendor?[n]:[];let o=!t;const a=()=>{for(const t of r)t({target:e});!function(t=document){Array.from(t.querySelectorAll('svg[data-marp-fitting="svg"]'),(t=>{var e;const r=t.firstChild,o=r.firstChild,{scrollWidth:n,scrollHeight:a}=o;let l,s=1;if(t.hasAttribute("data-marp-fitting-code")&&(l=null===(e=t.parentElement)||void 0===e?void 0:e.parentElement),t.hasAttribute("data-marp-fitting-math")&&(l=t.parentElement),l){const t=getComputedStyle(l),e=Math.ceil(l.clientWidth-parseFloat(t.paddingLeft||"0")-parseFloat(t.paddingRight||"0"));e&&(s=e)}const c=Math.max(n,s),d=Math.max(a,1),f=`0 0 ${c} ${d}`;i(r,"width",`${c}`),i(r,"height",`${d}`),i(t,"preserveAspectRatio",getComputedStyle(t).getPropertyValue("--preserve-aspect-ratio")||"xMinYMin meet"),i(t,"viewBox",f)&&t.classList.toggle("__reflow__")}))}(e),o&&window.requestAnimationFrame(a)};return a(),()=>{o=!1}}const l=Symbol(),s=document.currentScript;((t=document)=>{if("undefined"==typeof window)throw new Error("Marp Core's browser script is valid only in browser context.");if(t[l])return t[l];const e=a({target:t}),r=()=>{e(),delete t[l]};Object.defineProperty(t,l,{configurable:!0,value:r})})(s?s.getRootNode():document)}();
</script></foreignObject></svg></div><script>/*!! License: https://unpkg.com/@marp-team/marp-cli@1.7.1/lib/bespoke.js.LICENSE.txt */
!function(){"use strict";const e=document.body,t=(...e)=>history.replaceState(...e),n="presenter",r="next",o=["",n,r],a="data-bespoke-marp-",i=(e,{protocol:t,host:n,pathname:r,hash:o}=location)=>{const a=e.toString();return`${t}//${n}${r}${a?"?":""}${a}${o}`},s=()=>e.dataset.bespokeView,l=e=>new URLSearchParams(location.search).get(e),d=(e,n={})=>{var r;const o={location,setter:t,...n},a=new URLSearchParams(o.location.search);for(const t of Object.keys(e)){const n=e[t];"string"==typeof n?a.set(t,n):a.delete(t)}try{o.setter({...null!==(r=window.history.state)&&void 0!==r?r:{}},"",i(a,o.location))}catch(e){console.error(e)}},c=(()=>{const e="bespoke-marp";try{return localStorage.setItem(e,e),localStorage.removeItem(e),!0}catch(e){return!1}})(),u=e=>{try{return localStorage.getItem(e)}catch(e){return null}},f=(e,t)=>{try{return localStorage.setItem(e,t),!0}catch(e){return!1}},m=e=>{try{return localStorage.removeItem(e),!0}catch(e){return!1}},g=(e,t)=>{const n="aria-hidden";t?e.setAttribute(n,"true"):e.removeAttribute(n)},p=e=>{e.parent.classList.add("bespoke-marp-parent"),e.slides.forEach((e=>e.classList.add("bespoke-marp-slide"))),e.on("activate",(t=>{const n="bespoke-marp-active",r=t.slide,o=r.classList,a=!o.contains(n);if(e.slides.forEach((e=>{e.classList.remove(n),g(e,!0)})),o.add(n),g(r,!1),a){const e=`${n}-ready`;o.add(e),document.body.clientHeight,o.remove(e)}}))},v=e=>{let t=0,n=0;Object.defineProperty(e,"fragments",{enumerable:!0,value:e.slides.map((e=>[null,...e.querySelectorAll("[data-marpit-fragment]")]))});const r=r=>void 0!==e.fragments[t][n+r],o=(r,o)=>{t=r,n=o,e.fragments.forEach(((e,t)=>{e.forEach(((e,n)=>{if(null==e)return;const i=t<r||t===r&&n<=o;e.setAttribute(`${a}fragment`,(i?"":"in")+"active");const s=`${a}current-fragment`;t===r&&n===o?e.setAttribute(s,"current"):e.removeAttribute(s)}))})),e.fragmentIndex=o;const i={slide:e.slides[r],index:r,fragments:e.fragments[r],fragmentIndex:o};e.fire("fragment",i)};e.on("next",(({fragment:a=!0})=>{if(a){if(r(1))return o(t,n+1),!1;const a=t+1;e.fragments[a]&&o(a,0)}else{const r=e.fragments[t].length;if(n+1<r)return o(t,r-1),!1;const a=e.fragments[t+1];a&&o(t+1,a.length-1)}})),e.on("prev",(({fragment:a=!0})=>{if(r(-1)&&a)return o(t,n-1),!1;const i=t-1;e.fragments[i]&&o(i,e.fragments[i].length-1)})),e.on("slide",(({index:t,fragment:n})=>{let r=0;if(void 0!==n){const o=e.fragments[t];if(o){const{length:e}=o;r=-1===n?e-1:Math.min(Math.max(n,0),e-1)}}o(t,r)})),o(0,0)},h=document,y=()=>!(!h.fullscreenEnabled&&!h.webkitFullscreenEnabled),b=()=>!(!h.fullscreenElement&&!h.webkitFullscreenElement),x=e=>{e.fullscreen=()=>{y()&&(async()=>{return b()?null===(e=h.exitFullscreen||h.webkitExitFullscreen)||void 0===e?void 0:e.call(h):((e=h.body)=>{var t;return null===(t=e.requestFullscreen||e.webkitRequestFullscreen)||void 0===t?void 0:t.call(e)})();var e})()},document.addEventListener("keydown",(t=>{"f"!==t.key&&"F11"!==t.key||t.altKey||t.ctrlKey||t.metaKey||!y()||(e.fullscreen(),t.preventDefault())}))},w="bespoke-marp-inactive",k=(e=2e3)=>({parent:t,fire:n})=>{const r=t.classList,o=e=>n(`marp-${e?"":"in"}active`);let a;const i=()=>{a&&clearTimeout(a),a=setTimeout((()=>{r.add(w),o()}),e),r.contains(w)&&(r.remove(w),o(!0))};for(const e of["mousedown","mousemove","touchend"])document.addEventListener(e,i);setTimeout(i,0)},E=["AUDIO","BUTTON","INPUT","SELECT","TEXTAREA","VIDEO"],L=e=>{e.parent.addEventListener("keydown",(e=>{if(!e.target)return;const t=e.target;(E.includes(t.nodeName)||"true"===t.contentEditable)&&e.stopPropagation()}))},$=e=>{window.addEventListener("load",(()=>{for(const t of e.slides){const e=t.querySelector("[data-marp-fitting]")?"":"hideable";t.setAttribute(`${a}load`,e)}}))},S=({interval:e=250}={})=>t=>{document.addEventListener("keydown",(e=>{if(" "===e.key&&e.shiftKey)t.prev();else if("ArrowLeft"===e.key||"ArrowUp"===e.key||"PageUp"===e.key)t.prev({fragment:!e.shiftKey});else if(" "!==e.key||e.shiftKey)if("ArrowRight"===e.key||"ArrowDown"===e.key||"PageDown"===e.key)t.next({fragment:!e.shiftKey});else if("End"===e.key)t.slide(t.slides.length-1,{fragment:-