487 lines
15 KiB
HTML
Raw Normal View History

2025-01-12 00:52:51 +08:00
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta http-equiv="X-UA-Compatible" content="IE=EDGE" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Custom knitr language engines</title>
<script>// Pandoc 2.9 adds attributes on both header and div. We remove the former (to
// be compatible with the behavior of Pandoc < 2.8).
document.addEventListener('DOMContentLoaded', function(e) {
var hs = document.querySelectorAll("div.section[class*='level'] > :first-child");
var i, h, a;
for (i = 0; i < hs.length; i++) {
h = hs[i];
if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6
a = h.attributes;
while (a.length > 0) h.removeAttribute(a[0].name);
}
});
</script>
<style type="text/css">
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
</style>
<style type="text/css">
code {
white-space: pre;
}
.sourceCode {
overflow: visible;
}
</style>
<style type="text/css" data-origin="pandoc">
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 { display: inline-block; 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>
<script>
// apply pandoc div.sourceCode style to pre.sourceCode instead
(function() {
var sheets = document.styleSheets;
for (var i = 0; i < sheets.length; i++) {
if (sheets[i].ownerNode.dataset["origin"] !== "pandoc") continue;
try { var rules = sheets[i].cssRules; } catch (e) { continue; }
var j = 0;
while (j < rules.length) {
var rule = rules[j];
// check if there is a div.sourceCode rule
if (rule.type !== rule.STYLE_RULE || rule.selectorText !== "div.sourceCode") {
j++;
continue;
}
var style = rule.style.cssText;
// check if color or background-color is set
if (rule.style.color === '' && rule.style.backgroundColor === '') {
j++;
continue;
}
// replace div.sourceCode by a pre.sourceCode rule
sheets[i].deleteRule(j);
sheets[i].insertRule('pre.sourceCode{' + style + '}', j);
}
}
})();
</script>
<style type="text/css">body {
background-color: #fff;
margin: 1em auto;
max-width: 700px;
overflow: visible;
padding-left: 2em;
padding-right: 2em;
font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
line-height: 1.35;
}
#TOC {
clear: both;
margin: 0 0 10px 10px;
padding: 4px;
width: 400px;
border: 1px solid #CCCCCC;
border-radius: 5px;
background-color: #f6f6f6;
font-size: 13px;
line-height: 1.3;
}
#TOC .toctitle {
font-weight: bold;
font-size: 15px;
margin-left: 5px;
}
#TOC ul {
padding-left: 40px;
margin-left: -1.5em;
margin-top: 5px;
margin-bottom: 5px;
}
#TOC ul ul {
margin-left: -2em;
}
#TOC li {
line-height: 16px;
}
table {
margin: 1em auto;
border-width: 1px;
border-color: #DDDDDD;
border-style: outset;
border-collapse: collapse;
}
table th {
border-width: 2px;
padding: 5px;
border-style: inset;
}
table td {
border-width: 1px;
border-style: inset;
line-height: 18px;
padding: 5px 5px;
}
table, table th, table td {
border-left-style: none;
border-right-style: none;
}
table thead, table tr.even {
background-color: #f7f7f7;
}
p {
margin: 0.5em 0;
}
blockquote {
background-color: #f6f6f6;
padding: 0.25em 0.75em;
}
hr {
border-style: solid;
border: none;
border-top: 1px solid #777;
margin: 28px 0;
}
dl {
margin-left: 0;
}
dl dd {
margin-bottom: 13px;
margin-left: 13px;
}
dl dt {
font-weight: bold;
}
ul {
margin-top: 0;
}
ul li {
list-style: circle outside;
}
ul ul {
margin-bottom: 0;
}
pre, code {
background-color: #f7f7f7;
border-radius: 3px;
color: #333;
white-space: pre-wrap;
}
pre {
border-radius: 3px;
margin: 5px 0px 10px 0px;
padding: 10px;
}
pre:not([class]) {
background-color: #f7f7f7;
}
code {
font-family: Consolas, Monaco, 'Courier New', monospace;
font-size: 85%;
}
p > code, li > code {
padding: 2px 0px;
}
div.figure {
text-align: center;
}
img {
background-color: #FFFFFF;
padding: 2px;
border: 1px solid #DDDDDD;
border-radius: 3px;
border: 1px solid #CCCCCC;
margin: 0 5px;
}
h1 {
margin-top: 0;
font-size: 35px;
line-height: 40px;
}
h2 {
border-bottom: 4px solid #f7f7f7;
padding-top: 10px;
padding-bottom: 2px;
font-size: 145%;
}
h3 {
border-bottom: 2px solid #f7f7f7;
padding-top: 10px;
font-size: 120%;
}
h4 {
border-bottom: 1px solid #f7f7f7;
margin-left: 8px;
font-size: 105%;
}
h5, h6 {
border-bottom: 1px solid #ccc;
font-size: 105%;
}
a {
color: #0033dd;
text-decoration: none;
}
a:hover {
color: #6666ff; }
a:visited {
color: #800080; }
a:visited:hover {
color: #BB00BB; }
a[href^="http:"] {
text-decoration: underline; }
a[href^="https:"] {
text-decoration: underline; }
code > span.kw { color: #555; font-weight: bold; }
code > span.dt { color: #902000; }
code > span.dv { color: #40a070; }
code > span.bn { color: #d14; }
code > span.fl { color: #d14; }
code > span.ch { color: #d14; }
code > span.st { color: #d14; }
code > span.co { color: #888888; font-style: italic; }
code > span.ot { color: #007020; }
code > span.al { color: #ff0000; font-weight: bold; }
code > span.fu { color: #900; font-weight: bold; }
code > span.er { color: #a61717; background-color: #e3d2d2; }
</style>
</head>
<body>
<h1 class="title toc-ignore">Custom knitr language engines</h1>
<p>Glue provides a few <a href="https://bookdown.org/yihui/rmarkdown-cookbook/custom-engine.html#custom-engine">custom
language engines</a> for knitr, which allows you to use glue directly in
knitr chunks.</p>
<div id="glue-engine" class="section level2">
<h2><code>glue</code> engine</h2>
<p>The first engine is the <code>glue</code> engine, which evaluates the
chunk contents as a glue template.</p>
<pre class="glue"><code>1 + 1 = {1 + 1}</code></pre>
<pre><code>## 1 + 1 = 2</code></pre>
<p>Maybe the most useful use of the <code>glue</code> engine is to set
the knitr option <code>results = &#39;asis&#39;</code> and output markdown or
HTML directly into the document.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode markdown"><code class="sourceCode markdown"><span id="cb3-1"><a href="#cb3-1" tabindex="-1"></a><span class="in">```{glue, results = &#39;asis&#39;, echo = FALSE}</span></span>
<span id="cb3-2"><a href="#cb3-2" tabindex="-1"></a><span class="in">#### mtcars has **{nrow(mtcars)} rows** and _{ncol(mtcars)} columns_.</span></span>
<span id="cb3-3"><a href="#cb3-3" tabindex="-1"></a><span class="in">```</span></span></code></pre></div>
<div id="mtcars-has-32-rows-and-11-columns." class="section level4">
<h4>mtcars has <strong>32 rows</strong> and <em>11 columns</em>.</h4>
<p>If you want to pass additional arguments into the glue call, simply
include them as chunk options.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode markdown"><code class="sourceCode markdown"><span id="cb4-1"><a href="#cb4-1" tabindex="-1"></a><span class="in">```{glue, .open = &quot;&lt;&lt;&quot;, .close = &quot;&gt;&gt;&quot;, results = &#39;asis&#39;, echo = FALSE}</span></span>
<span id="cb4-2"><a href="#cb4-2" tabindex="-1"></a><span class="in">The **median waiting time** between eruptions is &lt;&lt;median(faithful$waiting)&gt;&gt;.</span></span>
<span id="cb4-3"><a href="#cb4-3" tabindex="-1"></a><span class="in">```</span></span></code></pre></div>
<p>The <strong>median waiting time</strong> between eruptions is 76.</p>
</div>
</div>
<div id="glue_sql-engine" class="section level2">
<h2><code>glue_sql</code> engine</h2>
<p>The second engine is <code>glue_sql</code>, which will use
<code>glue::glue_sql()</code> to generate a SQL query and then run the
query using the <a href="https://bookdown.org/yihui/rmarkdown/language-engines.html#sql">sql
engine</a>.</p>
<p>First we create a new connection to an in-memory SQLite database, and
write a new table to it.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb5-1"><a href="#cb5-1" tabindex="-1"></a>con <span class="ot">&lt;-</span> DBI<span class="sc">::</span><span class="fu">dbConnect</span>(RSQLite<span class="sc">::</span><span class="fu">SQLite</span>(), <span class="st">&quot;:memory:&quot;</span>)</span>
<span id="cb5-2"><a href="#cb5-2" tabindex="-1"></a>mtcars<span class="sc">$</span>model <span class="ot">&lt;-</span> <span class="fu">rownames</span>(mtcars)</span>
<span id="cb5-3"><a href="#cb5-3" tabindex="-1"></a>DBI<span class="sc">::</span><span class="fu">dbWriteTable</span>(con, <span class="st">&quot;mtcars&quot;</span>, mtcars)</span></code></pre></div>
<p>Next define some variables we that we can use with glue to
interpolate.</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb6-1"><a href="#cb6-1" tabindex="-1"></a>var <span class="ot">&lt;-</span> <span class="st">&quot;mpg&quot;</span></span>
<span id="cb6-2"><a href="#cb6-2" tabindex="-1"></a>tbl <span class="ot">&lt;-</span> <span class="st">&quot;mtcars&quot;</span></span>
<span id="cb6-3"><a href="#cb6-3" tabindex="-1"></a>num <span class="ot">&lt;-</span> <span class="dv">150</span></span></code></pre></div>
<p>Then we can use <code>glue_sql</code> to construct and run a query
using those variables into that database. <em>Note</em> you need to
provide the connection object as a <code>connection</code> chunk
option.</p>
<p>In this example there are two type of quotes. The first is a bare
backtick, these are passed directly to the SQL engine unchanged. The
second is backticks inside of braces, which are specially interpreted to
do the proper quoting for the given SQL engine by glue. In this example
we use the <code>sqlite</code> engine, which uses backticks for quoting,
but you would use the same backticks inside brace syntax for postgreSQL,
and <code>glue_sql()</code> would automatically use double quotes for
quoting instead.</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode markdown"><code class="sourceCode markdown"><span id="cb7-1"><a href="#cb7-1" tabindex="-1"></a><span class="in">```{glue_sql, connection = con}</span></span>
<span id="cb7-2"><a href="#cb7-2" tabindex="-1"></a><span class="in">SELECT `model`, `hp`, {`var`}</span></span>
<span id="cb7-3"><a href="#cb7-3" tabindex="-1"></a><span class="in">FROM {`tbl`}</span></span>
<span id="cb7-4"><a href="#cb7-4" tabindex="-1"></a><span class="in">WHERE {`tbl`}.`hp` &gt; {num}</span></span>
<span id="cb7-5"><a href="#cb7-5" tabindex="-1"></a><span class="in">```</span></span></code></pre></div>
<div class="sourceCode" id="cb8"><pre class="sourceCode sql"><code class="sourceCode sql"><span id="cb8-1"><a href="#cb8-1" tabindex="-1"></a><span class="kw">SELECT</span> `model`, `hp`, `mpg`</span>
<span id="cb8-2"><a href="#cb8-2" tabindex="-1"></a><span class="kw">FROM</span> `mtcars`</span>
<span id="cb8-3"><a href="#cb8-3" tabindex="-1"></a><span class="kw">WHERE</span> `mtcars`.`hp` <span class="op">&gt;</span> <span class="dv">150</span></span></code></pre></div>
<div class="knitsql-table">
<table>
<caption>Displaying records 1 - 10</caption>
<thead>
<tr class="header">
<th align="left">model</th>
<th align="right">hp</th>
<th align="right">mpg</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td align="left">Hornet Sportabout</td>
<td align="right">175</td>
<td align="right">18.7</td>
</tr>
<tr class="even">
<td align="left">Duster 360</td>
<td align="right">245</td>
<td align="right">14.3</td>
</tr>
<tr class="odd">
<td align="left">Merc 450SE</td>
<td align="right">180</td>
<td align="right">16.4</td>
</tr>
<tr class="even">
<td align="left">Merc 450SL</td>
<td align="right">180</td>
<td align="right">17.3</td>
</tr>
<tr class="odd">
<td align="left">Merc 450SLC</td>
<td align="right">180</td>
<td align="right">15.2</td>
</tr>
<tr class="even">
<td align="left">Cadillac Fleetwood</td>
<td align="right">205</td>
<td align="right">10.4</td>
</tr>
<tr class="odd">
<td align="left">Lincoln Continental</td>
<td align="right">215</td>
<td align="right">10.4</td>
</tr>
<tr class="even">
<td align="left">Chrysler Imperial</td>
<td align="right">230</td>
<td align="right">14.7</td>
</tr>
<tr class="odd">
<td align="left">Camaro Z28</td>
<td align="right">245</td>
<td align="right">13.3</td>
</tr>
<tr class="even">
<td align="left">Pontiac Firebird</td>
<td align="right">175</td>
<td align="right">19.2</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- code folding -->
<!-- dynamically load mathjax for compatibility with self-contained -->
<script>
(function () {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
document.getElementsByTagName("head")[0].appendChild(script);
})();
</script>
</body>
</html>