-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstyle-guide.html
More file actions
288 lines (260 loc) · 20.4 KB
/
style-guide.html
File metadata and controls
288 lines (260 loc) · 20.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
<!DOCTYPE html>
<!-- Generated by pkgdown: do not edit by hand --><html lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Style Guide • rdev</title>
<!-- favicons --><link rel="icon" type="image/png" sizes="96x96" href="../favicon-96x96.png">
<link rel="icon" type="”image/svg+xml”" href="../favicon.svg">
<link rel="apple-touch-icon" sizes="180x180" href="../apple-touch-icon.png">
<link rel="icon" sizes="any" href="../favicon.ico">
<link rel="manifest" href="../site.webmanifest">
<script src="../lightswitch.js"></script><script src="../deps/jquery-3.6.0/jquery-3.6.0.min.js"></script><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link href="../deps/bootstrap-5.3.1/bootstrap.min.css" rel="stylesheet">
<script src="../deps/bootstrap-5.3.1/bootstrap.bundle.min.js"></script><link href="../deps/font-awesome-6.5.2/css/all.min.css" rel="stylesheet">
<link href="../deps/font-awesome-6.5.2/css/v4-shims.min.css" rel="stylesheet">
<script src="../deps/headroom-0.11.0/headroom.min.js"></script><script src="../deps/headroom-0.11.0/jQuery.headroom.min.js"></script><script src="../deps/bootstrap-toc-1.0.1/bootstrap-toc.min.js"></script><script src="../deps/clipboard.js-2.0.11/clipboard.min.js"></script><script src="../deps/search-1.0.0/autocomplete.jquery.min.js"></script><script src="../deps/search-1.0.0/fuse.min.js"></script><script src="../deps/search-1.0.0/mark.min.js"></script><!-- pkgdown --><script src="../pkgdown.js"></script><link href="../extra.css" rel="stylesheet">
<meta property="og:title" content="Style Guide">
</head>
<body>
<a href="#main" class="visually-hidden-focusable">Skip to contents</a>
<nav class="navbar navbar-expand-lg fixed-top " aria-label="Site navigation"><div class="container">
<a class="navbar-brand me-2" href="../index.html">rdev</a>
<small class="nav-text text-muted me-auto" data-bs-toggle="tooltip" data-bs-placement="bottom" title="">1.15.6</small>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div id="navbar" class="collapse navbar-collapse ms-3">
<ul class="navbar-nav me-auto">
<li class="nav-item"><a class="nav-link" href="../articles/rdev.html">Get started</a></li>
<li class="nav-item"><a class="nav-link" href="../reference/index.html">Reference</a></li>
<li class="active nav-item dropdown">
<button class="nav-link dropdown-toggle" type="button" id="dropdown-articles" data-bs-toggle="dropdown" aria-expanded="false" aria-haspopup="true">Articles</button>
<ul class="dropdown-menu" aria-labelledby="dropdown-articles">
<li><a class="dropdown-item" href="../articles/analysis-package-layout.html">Analysis Package Layout</a></li>
<li><a class="dropdown-item" href="../articles/style-guide.html">Style Guide</a></li>
</ul>
</li>
<li class="nav-item"><a class="nav-link" href="../news/index.html">Changelog</a></li>
</ul>
<ul class="navbar-nav">
<li class="nav-item"><form class="form-inline" role="search">
<input class="form-control" type="search" name="search-input" id="search-input" autocomplete="off" aria-label="Search site" placeholder="Search for" data-search-index="../search.json">
</form></li>
<li class="nav-item"><a class="external-link nav-link" href="https://github.com/jabenninghoff/rdev/" aria-label="GitHub"><span class="fa fab fa-github fa-lg"></span></a></li>
<li class="nav-item dropdown">
<button class="nav-link dropdown-toggle" type="button" id="dropdown-lightswitch" data-bs-toggle="dropdown" aria-expanded="false" aria-haspopup="true" aria-label="Light switch"><span class="fa fa-sun"></span></button>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="dropdown-lightswitch">
<li><button class="dropdown-item" data-bs-theme-value="light"><span class="fa fa-sun"></span> Light</button></li>
<li><button class="dropdown-item" data-bs-theme-value="dark"><span class="fa fa-moon"></span> Dark</button></li>
<li><button class="dropdown-item" data-bs-theme-value="auto"><span class="fa fa-adjust"></span> Auto</button></li>
</ul>
</li>
</ul>
</div>
</div>
</nav><div class="container template-article">
<div class="row">
<main id="main" class="col-md-9"><div class="page-header">
<img src="../logo.png" class="logo" alt=""><h1>Style Guide</h1>
<small class="dont-index">Source: <a href="https://github.com/jabenninghoff/rdev/blob/HEAD/vignettes/style-guide.Rmd" class="external-link"><code>vignettes/style-guide.Rmd</code></a></small>
<div class="d-none name"><code>style-guide.Rmd</code></div>
</div>
<p>The R Style Guide describes the rdev style conventions, along with
automated checks (<a href="https://styler.r-lib.org" class="external-link">styler</a> and <a href="https://lintr.r-lib.org" class="external-link">lintr</a>). The rdev R Style Guide
incorporates both the <a href="https://style.tidyverse.org" class="external-link">Tidyverse
Style Guide</a> and <a href="https://google.github.io/styleguide/Rguide.html" class="external-link">Google’s R Style
Guide</a>.</p>
<div class="section level2">
<h2 id="rdev-conventions">rdev conventions<a class="anchor" aria-label="anchor" href="#rdev-conventions"></a>
</h2>
<p>rdev uses a mix of Google and tidyverse conventions.</p>
<div class="section level3">
<h3 id="naming-conventions">Naming conventions<a class="anchor" aria-label="anchor" href="#naming-conventions"></a>
</h3>
<p>rdev follows the tidyverse naming convention of
<code>snake_case</code>.</p>
</div>
<div class="section level3">
<h3 id="right-hand-assignment">Right-hand assignment<a class="anchor" aria-label="anchor" href="#right-hand-assignment"></a>
</h3>
<p>rdev follows Google’s style guide, and does not use right-hand
assignment.</p>
</div>
<div class="section level3">
<h3 id="returns">Returns<a class="anchor" aria-label="anchor" href="#returns"></a>
</h3>
<p>rdev typically uses implicit returns unless needed for flow control
or to construct a specific return structure.</p>
</div>
<div class="section level3">
<h3 id="qualifying-namespaces">Qualifying namespaces<a class="anchor" aria-label="anchor" href="#qualifying-namespaces"></a>
</h3>
<p>Use of <code>@import</code> and <code>@importFrom</code> are
discouraged, instead using <code>::</code> in functions defined in
<code>R/</code>. An exception is infix functions (<code>%name%</code>),
which are always imported, using roxygen <code>@importFrom</code>.
Within R and Quarto Notebooks, use of <code><a href="https://rdrr.io/r/base/library.html" class="external-link">library()</a></code> is
encouraged for readability.</p>
</div>
<div class="section level3">
<h3 id="package-level-documentation">Package-level documentation<a class="anchor" aria-label="anchor" href="#package-level-documentation"></a>
</h3>
<p>rdev package documentation lives in <code>R/package.R</code>.</p>
<p>Additionally, use of base R is encouraged within functions defined in
<code>R/</code> (to control dependencies), where tidyverse R is
encouraged within notebooks for readability.</p>
<p>R Markdown documents should generally wrap at the same width as code,
with exceptions for the R Notebook ‘description line’ (the first
non-blank line in the body), and long hyperlinks.</p>
</div>
</div>
<div class="section level2">
<h2 id="styler">styler<a class="anchor" aria-label="anchor" href="#styler"></a>
</h2>
<p>The rdev package implements <a href="https://styler.r-lib.org" class="external-link">styler</a> using the styler defaults,
with permanent caching enabled
(<code>options(styler.cache_root = "styler-perm")</code>). The
<code><a href="../reference/style_all.html">style_all()</a></code> function applies the tidyverse style to all R
and Quarto files (<code>R</code>, <code>Rprofile</code>,
<code>Rmd</code>, <code>Rnw</code>, <code>qmd</code>) in the package
directory structure.</p>
</div>
<div class="section level2">
<h2 id="lintr">lintr<a class="anchor" aria-label="anchor" href="#lintr"></a>
</h2>
<p>The <code><a href="../reference/lint_all.html">lint_all()</a></code> function lints all R and Quarto files
(<code>R</code>, <code>Rmd</code>, <code>qmd</code>, <code>Rnw</code>,
<code>Rhtml</code>, <code>Rpres</code>, <code>Rrst</code>,
<code>Rtex</code>, <code>Rtxt</code>) with <a href="https://lintr.r-lib.org" class="external-link">lintr</a> using an opinionated
configuration (<code>.lintr</code>):</p>
<div class="sourceCode" id="cb1"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="va">linters</span><span class="op">:</span> <span class="fu">linters_with_tags</span><span class="op">(</span></span>
<span> tags <span class="op">=</span> <span class="cn">NULL</span>,</span>
<span> implicit_integer_linter <span class="op">=</span> <span class="cn">NULL</span>,</span>
<span> <span class="fu">line_length_linter</span><span class="op">(</span><span class="fl">100</span><span class="op">)</span>,</span>
<span> missing_package_linter <span class="op">=</span> <span class="cn">NULL</span>,</span>
<span> namespace_linter <span class="op">=</span> <span class="cn">NULL</span>,</span>
<span> nonportable_path_linter <span class="op">=</span> <span class="cn">NULL</span>,</span>
<span> <span class="fu">paste_linter</span><span class="op">(</span>allow_file_path <span class="op">=</span> <span class="st">"always"</span><span class="op">)</span>,</span>
<span> todo_comment_linter <span class="op">=</span> <span class="cn">NULL</span>,</span>
<span> <span class="fu">undesirable_function_linter</span><span class="op">(</span></span>
<span> <span class="fu"><a href="https://rdrr.io/r/base/with.html" class="external-link">within</a></span><span class="op">(</span><span class="va">all_undesirable_functions</span>, <span class="fu"><a href="https://rdrr.io/r/base/rm.html" class="external-link">rm</a></span><span class="op">(</span><span class="va">ifelse</span>, <span class="va">library</span>, <span class="va">require</span>, <span class="va">structure</span><span class="op">)</span><span class="op">)</span></span>
<span> <span class="op">)</span>,</span>
<span> <span class="fu">undesirable_operator_linter</span><span class="op">(</span><span class="va">all_undesirable_operators</span><span class="op">)</span>,</span>
<span> <span class="fu">unnecessary_concatenation_linter</span><span class="op">(</span>allow_single_expression <span class="op">=</span> <span class="cn">FALSE</span><span class="op">)</span>,</span>
<span> <span class="fu">unused_import_linter</span><span class="op">(</span></span>
<span> except_packages <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"bit64"</span>, <span class="st">"data.table"</span>, <span class="st">"tidyverse"</span>, <span class="fu">pkgload</span><span class="fu">::</span><span class="fu"><a href="https://pkgload.r-lib.org/reference/packages.html" class="external-link">pkg_name</a></span><span class="op">(</span><span class="st">"."</span><span class="op">)</span><span class="op">)</span></span>
<span> <span class="op">)</span></span>
<span> <span class="op">)</span></span></code></pre></div>
<p>These settings were deliberately chosen to meet specific goals:</p>
<div class="section level3">
<h3 id="use-all-linters">Use all linters<a class="anchor" aria-label="anchor" href="#use-all-linters"></a>
</h3>
<div class="sourceCode" id="cb2"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb2-1"><a href="#cb2-1" tabindex="-1"></a>linters<span class="sc">:</span> <span class="fu">linters_with_tags</span>(</span>
<span id="cb2-2"><a href="#cb2-2" tabindex="-1"></a> <span class="at">tags =</span> <span class="cn">NULL</span>,</span></code></pre></div>
<p>This selects all linters, including the new <a href="https://lintr.r-lib.org/news/index.html#google-linters-3-0-0" class="external-link">Google
linters</a>. By selecting all linters, not just the defaults, this
forces evaluation of new linters as they are added to lintr. Specific
linters are disabled or configured per rdev style.</p>
</div>
<div class="section level3">
<h3 id="allow-implicit-integers">Allow implicit integers<a class="anchor" aria-label="anchor" href="#allow-implicit-integers"></a>
</h3>
<div class="sourceCode" id="cb3"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb3-1"><a href="#cb3-1" tabindex="-1"></a> implicit_integer_linter <span class="ot">=</span> <span class="cn">NULL</span>,</span></code></pre></div>
<p>The implicit integer linter checks that integers are explicitly typed
using the form <code>1L</code>. Again, while this is safer, implicit
integers are common practice, including in the output of
<code><a href="https://rdrr.io/r/base/dput.html" class="external-link">dput()</a></code>:</p>
<div class="sourceCode" id="cb4"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="fu"><a href="https://rdrr.io/r/base/dput.html" class="external-link">dput</a></span><span class="op">(</span><span class="fu"><a href="https://rdrr.io/r/base/character.html" class="external-link">character</a></span><span class="op">(</span><span class="fl">0L</span><span class="op">)</span><span class="op">)</span></span>
<span><span class="co">#> character(0)</span></span></code></pre></div>
</div>
<div class="section level3">
<h3 id="set-line-length">Set line length<a class="anchor" aria-label="anchor" href="#set-line-length"></a>
</h3>
<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">line_length_linter</span>(<span class="dv">100</span>),</span></code></pre></div>
<p>A line length of 100 is a reasonable width when working in the
RStudio IDE on a laptop.</p>
</div>
<div class="section level3">
<h3 id="use-renv-for-missing-packages">Use renv for missing packages<a class="anchor" aria-label="anchor" href="#use-renv-for-missing-packages"></a>
</h3>
<div class="sourceCode" id="cb6"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb6-1"><a href="#cb6-1" tabindex="-1"></a> missing_package_linter <span class="ot">=</span> <span class="cn">NULL</span>,</span>
<span id="cb6-2"><a href="#cb6-2" tabindex="-1"></a> namespace_linter <span class="ot">=</span> <span class="cn">NULL</span>,</span></code></pre></div>
<p>The missing package linter and the namespace linter both check for
packages referenced in code that are not installed. rdev uses <a href="https://rstudio.github.io/renv/" class="external-link">renv</a> to manage packages,
which does a better job of detecting missing packages, including not
complaining when the current package (<code>"."</code>) is not
installed.</p>
</div>
<div class="section level3">
<h3 id="allow-non-portable-paths">Allow non-portable paths<a class="anchor" aria-label="anchor" href="#allow-non-portable-paths"></a>
</h3>
<div class="sourceCode" id="cb7"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb7-1"><a href="#cb7-1" tabindex="-1"></a> nonportable_path_linter <span class="ot">=</span> <span class="cn">NULL</span>,</span>
<span id="cb7-2"><a href="#cb7-2" tabindex="-1"></a> <span class="fu">paste_linter</span>(<span class="at">allow_file_path =</span> <span class="st">"always"</span>),</span></code></pre></div>
<p>The non-portable path linter generates too many false positives,
including calls to <a href="https://fs.r-lib.org" class="external-link">fs</a>, which
essentially makes UNIX-style paths portable across operating systems.
Similarly, the <code>allow_file_path</code> default option of
<code>"double_slash"</code> generates false positives when used with
fs.</p>
</div>
<div class="section level3">
<h3 id="allow-todo-comments">Allow TODO comments<a class="anchor" aria-label="anchor" href="#allow-todo-comments"></a>
</h3>
<div class="sourceCode" id="cb8"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb8-1"><a href="#cb8-1" tabindex="-1"></a> todo_comment_linter <span class="ot">=</span> <span class="cn">NULL</span>,</span></code></pre></div>
<p>rdev conventions encourage use of <code># TODO:</code> comments as a
convenient way of identifying needed or planned updates inline.</p>
</div>
<div class="section level3">
<h3 id="disallow-almost-all-undesirable-functions-and-operators">Disallow almost all undesirable functions and operators<a class="anchor" aria-label="anchor" href="#disallow-almost-all-undesirable-functions-and-operators"></a>
</h3>
<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="fu">undesirable_function_linter</span>(</span>
<span id="cb9-2"><a href="#cb9-2" tabindex="-1"></a> <span class="fu">within</span>(all_undesirable_functions, <span class="fu">rm</span>(ifelse, library, require, structure))</span>
<span id="cb9-3"><a href="#cb9-3" tabindex="-1"></a> ),</span>
<span id="cb9-4"><a href="#cb9-4" tabindex="-1"></a> <span class="fu">undesirable_operator_linter</span>(all_undesirable_operators),</span></code></pre></div>
<p>Enable all undesirable functions and operators, not just the
defaults, except for <code><a href="https://rdrr.io/r/base/ifelse.html" class="external-link">ifelse()</a></code> which is more succinct than
an <code>if</code>/<code>else</code> block, <code><a href="https://rdrr.io/r/base/library.html" class="external-link">library()</a></code>,
<code><a href="https://rdrr.io/r/base/library.html" class="external-link">require()</a></code>, and <code><a href="https://rdrr.io/r/base/structure.html" class="external-link">structure()</a></code>. Use of
<code><a href="https://rdrr.io/r/base/library.html" class="external-link">require()</a></code> within <code>.Rprofile</code> and
<code><a href="https://rdrr.io/r/base/library.html" class="external-link">library()</a></code> within R Markdown documents is an appropriate and
common practice, although neither should be used within package code.
<code><a href="https://rdrr.io/r/base/structure.html" class="external-link">structure()</a></code> is useful for comparing test results to values
generated with <code><a href="https://rdrr.io/r/base/dput.html" class="external-link">dput()</a></code>.</p>
</div>
<div class="section level3">
<h3 id="enforce-strict-unnecessary-concatenation">Enforce strict unnecessary concatenation<a class="anchor" aria-label="anchor" href="#enforce-strict-unnecessary-concatenation"></a>
</h3>
<div class="sourceCode" id="cb10"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb10-1"><a href="#cb10-1" tabindex="-1"></a> <span class="fu">unnecessary_concatenation_linter</span>(<span class="at">allow_single_expression =</span> <span class="cn">FALSE</span>),</span></code></pre></div>
<p>Enforce the stricter version of the unnecessary concatenation
linter.</p>
</div>
<div class="section level3">
<h3 id="verify-imported-packages-are-used">Verify imported packages are used<a class="anchor" aria-label="anchor" href="#verify-imported-packages-are-used"></a>
</h3>
<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">unused_import_linter</span>(</span>
<span id="cb11-2"><a href="#cb11-2" tabindex="-1"></a> <span class="at">except_packages =</span> <span class="fu">c</span>(<span class="st">"bit64"</span>, <span class="st">"data.table"</span>, <span class="st">"tidyverse"</span>, pkgload<span class="sc">::</span><span class="fu">pkg_name</span>(<span class="st">"."</span>))</span>
<span id="cb11-3"><a href="#cb11-3" tabindex="-1"></a> )</span>
<span id="cb11-4"><a href="#cb11-4" tabindex="-1"></a> <span class="er">)</span></span></code></pre></div>
<p>Verify that imported packages are used, except for packages that are
attached for their side effects, and the current package (to support
package development).</p>
</div>
</div>
</main><aside class="col-md-3"><nav id="toc" aria-label="Table of contents"><h2>On this page</h2>
</nav></aside>
</div>
<footer><div class="pkgdown-footer-left">
<p>Developed by John Benninghoff.</p>
</div>
<div class="pkgdown-footer-right">
<p>Site built with <a href="https://pkgdown.r-lib.org/" class="external-link">pkgdown</a> 2.2.0.</p>
</div>
</footer>
</div>
</body>
</html>