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

639 lines
38 KiB
HTML
Raw Permalink 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>
<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>Introduction to glue</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">Introduction to glue</h1>
<p>The glue package contains functions for string interpolation: gluing
together character strings and R code.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb1-1"><a href="#cb1-1" tabindex="-1"></a><span class="fu">library</span>(glue)</span></code></pre></div>
<div id="gluing-and-interpolating" class="section level2">
<h2>Gluing and interpolating</h2>
<p><code>glue()</code> can be used to glue together pieces of text:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb2-1"><a href="#cb2-1" tabindex="-1"></a><span class="fu">glue</span>(<span class="st">&quot;glue &quot;</span>, <span class="st">&quot;some &quot;</span>, <span class="st">&quot;text &quot;</span>, <span class="st">&quot;together&quot;</span>)</span>
<span id="cb2-2"><a href="#cb2-2" tabindex="-1"></a><span class="co">#&gt; glue some text together</span></span></code></pre></div>
<p>But glues real power comes with <code>{}</code>: anything inside of
<code>{}</code> is evaluated and pasted into the string. This makes it
easy to interpolate variables:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb3-1"><a href="#cb3-1" tabindex="-1"></a>name <span class="ot">&lt;-</span> <span class="st">&quot;glue&quot;</span></span>
<span id="cb3-2"><a href="#cb3-2" tabindex="-1"></a><span class="fu">glue</span>(<span class="st">&quot;We are learning how to use the {name} R package.&quot;</span>)</span>
<span id="cb3-3"><a href="#cb3-3" tabindex="-1"></a><span class="co">#&gt; We are learning how to use the glue R package.</span></span></code></pre></div>
<p>As well as more complex expressions:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb4-1"><a href="#cb4-1" tabindex="-1"></a>release_date <span class="ot">&lt;-</span> <span class="fu">as.Date</span>(<span class="st">&quot;2017-06-13&quot;</span>)</span>
<span id="cb4-2"><a href="#cb4-2" tabindex="-1"></a><span class="fu">glue</span>(<span class="st">&quot;Release was on a {format(release_date, &#39;%A&#39;)}.&quot;</span>)</span>
<span id="cb4-3"><a href="#cb4-3" tabindex="-1"></a><span class="co">#&gt; Release was on a Tuesday.</span></span></code></pre></div>
</div>
<div id="control-of-line-breaks" class="section level2">
<h2>Control of line breaks</h2>
<p><code>glue()</code> honors the line breaks in its input:</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><span class="fu">glue</span>(<span class="st">&quot;</span></span>
<span id="cb5-2"><a href="#cb5-2" tabindex="-1"></a><span class="st"> A formatted string</span></span>
<span id="cb5-3"><a href="#cb5-3" tabindex="-1"></a><span class="st"> Can have multiple lines</span></span>
<span id="cb5-4"><a href="#cb5-4" tabindex="-1"></a><span class="st"> with additional indention preserved</span></span>
<span id="cb5-5"><a href="#cb5-5" tabindex="-1"></a><span class="st"> &quot;</span></span>
<span id="cb5-6"><a href="#cb5-6" tabindex="-1"></a>)</span>
<span id="cb5-7"><a href="#cb5-7" tabindex="-1"></a><span class="co">#&gt; A formatted string</span></span>
<span id="cb5-8"><a href="#cb5-8" tabindex="-1"></a><span class="co">#&gt; Can have multiple lines</span></span>
<span id="cb5-9"><a href="#cb5-9" tabindex="-1"></a><span class="co">#&gt; with additional indention preserved</span></span></code></pre></div>
<p>The example above demonstrates some other important facts about the
pre-processing of the template string:</p>
<ul>
<li>An empty first or last line is automatically trimmed.</li>
<li>Leading whitespace that is common across all lines is trimmed.</li>
</ul>
<p>The elimination of common leading whitespace is advantageous, because
you arent forced to choose between indenting your code normally and
getting the output you actually want. This is easier to appreciate when
you have <code>glue()</code> inside a function body (this example also
shows an alternative way of styling the end of a <code>glue()</code>
call):</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>foo <span class="ot">&lt;-</span> <span class="cf">function</span>() {</span>
<span id="cb6-2"><a href="#cb6-2" tabindex="-1"></a> <span class="fu">glue</span>(<span class="st">&quot;</span></span>
<span id="cb6-3"><a href="#cb6-3" tabindex="-1"></a><span class="st"> A formatted string</span></span>
<span id="cb6-4"><a href="#cb6-4" tabindex="-1"></a><span class="st"> Can have multiple lines</span></span>
<span id="cb6-5"><a href="#cb6-5" tabindex="-1"></a><span class="st"> with additional indention preserved&quot;</span>)</span>
<span id="cb6-6"><a href="#cb6-6" tabindex="-1"></a>}</span>
<span id="cb6-7"><a href="#cb6-7" tabindex="-1"></a><span class="fu">foo</span>()</span>
<span id="cb6-8"><a href="#cb6-8" tabindex="-1"></a><span class="co">#&gt; A formatted string</span></span>
<span id="cb6-9"><a href="#cb6-9" tabindex="-1"></a><span class="co">#&gt; Can have multiple lines</span></span>
<span id="cb6-10"><a href="#cb6-10" tabindex="-1"></a><span class="co">#&gt; with additional indention preserved</span></span></code></pre></div>
<p>On the other hand, what if you dont want a line break in the output,
but you also like to limit the length of lines in your source code to,
e.g., 80 characters? The first option is to use <code>\\</code> to break
the template string into multiple lines, without getting line breaks in
the output:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb7-1"><a href="#cb7-1" tabindex="-1"></a>release_date <span class="ot">&lt;-</span> <span class="fu">as.Date</span>(<span class="st">&quot;2017-06-13&quot;</span>)</span>
<span id="cb7-2"><a href="#cb7-2" tabindex="-1"></a><span class="fu">glue</span>(<span class="st">&quot;</span></span>
<span id="cb7-3"><a href="#cb7-3" tabindex="-1"></a><span class="st"> The first version of the glue package was released on </span><span class="sc">\\</span></span>
<span id="cb7-4"><a href="#cb7-4" tabindex="-1"></a><span class="st"> a {format(release_date, &#39;%A&#39;)}.&quot;</span>)</span>
<span id="cb7-5"><a href="#cb7-5" tabindex="-1"></a><span class="co">#&gt; The first version of the glue package was released on a Tuesday.</span></span></code></pre></div>
<p>This comes up fairly often when an expression to evaluate inside
<code>{}</code> takes up more characters than its result,
i.e. <code>format(release_date, &#39;%A&#39;)</code> versus
<code>Tuesday</code>. A second way to achieve the same result is to
break the template into individual pieces, which are then
concatenated.</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb8-1"><a href="#cb8-1" tabindex="-1"></a><span class="fu">glue</span>(</span>
<span id="cb8-2"><a href="#cb8-2" tabindex="-1"></a> <span class="st">&quot;The first version of the glue package was released on &quot;</span>,</span>
<span id="cb8-3"><a href="#cb8-3" tabindex="-1"></a> <span class="st">&quot;a {format(release_date, &#39;%A&#39;)}.&quot;</span></span>
<span id="cb8-4"><a href="#cb8-4" tabindex="-1"></a>)</span>
<span id="cb8-5"><a href="#cb8-5" tabindex="-1"></a><span class="co">#&gt; The first version of the glue package was released on a Tuesday.</span></span></code></pre></div>
<p>If you want an explicit newline at the start or end, include an extra
empty line.</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb9-1"><a href="#cb9-1" tabindex="-1"></a><span class="co"># no leading or trailing newline</span></span>
<span id="cb9-2"><a href="#cb9-2" tabindex="-1"></a>x <span class="ot">&lt;-</span> <span class="fu">glue</span>(<span class="st">&quot;</span></span>
<span id="cb9-3"><a href="#cb9-3" tabindex="-1"></a><span class="st"> blah</span></span>
<span id="cb9-4"><a href="#cb9-4" tabindex="-1"></a><span class="st"> &quot;</span>)</span>
<span id="cb9-5"><a href="#cb9-5" tabindex="-1"></a><span class="fu">unclass</span>(x)</span>
<span id="cb9-6"><a href="#cb9-6" tabindex="-1"></a><span class="co">#&gt; [1] &quot;blah&quot;</span></span>
<span id="cb9-7"><a href="#cb9-7" tabindex="-1"></a></span>
<span id="cb9-8"><a href="#cb9-8" tabindex="-1"></a><span class="co"># both a leading and trailing newline</span></span>
<span id="cb9-9"><a href="#cb9-9" tabindex="-1"></a>y <span class="ot">&lt;-</span> <span class="fu">glue</span>(<span class="st">&quot;</span></span>
<span id="cb9-10"><a href="#cb9-10" tabindex="-1"></a></span>
<span id="cb9-11"><a href="#cb9-11" tabindex="-1"></a><span class="st"> blah</span></span>
<span id="cb9-12"><a href="#cb9-12" tabindex="-1"></a></span>
<span id="cb9-13"><a href="#cb9-13" tabindex="-1"></a><span class="st"> &quot;</span>)</span>
<span id="cb9-14"><a href="#cb9-14" tabindex="-1"></a><span class="fu">unclass</span>(y)</span>
<span id="cb9-15"><a href="#cb9-15" tabindex="-1"></a><span class="co">#&gt; [1] &quot;\nblah\n&quot;</span></span></code></pre></div>
<p>We use <code>unclass()</code> above to make it easier to see the
absence and presence of the newlines, i.e. to reveal the literal
<code>\n</code> escape sequences. <code>glue()</code> and friends
generally return a glue object, which is a character vector with the S3
class <code>&quot;glue&quot;</code>. The <code>&quot;glue&quot;</code> class exists
primarily for the sake of a print method, which displays the natural
formatted result of a glue string. Most of the time this is
<em>exactly</em> what the user wants to see. The example above happens
to be an exception, where we really do want to see the underlying string
representation.</p>
<p>Heres another example to drive home the difference between printing
a glue object and looking at its string representation.
<code>as.character()</code> is a another way to do this that is arguably
more expressive.</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb10-1"><a href="#cb10-1" tabindex="-1"></a>x <span class="ot">&lt;-</span> <span class="fu">glue</span>(<span class="st">&#39;</span></span>
<span id="cb10-2"><a href="#cb10-2" tabindex="-1"></a><span class="st"> abc</span></span>
<span id="cb10-3"><a href="#cb10-3" tabindex="-1"></a><span class="st"> &quot; }</span></span>
<span id="cb10-4"><a href="#cb10-4" tabindex="-1"></a></span>
<span id="cb10-5"><a href="#cb10-5" tabindex="-1"></a><span class="st"> xyz&#39;</span>)</span>
<span id="cb10-6"><a href="#cb10-6" tabindex="-1"></a><span class="fu">class</span>(x)</span>
<span id="cb10-7"><a href="#cb10-7" tabindex="-1"></a><span class="co">#&gt; [1] &quot;glue&quot; &quot;character&quot;</span></span>
<span id="cb10-8"><a href="#cb10-8" tabindex="-1"></a></span>
<span id="cb10-9"><a href="#cb10-9" tabindex="-1"></a>x</span>
<span id="cb10-10"><a href="#cb10-10" tabindex="-1"></a><span class="co">#&gt; abc</span></span>
<span id="cb10-11"><a href="#cb10-11" tabindex="-1"></a><span class="co">#&gt; &quot; }</span></span>
<span id="cb10-12"><a href="#cb10-12" tabindex="-1"></a><span class="co">#&gt; </span></span>
<span id="cb10-13"><a href="#cb10-13" tabindex="-1"></a><span class="co">#&gt; xyz</span></span>
<span id="cb10-14"><a href="#cb10-14" tabindex="-1"></a><span class="fu">unclass</span>(x)</span>
<span id="cb10-15"><a href="#cb10-15" tabindex="-1"></a><span class="co">#&gt; [1] &quot;abc\n\&quot;\t}\n\nxyz&quot;</span></span>
<span id="cb10-16"><a href="#cb10-16" tabindex="-1"></a><span class="fu">as.character</span>(x)</span>
<span id="cb10-17"><a href="#cb10-17" tabindex="-1"></a><span class="co">#&gt; [1] &quot;abc\n\&quot;\t}\n\nxyz&quot;</span></span></code></pre></div>
</div>
<div id="delimiters" class="section level2">
<h2>Delimiters</h2>
<p>By default, code to be evaluated goes inside <code>{}</code> in a
glue string. If want a literal curly brace in your string, double
it:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb11-1"><a href="#cb11-1" tabindex="-1"></a><span class="fu">glue</span>(<span class="st">&quot;The name of the package is {name}, not {{name}}.&quot;</span>)</span>
<span id="cb11-2"><a href="#cb11-2" tabindex="-1"></a><span class="co">#&gt; The name of the package is glue, not {name}.</span></span></code></pre></div>
<p>Sometimes its just more convenient to use different delimiters
altogether, especially if the template text comes from elsewhere or is
subject to external requirements. Consider this example where we want to
interpolate the function name into a code snippet that defines a
function:</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb12-1"><a href="#cb12-1" tabindex="-1"></a>fn_def <span class="ot">&lt;-</span> <span class="st">&quot;</span></span>
<span id="cb12-2"><a href="#cb12-2" tabindex="-1"></a><span class="st"> &lt;&lt;NAME&gt;&gt; &lt;- function(x) {</span></span>
<span id="cb12-3"><a href="#cb12-3" tabindex="-1"></a><span class="st"> # imagine a function body here</span></span>
<span id="cb12-4"><a href="#cb12-4" tabindex="-1"></a><span class="st"> }&quot;</span></span>
<span id="cb12-5"><a href="#cb12-5" tabindex="-1"></a><span class="fu">glue</span>(fn_def, <span class="at">NAME =</span> <span class="st">&quot;my_function&quot;</span>, <span class="at">.open =</span> <span class="st">&quot;&lt;&lt;&quot;</span>, <span class="at">.close =</span> <span class="st">&quot;&gt;&gt;&quot;</span>)</span>
<span id="cb12-6"><a href="#cb12-6" tabindex="-1"></a><span class="co">#&gt; my_function &lt;- function(x) {</span></span>
<span id="cb12-7"><a href="#cb12-7" tabindex="-1"></a><span class="co">#&gt; # imagine a function body here</span></span>
<span id="cb12-8"><a href="#cb12-8" tabindex="-1"></a><span class="co">#&gt; }</span></span></code></pre></div>
<p>In this glue string, <code>{</code> and <code>}</code> have very
special meaning. If we forced ourselves to double them, suddenly it
doesnt look like normal R code anymore. Using alternative delimiters is
a nice option in cases like this.</p>
</div>
<div id="where-glue-looks-for-values" class="section level2">
<h2>Where glue looks for values</h2>
<p>By default, <code>glue()</code> evaluates the code inside
<code>{}</code> in the caller environment:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb13-1"><a href="#cb13-1" tabindex="-1"></a><span class="fu">glue</span>(..., <span class="at">.envir =</span> <span class="fu">parent.frame</span>())</span></code></pre></div>
<p>So, for a top-level <code>glue()</code> call, that means the global
environment.</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb14-1"><a href="#cb14-1" tabindex="-1"></a>x <span class="ot">&lt;-</span> <span class="st">&quot;the caller environment&quot;</span></span>
<span id="cb14-2"><a href="#cb14-2" tabindex="-1"></a><span class="fu">glue</span>(<span class="st">&quot;By default, `glue()` evaluates code in {x}.&quot;</span>)</span>
<span id="cb14-3"><a href="#cb14-3" tabindex="-1"></a><span class="co">#&gt; By default, `glue()` evaluates code in the caller environment.</span></span></code></pre></div>
<p>But you can provide more narrowly scoped values by passing them to
<code>glue()</code> in <code>name = value</code> form:</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb15-1"><a href="#cb15-1" tabindex="-1"></a>x <span class="ot">&lt;-</span> <span class="st">&quot;the local environment&quot;</span></span>
<span id="cb15-2"><a href="#cb15-2" tabindex="-1"></a><span class="fu">glue</span>(</span>
<span id="cb15-3"><a href="#cb15-3" tabindex="-1"></a> <span class="st">&quot;`glue()` can access values from {x} or from {y}. {z}&quot;</span>,</span>
<span id="cb15-4"><a href="#cb15-4" tabindex="-1"></a> <span class="at">y =</span> <span class="st">&quot;named arguments&quot;</span>,</span>
<span id="cb15-5"><a href="#cb15-5" tabindex="-1"></a> <span class="at">z =</span> <span class="st">&quot;Woo!&quot;</span></span>
<span id="cb15-6"><a href="#cb15-6" tabindex="-1"></a>)</span>
<span id="cb15-7"><a href="#cb15-7" tabindex="-1"></a><span class="co">#&gt; `glue()` can access values from the local environment or from named arguments. Woo!</span></span></code></pre></div>
<p>If the relevant data lives in a data frame (or list or environment),
use <code>glue_data()</code> instead:</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb16-1"><a href="#cb16-1" tabindex="-1"></a>mini_mtcars <span class="ot">&lt;-</span> <span class="fu">head</span>(<span class="fu">cbind</span>(<span class="at">model =</span> <span class="fu">rownames</span>(mtcars), mtcars))</span>
<span id="cb16-2"><a href="#cb16-2" tabindex="-1"></a><span class="fu">rownames</span>(mini_mtcars) <span class="ot">&lt;-</span> <span class="cn">NULL</span></span>
<span id="cb16-3"><a href="#cb16-3" tabindex="-1"></a><span class="fu">glue_data</span>(mini_mtcars, <span class="st">&quot;{model} has {hp} hp.&quot;</span>)</span>
<span id="cb16-4"><a href="#cb16-4" tabindex="-1"></a><span class="co">#&gt; Mazda RX4 has 110 hp.</span></span>
<span id="cb16-5"><a href="#cb16-5" tabindex="-1"></a><span class="co">#&gt; Mazda RX4 Wag has 110 hp.</span></span>
<span id="cb16-6"><a href="#cb16-6" tabindex="-1"></a><span class="co">#&gt; Datsun 710 has 93 hp.</span></span>
<span id="cb16-7"><a href="#cb16-7" tabindex="-1"></a><span class="co">#&gt; Hornet 4 Drive has 110 hp.</span></span>
<span id="cb16-8"><a href="#cb16-8" tabindex="-1"></a><span class="co">#&gt; Hornet Sportabout has 175 hp.</span></span>
<span id="cb16-9"><a href="#cb16-9" tabindex="-1"></a><span class="co">#&gt; Valiant has 105 hp.</span></span></code></pre></div>
<p><code>glue_data()</code> is very natural to use with the pipe:</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb17-1"><a href="#cb17-1" tabindex="-1"></a>mini_mtcars <span class="sc">|&gt;</span></span>
<span id="cb17-2"><a href="#cb17-2" tabindex="-1"></a> <span class="fu">glue_data</span>(<span class="st">&quot;{model} gets {mpg} miles per gallon.&quot;</span>)</span>
<span id="cb17-3"><a href="#cb17-3" tabindex="-1"></a><span class="co">#&gt; Mazda RX4 gets 21 miles per gallon.</span></span>
<span id="cb17-4"><a href="#cb17-4" tabindex="-1"></a><span class="co">#&gt; Mazda RX4 Wag gets 21 miles per gallon.</span></span>
<span id="cb17-5"><a href="#cb17-5" tabindex="-1"></a><span class="co">#&gt; Datsun 710 gets 22.8 miles per gallon.</span></span>
<span id="cb17-6"><a href="#cb17-6" tabindex="-1"></a><span class="co">#&gt; Hornet 4 Drive gets 21.4 miles per gallon.</span></span>
<span id="cb17-7"><a href="#cb17-7" tabindex="-1"></a><span class="co">#&gt; Hornet Sportabout gets 18.7 miles per gallon.</span></span>
<span id="cb17-8"><a href="#cb17-8" tabindex="-1"></a><span class="co">#&gt; Valiant gets 18.1 miles per gallon.</span></span></code></pre></div>
<p>Returning to <code>glue()</code>, recall that it defaults to
evaluation in the caller environment. This has happy implications inside
a <code>dplyr::mutate()</code> pipeline. The data-masking feature of
<code>mutate()</code> means the columns of the target data frame are “in
scope” for a <code>glue()</code> call:</p>
<div class="sourceCode" id="cb18"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb18-1"><a href="#cb18-1" tabindex="-1"></a><span class="fu">library</span>(dplyr)</span>
<span id="cb18-2"><a href="#cb18-2" tabindex="-1"></a></span>
<span id="cb18-3"><a href="#cb18-3" tabindex="-1"></a>mini_mtcars <span class="sc">|&gt;</span></span>
<span id="cb18-4"><a href="#cb18-4" tabindex="-1"></a> <span class="fu">mutate</span>(<span class="at">note =</span> <span class="fu">glue</span>(<span class="st">&quot;{model} gets {mpg} miles per gallon.&quot;</span>)) <span class="sc">|&gt;</span></span>
<span id="cb18-5"><a href="#cb18-5" tabindex="-1"></a> <span class="fu">select</span>(note, cyl, disp)</span>
<span id="cb18-6"><a href="#cb18-6" tabindex="-1"></a><span class="co">#&gt; note cyl disp</span></span>
<span id="cb18-7"><a href="#cb18-7" tabindex="-1"></a><span class="co">#&gt; 1 Mazda RX4 gets 21 miles per gallon. 6 160</span></span>
<span id="cb18-8"><a href="#cb18-8" tabindex="-1"></a><span class="co">#&gt; 2 Mazda RX4 Wag gets 21 miles per gallon. 6 160</span></span>
<span id="cb18-9"><a href="#cb18-9" tabindex="-1"></a><span class="co">#&gt; 3 Datsun 710 gets 22.8 miles per gallon. 4 108</span></span>
<span id="cb18-10"><a href="#cb18-10" tabindex="-1"></a><span class="co">#&gt; 4 Hornet 4 Drive gets 21.4 miles per gallon. 6 258</span></span>
<span id="cb18-11"><a href="#cb18-11" tabindex="-1"></a><span class="co">#&gt; 5 Hornet Sportabout gets 18.7 miles per gallon. 8 360</span></span>
<span id="cb18-12"><a href="#cb18-12" tabindex="-1"></a><span class="co">#&gt; 6 Valiant gets 18.1 miles per gallon. 6 225</span></span></code></pre></div>
</div>
<div id="sql" class="section level2">
<h2>SQL</h2>
<p>glue has explicit support for constructing SQL statements. Use
backticks to quote identifiers. Normal strings and numbers are quoted
appropriately for your backend.</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb19-1"><a href="#cb19-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="cb19-2"><a href="#cb19-2" tabindex="-1"></a><span class="fu">colnames</span>(iris) <span class="ot">&lt;-</span> <span class="fu">gsub</span>(<span class="st">&quot;[.]&quot;</span>, <span class="st">&quot;_&quot;</span>, <span class="fu">tolower</span>(<span class="fu">colnames</span>(iris)))</span>
<span id="cb19-3"><a href="#cb19-3" tabindex="-1"></a>DBI<span class="sc">::</span><span class="fu">dbWriteTable</span>(con, <span class="st">&quot;iris&quot;</span>, iris)</span>
<span id="cb19-4"><a href="#cb19-4" tabindex="-1"></a>var <span class="ot">&lt;-</span> <span class="st">&quot;sepal_width&quot;</span></span>
<span id="cb19-5"><a href="#cb19-5" tabindex="-1"></a>tbl <span class="ot">&lt;-</span> <span class="st">&quot;iris&quot;</span></span>
<span id="cb19-6"><a href="#cb19-6" tabindex="-1"></a>num <span class="ot">&lt;-</span> <span class="dv">2</span></span>
<span id="cb19-7"><a href="#cb19-7" tabindex="-1"></a>val <span class="ot">&lt;-</span> <span class="st">&quot;setosa&quot;</span></span>
<span id="cb19-8"><a href="#cb19-8" tabindex="-1"></a><span class="fu">glue_sql</span>(<span class="st">&quot;</span></span>
<span id="cb19-9"><a href="#cb19-9" tabindex="-1"></a><span class="st"> SELECT {`var`}</span></span>
<span id="cb19-10"><a href="#cb19-10" tabindex="-1"></a><span class="st"> FROM {`tbl`}</span></span>
<span id="cb19-11"><a href="#cb19-11" tabindex="-1"></a><span class="st"> WHERE {`tbl`}.sepal_length &gt; {num}</span></span>
<span id="cb19-12"><a href="#cb19-12" tabindex="-1"></a><span class="st"> AND {`tbl`}.species = {val}</span></span>
<span id="cb19-13"><a href="#cb19-13" tabindex="-1"></a><span class="st"> &quot;</span>, <span class="at">.con =</span> con)</span>
<span id="cb19-14"><a href="#cb19-14" tabindex="-1"></a><span class="co">#&gt; &lt;SQL&gt; SELECT `sepal_width`</span></span>
<span id="cb19-15"><a href="#cb19-15" tabindex="-1"></a><span class="co">#&gt; FROM `iris`</span></span>
<span id="cb19-16"><a href="#cb19-16" tabindex="-1"></a><span class="co">#&gt; WHERE `iris`.sepal_length &gt; 2</span></span>
<span id="cb19-17"><a href="#cb19-17" tabindex="-1"></a><span class="co">#&gt; AND `iris`.species = &#39;setosa&#39;</span></span></code></pre></div>
<p><code>glue_sql()</code> can be used in conjunction with parameterized
queries using <code>DBI::dbBind()</code> to provide protection for SQL
Injection attacks.</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb20-1"><a href="#cb20-1" tabindex="-1"></a>sql <span class="ot">&lt;-</span> <span class="fu">glue_sql</span>(<span class="st">&quot;</span></span>
<span id="cb20-2"><a href="#cb20-2" tabindex="-1"></a><span class="st"> SELECT {`var`}</span></span>
<span id="cb20-3"><a href="#cb20-3" tabindex="-1"></a><span class="st"> FROM {`tbl`}</span></span>
<span id="cb20-4"><a href="#cb20-4" tabindex="-1"></a><span class="st"> WHERE {`tbl`}.sepal_length &gt; ?</span></span>
<span id="cb20-5"><a href="#cb20-5" tabindex="-1"></a><span class="st">&quot;</span>, <span class="at">.con =</span> con)</span>
<span id="cb20-6"><a href="#cb20-6" tabindex="-1"></a>query <span class="ot">&lt;-</span> DBI<span class="sc">::</span><span class="fu">dbSendQuery</span>(con, sql)</span>
<span id="cb20-7"><a href="#cb20-7" tabindex="-1"></a>DBI<span class="sc">::</span><span class="fu">dbBind</span>(query, <span class="fu">list</span>(num))</span>
<span id="cb20-8"><a href="#cb20-8" tabindex="-1"></a>DBI<span class="sc">::</span><span class="fu">dbFetch</span>(query, <span class="at">n =</span> <span class="dv">4</span>)</span>
<span id="cb20-9"><a href="#cb20-9" tabindex="-1"></a><span class="co">#&gt; sepal_width</span></span>
<span id="cb20-10"><a href="#cb20-10" tabindex="-1"></a><span class="co">#&gt; 1 3.5</span></span>
<span id="cb20-11"><a href="#cb20-11" tabindex="-1"></a><span class="co">#&gt; 2 3.0</span></span>
<span id="cb20-12"><a href="#cb20-12" tabindex="-1"></a><span class="co">#&gt; 3 3.2</span></span>
<span id="cb20-13"><a href="#cb20-13" tabindex="-1"></a><span class="co">#&gt; 4 3.1</span></span>
<span id="cb20-14"><a href="#cb20-14" tabindex="-1"></a>DBI<span class="sc">::</span><span class="fu">dbClearResult</span>(query)</span></code></pre></div>
<p><code>glue_sql()</code> can be used to build up more complex queries
with interchangeable sub queries. It returns <code>DBI::SQL()</code>
objects which are properly protected from quoting.</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb21-1"><a href="#cb21-1" tabindex="-1"></a>sub_query <span class="ot">&lt;-</span> <span class="fu">glue_sql</span>(<span class="st">&quot;</span></span>
<span id="cb21-2"><a href="#cb21-2" tabindex="-1"></a><span class="st"> SELECT *</span></span>
<span id="cb21-3"><a href="#cb21-3" tabindex="-1"></a><span class="st"> FROM {`tbl`}</span></span>
<span id="cb21-4"><a href="#cb21-4" tabindex="-1"></a><span class="st"> &quot;</span>, <span class="at">.con =</span> con)</span>
<span id="cb21-5"><a href="#cb21-5" tabindex="-1"></a></span>
<span id="cb21-6"><a href="#cb21-6" tabindex="-1"></a><span class="fu">glue_sql</span>(<span class="st">&quot;</span></span>
<span id="cb21-7"><a href="#cb21-7" tabindex="-1"></a><span class="st"> SELECT s.{`var`}</span></span>
<span id="cb21-8"><a href="#cb21-8" tabindex="-1"></a><span class="st"> FROM ({sub_query}) AS s</span></span>
<span id="cb21-9"><a href="#cb21-9" tabindex="-1"></a><span class="st"> &quot;</span>, <span class="at">.con =</span> con)</span>
<span id="cb21-10"><a href="#cb21-10" tabindex="-1"></a><span class="co">#&gt; &lt;SQL&gt; SELECT s.`sepal_width`</span></span>
<span id="cb21-11"><a href="#cb21-11" tabindex="-1"></a><span class="co">#&gt; FROM (SELECT *</span></span>
<span id="cb21-12"><a href="#cb21-12" tabindex="-1"></a><span class="co">#&gt; FROM `iris`) AS s</span></span></code></pre></div>
<p>If you want to input multiple values for use in SQL IN statements put
<code>*</code> at the end of the value and the values will be collapsed
and quoted appropriately.</p>
<div class="sourceCode" id="cb22"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb22-1"><a href="#cb22-1" tabindex="-1"></a><span class="fu">glue_sql</span>(<span class="st">&quot;SELECT * FROM {`tbl`} WHERE sepal_length IN ({vals*})&quot;</span>,</span>
<span id="cb22-2"><a href="#cb22-2" tabindex="-1"></a> <span class="at">vals =</span> <span class="dv">1</span>, <span class="at">.con =</span> con)</span>
<span id="cb22-3"><a href="#cb22-3" tabindex="-1"></a><span class="co">#&gt; &lt;SQL&gt; SELECT * FROM `iris` WHERE sepal_length IN (1)</span></span>
<span id="cb22-4"><a href="#cb22-4" tabindex="-1"></a></span>
<span id="cb22-5"><a href="#cb22-5" tabindex="-1"></a><span class="fu">glue_sql</span>(<span class="st">&quot;SELECT * FROM {`tbl`} WHERE sepal_length IN ({vals*})&quot;</span>,</span>
<span id="cb22-6"><a href="#cb22-6" tabindex="-1"></a> <span class="at">vals =</span> <span class="dv">1</span><span class="sc">:</span><span class="dv">5</span>, <span class="at">.con =</span> con)</span>
<span id="cb22-7"><a href="#cb22-7" tabindex="-1"></a><span class="co">#&gt; &lt;SQL&gt; SELECT * FROM `iris` WHERE sepal_length IN (1, 2, 3, 4, 5)</span></span>
<span id="cb22-8"><a href="#cb22-8" tabindex="-1"></a></span>
<span id="cb22-9"><a href="#cb22-9" tabindex="-1"></a><span class="fu">glue_sql</span>(<span class="st">&quot;SELECT * FROM {`tbl`} WHERE species IN ({vals*})&quot;</span>,</span>
<span id="cb22-10"><a href="#cb22-10" tabindex="-1"></a> <span class="at">vals =</span> <span class="st">&quot;setosa&quot;</span>, <span class="at">.con =</span> con)</span>
<span id="cb22-11"><a href="#cb22-11" tabindex="-1"></a><span class="co">#&gt; &lt;SQL&gt; SELECT * FROM `iris` WHERE species IN (&#39;setosa&#39;)</span></span>
<span id="cb22-12"><a href="#cb22-12" tabindex="-1"></a></span>
<span id="cb22-13"><a href="#cb22-13" tabindex="-1"></a><span class="fu">glue_sql</span>(<span class="st">&quot;SELECT * FROM {`tbl`} WHERE species IN ({vals*})&quot;</span>,</span>
<span id="cb22-14"><a href="#cb22-14" tabindex="-1"></a> <span class="at">vals =</span> <span class="fu">c</span>(<span class="st">&quot;setosa&quot;</span>, <span class="st">&quot;versicolor&quot;</span>), <span class="at">.con =</span> con)</span>
<span id="cb22-15"><a href="#cb22-15" tabindex="-1"></a><span class="co">#&gt; &lt;SQL&gt; SELECT * FROM `iris` WHERE species IN (&#39;setosa&#39;, &#39;versicolor&#39;)</span></span></code></pre></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>