-
Notifications
You must be signed in to change notification settings - Fork 0
/
guidr.html
602 lines (547 loc) · 22.3 KB
/
guidr.html
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
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Chief R Style Guide</title>
<style>
body {
background-color: #fff;
color: #333;
font-family: sans-serif;
font-size: 10pt;
margin: 0 0 5px 5px;
}
h1, h2, h3, h4, h5, h6, .toc_title {
color: #06c;
margin-top: 2em;
margin-bottom: 1em;
}
h1 {
text-align: center;
font-size: 18pt;
}
h2, .toc_title {
font-weight: bold;
font-size: 12pt;
}
h3, h4, h5, h6 {
font-size: 10pt;
}
.toc_category, .toc_stylepoint {
font-size: 10pt;
padding-top: .3em;
padding-bottom: .3em;
}
table {
border-collapse: collapse;
}
td, th {
border: 1px solid #ccc;
padding: 2px 12px;
font-size: 10pt;
}
.toc td, .toc th {
border-width: 1px 5px;
}
code, samp, var {
color: #060;
}
pre {
white-space: pre-wrap;
font-size: 10pt;
display: block;
color: #060;
background-color: #f8fff8;
border-color: #f0fff0;
border-style: solid;
border-top-width: 1px;
border-bottom-width: 1px;
border-right-width: 1px;
border-left-width: 5px;
padding-left: 12px;
padding-right: 12px;
padding-top: 4px;
padding-bottom: 4px;
}
pre.badcode {
color: #c00;
background-color: #fff8f8;
border-color: #fff0f0;
}
.showhide_button {
float: left;
cursor: pointer;
border-width: 1px;
border-style: solid;
border-color: #ddd #aaa #aaa #ddd;
padding: 0 3px 1px;
margin: 0 4px 8px 0;
border-radius: 3px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
}
.link_button {
float: left;
display: none;
background-color: #f8f8ff;
border-color: #f0f0ff;
border-style: solid;
border-width: 1px;
font-size: 75%;
margin-top: 0;
margin-left: -50px;
padding: 4px;
border-radius: 3px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
}
address {
text-align: right;
}
hr {
margin-top: 3.5em;
border-width: 1px;
color: #fff;
}
.stylepoint_section {
display: block;
margin-bottom: 1em;
color: #5588ff;
font-family: sans-serif;
font-size: 90%;
font-weight: bold;
margin-left: -2%;
}
.stylepoint_subsection {
color: #667799;
font-family: sans-serif;
font-size: 90%;
font-weight: bold;
margin-left: -1%;
}
.stylepoint_subsubsection {
color: #667799;
font-family: sans-serif;
font-size: 80%;
font-weight: bold;
margin-left: 0;
}
.revision {
text-align: right;
}
</style>
</head>
<body>
<h1>Chief R Style Guide</h1>
<p>
R is a high-level programming language used primarily for
statistical computing and graphics. The goal of the R
Programming Style Guide is to make our R code easier to read,
share, and verify. The rules below ground on <a href="https://google.github.io/styleguide/Rguide.xml">Google's R Style Guide</a> (<a href="https://creativecommons.org/licenses/by/3.0/">CC BY 3.0</a>) authored by <a href="https://github.com/wieczorek1990">@wieczorek1990</a> and <a href="https://github.com/herrjemand">@herrjemand</a>. The Chief R Style Guide incorporates modifications of all sections by <a href="https://github.com/chiefBiiko">@chiefBiiko</a>.
</p>
<h2>Summary: R Style Rules</h2>
<ol>
<li><a href="guidr.html#filenames">File Names</a>: lowercase, their separator is <code>_</code> ending with <code>.R</code> or <code>.Rmd</code> </li>
<li><a href="guidr.html#identifiers">Identifiers</a>: <code>variable</code>,
<code>functionName</code>,
<code>CONSTANT</code>,
<code>GLOBAL</code></li>
<li><a href="guidr.html#linelength">Line Length</a>: try respecting a maximum of 80 characters</li>
<li><a href="guidr.html#indentation">Indentation</a>: two spaces, no tabs</li>
<li><a href="guidr.html#spacing">Spacing</a></li>
<li><b>Strings</b>: single quotes - double quotes only when nesting strings</li>
<li><a href="guidr.html#curlybraces">Curly Braces</a>: first on same line, last on
own line</li>
<li><a href="guidr.html#else">else</a>: surround else with braces </li>
<li><a href="guidr.html#assignment">Assignment</a>: use <code><-</code>, not
<code>=</code></li>
<li><a href="guidr.html#semicolons">Semicolons</a>: don't use them</li>
<li><a href="guidr.html#generallayout"> General Layout and Ordering</a></li>
<li><a href="guidr.html#comments"> Commenting Guidelines</a>: all comments begin
with <code>#</code> followed by a space; inline comments need two
spaces before the <code>#</code></li>
<li><a href="guidr.html#functiondefinition">Function Definitions and Calls</a></li>
<li><a href="guidr.html#functiondocumentation"> Function Documentation</a></li>
<li><a href="guidr.html#examplefunction"> Example Function</a></li>
<li><a href="guidr.html#todo"> TODO Style</a>: <code># TODO(username)</code></li>
</ol>
<h2>Summary: R Language Rules</h2>
<ol>
<li><a href="guidr.html#attach"> <code>attach</code></a>: avoid it</li>
<li><a href="guidr.html#functionlanguage"> Functions</a>:
errors should be raised using <code>stop()</code> or <code>stopifnot()</code></li>
<li><a href="guidr.html#object"> Objects and Methods</a>: avoid S4 objects and
methods when possible; never mix S3 and S4 </li>
</ol>
<h3>Notation and Naming</h3>
<h4 id="filenames">File Names</h4>
<p>
File names should end in <code>.R</code> or <code>.Rmd</code> and, of course, be
meaningful.
<br /> GOOD: <code>predict_ad_revenue.R</code>
<br /> BAD: <code><span style="color:red">foo.R</span></code>
</p>
<h4 id="identifiers">Identifiers</h4>
<p>
Don't use hyphens ( <code>-</code> ) in identifiers.
Avoid underscores ( <code>_</code> ) if possible.
Identifiers should be named according to the following conventions.
The preferred form for variable names is all lower case
letters and words separated with dots
(<code>variable</code> or <code>variable.name</code>);
function/method names should be camelCase, alternatively all lowercase
with only a single underscore as separator or just all lowercase
with a verb as name that explicitely marks it as a function
(<code>functionName</code> or <code>func_name</code> or <code>verb</code>);
constants and globals are named all uppercase and with an <code>_</code> as
separator.
</p>
<ul>
<li><code>variable.name</code> or just <code>variable</code>
<br /> GOOD: <code>avg.clicks</code>
<br /> BAD: <code><span style="color:red">avg_Clicks</span></code>
</li>
<li><code>functionName </code> or <code>func_name</code> or <code>verb</code>
<br /> GOOD: <code>calculateAvgClicks, do_sth, make</code>
<br /> OK: <code>CalculateAvgClicks</code>
<br /> BAD: <code><span style="color:red">Calculate_Avg_Clicks</span>,
<span style="color:red">calculate_avg_clicks</span></code>
<br /> Make function names verbs.
<br /><em>Exception: When creating a classed object, the function
name (constructor) and class should match (e.g., lm).</em></li>
<li><code>CONSTANT, GLOBAL</code> or <code>CONSTANT_NAME, GLOBAL_NAME</code></li>
</ul>
<h3>Syntax</h3>
<h4 id="linelength">Line Length</h4>
<p>
The ideal line length is maximal 80 characters.
</p>
<h4 id="indentation">Indentation</h4>
<p>
When indenting your code, use two spaces. Never use tabs or mix
tabs and spaces.
<br /><em>Exception: When a line break occurs inside parentheses,
align the wrapped line with the first character inside the
parenthesis.</em>
</p>
<h4 id="spacing">Spacing</h4>
<p>
Place spaces around all binary operators (<code>=</code>,
<code>+</code>, <code>-</code>, <code><-</code>, etc.).
<br /><em> Exception: Spaces around <code>=</code>'s are
optional when passing parameters in a function call.</em>
</p>
<p>
Do not place a space before a comma, but always place one after a
comma.
<br /><br /> GOOD:
</p>
<pre>prior <- table(df[df$days < 0, 'id'])
total <- sum(x[, 1])
total <- sum(x[1, ])</pre>
<p>
BAD:
</p>
<pre><span style="color:red">prior <- table(df[df$days<0, 'id']) # Needs spaces around <
prior <- table(df[df$days < 0,'id']) # Needs a space after the ,
prior<-table(df[df$days < 0, 'id']) # Needs spaces around <-
total <- sum(x[ ,1]) # Needs a space AFTER the , - not before</span>
</pre>
<p>
Place a space before left parenthesis, except in a function call.
</p>
<p>
GOOD:
<br /><code>if (debug)</code>
</p>
<p>
BAD:
<br /><code><span style="color:red">if(debug)</span></code>
</p>
<p>
Extra spacing (i.e., more than one space in a row) is okay if it
improves alignment of equals signs or arrows (<code><-</code>).
</p>
<pre>plot(x = x.coord,
y = data.mat[, MakeColName(metric, ptiles[1], 'roiOpt')],
ylim = ylim,
xlab = 'dates',
ylab = metric,
main = (paste(metric, ' for 3 samples ', sep = '')))
</pre>
<p>
Do not place spaces around code in parentheses or square brackets.
<br /><em> Exception: Always place a space after a comma.</em>
</p>
<p>
GOOD:</p><pre>if (debug)
x[1, ]</pre>
<p>
BAD:</p><pre><span style="color:red">if ( debug ) # No spaces around debug
x[1,] # Needs a space after the comma </span></pre>
<h4 id="curlybraces">Curly Braces</h4>
<p>
An opening curly brace should never go on its own line; a closing
curly brace should always go on its own line. You can and are
encouraged to omit curly braces when a block consists of a short single
statement only and together with its keyword initializer fits on one
line within a 80 character window; In such cases the keyword
(<code>if ()</code>, <code>function()</code> etc.) and its corresponding
block/statement should be on the same line without enclosing curly
braces. Such one-liners allow for short but readable conditional tests
and anonymous functions. Complex <code>if/else</code> constructs must
always make use of curly braces.
</p>
GOOD:
<pre>
if (exists(secret) && is.null(secret)) {
secret <- as.character('SAKAWASAFESECRETSOSUSUSTAYSPINNING')
}
if (x < 0) 'minus' else 'plus'
if (is.null(ylim)) ylim <- c(0, 0.06)</pre>
<p>
Do not surround the body of an one-liner with curly braces. If a
block contains multiple statements always make use of curly
braces.
</p>
<p>BAD: </p>
<pre style="color:red">
if (is.null(ylim)) {ylim <- c(0, 0.06)}
if (condition)
one line
else
one line
</pre>
<h4 id="else">Surround else with braces</h4>
<p>
An <code>else</code> statement should always be surrounded on the
same line by curly braces.
When using <code>if/else</code> constructs for switching through cases,
a final else block whose only purpose is preventing fallthrough by
raising an error with <code>stop()</code> can be one the same line
as its <code>else</code> keyword but then must be surrounded with
one space on both sides and curly braces.
</p>
<p>
GOOD:<br />
</p>
<pre>if (condition) {
# one or more lines
} else if (condition) {
# one or more lines
} else { stop('error') }
</pre>
<p>
BAD:<br />
</p>
<pre style="color:red">
if (condition) {
# one or more lines
}
else {
# one or more lines
}
</pre>
<h4 id="assignment">Assignment</h4>
<p>
Use <code><-</code>, not <code>=</code>, for assignment.
</p>
<p>
GOOD:
<br /><code> x <- 5 </code>
</p>
<p>
BAD:
<br /><code><span style="color:red"> x = 5</span></code>
</p>
<h4 id="semicolons">Semicolons</h4>
<p>
Do not terminate your lines with semicolons or use semicolons to
put more than one command on the same line. (Semicolons are not
necessary, and are omitted for consistency with other Google style
guides.)
</p>
<h3> Organization </h3>
<h4 id="generallayout">General Layout and Ordering</h4>
<p>
If everyone uses the same general ordering, we'll be able to
read and understand each other's scripts faster and more easily.
</p>
<ol>
<li>Copyright statement comment </li>
<li>Author comment</li>
<li>File description comment, including purpose of
program, inputs, and outputs</li>
<li><code>source()</code> and <code>library()</code> statements</li>
<li>Function definitions</li>
<li>Executed statements, if applicable (e.g.,
<code> print</code>, <code>plot</code>)</li>
</ol>
<p>
Unit tests should go in a separate file named
<code>originalfilename_test.R</code>.
</p>
<h4 id="comments">Commenting Guidelines</h4>
<p>
Comment your code. Entire commented lines should begin with
<code>#</code> and one space.
</p>
<p>
Short comments can be placed after code preceded by two spaces,
<code>#</code>, and then one space.
</p>
<pre># Easy string concatenation
'%+%' <- function(a, b) UseMethod('%+%') # Generic concat operator
'%+%.character' <- function(a, b) paste0(a, b) # String concat operator
</pre>
<h4 id="functiondefinition">Function Definitions and
Calls</h4>
<p>
Define all values a function requires for execution as its formal
arguments. Function definitions should first list arguments without
default values, followed by those with default values.
Arguments should be checked for validity at the top of the function body
with <code>stopifnot()</code> or <code>if () stop()</code>.
Avoid creating unnecessary objects and name bindings. If possible always
favor passing unnamed return values from one to another function. Excessive
aliasing lowers performance and readability.
In general errors should be raised as early as possible. Keep this in
mind when generating side effects (I/O, network requests).
Try 'housekeeping' only immutable variables (as far as it makes sense).
Avoid altering external state, i.e. don't modify objects that are out
of the scope of the current function; instead one should create a new
object with the specified features within a function and return that.
Functions should have explicit return values denoted by
<code>return(value)</code>. However, one-liner functions (anonymous and named)
with a single statement body should be returned implicit
(i.e. <code>function(a, b) paste0(a, b)</code>).
</p>
<p>
In both function definitions and function calls, multiple
arguments per line are allowed; line breaks are only allowed
between assignments. Default argument values can be expressions and statements.
</p>
<p>GOOD:
<pre>predictCTR <- function(query, property, num.days,
show.plot=T)
push <- function(code=NULL,
file=grepl('\\.r$', code, ignore.case=T),
mode=as.integer(file) + 1)
</pre>
BAD:
<pre><span style="color:red">predictCTR <- function(query, property, num.days, show.plot =
TRUE)
</span></pre>
<p>
Do not create an object if its existence is not absolutely necessary.
Having a multitude of name bindings within an environement or function
can decrease the readability of code drastically. As long as there is
clarity about a function's inputs and outputs embeeding a literal
function within code is more readable than creating a name binding
for its return value.
Ideally, unit tests should serve as sample function calls (for
shared library routines).
</p>
<h4 id="functiondocumentation">Function Documentation</h4>
<p> Functions should contain a comments section immediately below
the function definition line. These comments should consist of a
one-sentence description of the function; a list of the function's
arguments, each beginning with <code>@param {data type} name</code>
followed by a short description; and a description of the return
value, denoted by <code>@return {data type}</code> and a short description.
The comments should be descriptive enough that a caller can use the
function without reading any of the function's code.
</p>
<h4 id="examplefunction">Example Function</h4>
<pre>
calculateSampleCovariance <- function(x, y, verbose=T) {
# Computes the sample covariance between two vectors.
# @param {numeric} x Numeric vector
# @param {numeric} y Must have the same length as x (> 1)
# @param {bool} verbose If T, prints sample covariance
# @return {numeric} The sample covariance between x and y
n <- length(x)
# Error handling
if (n <= 1 || n != length(y)) {
stop('Arguments x and y have different lengths: ',
length(x), ' and ', length(y), '.')
}
if (anyNA(x) || anyNA(y)) {
stop(' Arguments x and y must not have missing values.')
}
covariance <- var(x, y)
if (verbose) {
cat('Covariance = ', round(covariance, 4), '.\n', sep = '')
}
return(covariance)
}
</pre>
<h4 id="todo">TODO Style</h4>
<p>
Use a consistent style for TODOs throughout your code.
<br /><code># TODO(username): Explicit description of action to
be taken</code>
</p>
<h3> Language </h3>
<h4 id="attach">Attach</h4>
<p> The possibilities for creating errors when using
<code>attach</code> are numerous. Avoid it.</p>
<h4 id="functionlanguage">Functions</h4>
<p> Make your code <a href="https://medium.com/@cscalfani/so-you-want-to-be-a-functional-programmer-part-1-1f15e387e536#.7z0ymzk9w">functional</a> in order to increase its readability,
modularity and performance.
Favor vectorized procedures over for loops. Errors should be raised
as early as possible using <code>stop()</code> or <code>stopifnot()</code>.
Avoid creating unnecessary objects and name bindings.</p>
<h4 id="object">Objects and Methods</h4>
<p> The S language has two object systems, S3 and S4, both of which
are available in R. S3 methods are more interactive and flexible,
whereas S4 methods are more formal and rigorous. (For an illustration
of the two systems, see Thomas Lumley's
"Programmer's Niche: A Simple
Class, in S3 and S4" in R News 4/1, 2004, pgs. 33 - 36:
<a href="https://cran.r-project.org/doc/Rnews/Rnews_2004-1.pdf">
https://cran.r-project.org/doc/Rnews/Rnews_2004-1.pdf</a>.)
</p>
<p>Use S3 objects and methods unless there is a strong reason to use
S4 objects or methods. A primary justification for an S4 object
would be to use objects directly in C++ code. A primary
justification for an S4 generic/method would be to dispatch on two
arguments.
</p>
<p>Avoid mixing S3 and S4: S4 methods ignore S3 inheritance and
vice-versa.
</p>
<h3>Exceptions</h3>
<p>
The coding conventions described above should be followed, unless
there is good reason to do otherwise. Exceptions include legacy
code and modifying third-party code.
</p>
<h3>Parting Words</h3>
<p>
Use common sense and BE CONSISTENT.
</p>
<p>
If you are editing code, take a few minutes to look at the code around
you and determine its style. If others use spaces around their
<code>if </code>
clauses, you should, too. If their comments have little boxes of stars
around them, make your comments have little boxes of stars around them,
too.
</p>
<p>
The point of having style guidelines is to have a common vocabulary of
coding so people can concentrate on <em>what</em> you are saying,
rather than on <em>how</em> you are saying it. We present global style
rules here so people
know the vocabulary. But local style is also important. If code you add
to a file looks drastically different from the existing code around it,
the discontinuity will throw readers out of their rhythm when they go to
read it. Try to avoid this.
</p>
<p>
OK, enough writing about writing code; the code itself is much more
interesting. Have fun!
</p>
</body>
</html>