xref: /aosp_15_r20/external/google-styleguide/Rguide.md (revision 8c35d5ee8e2913d4bd6623e2b93232b1da0ab719)
1*8c35d5eeSXin Li# Google's R Style Guide
2*8c35d5eeSXin Li
3*8c35d5eeSXin LiR is a high-level programming language used primarily for statistical computing
4*8c35d5eeSXin Liand graphics. The goal of the R Programming Style Guide is to make our R code
5*8c35d5eeSXin Lieasier to read, share, and verify.
6*8c35d5eeSXin Li
7*8c35d5eeSXin LiThe Google R Style Guide is a fork of the
8*8c35d5eeSXin Li[Tidyverse Style Guide](https://style.tidyverse.org/) by Hadley Wickham
9*8c35d5eeSXin Li[license](https://creativecommons.org/licenses/by-sa/2.0/). Google modifications
10*8c35d5eeSXin Liwere developed in collaboration with the internal R user community. The rest of
11*8c35d5eeSXin Lithis document explains Google's primary differences with the Tidyverse guide,
12*8c35d5eeSXin Liand why these differences exist.
13*8c35d5eeSXin Li
14*8c35d5eeSXin Li## Syntax
15*8c35d5eeSXin Li
16*8c35d5eeSXin Li### Naming conventions
17*8c35d5eeSXin Li
18*8c35d5eeSXin LiGoogle prefers identifying functions with `BigCamelCase` to clearly distinguish
19*8c35d5eeSXin Lithem from other objects.
20*8c35d5eeSXin Li
21*8c35d5eeSXin Li```
22*8c35d5eeSXin Li# Good
23*8c35d5eeSXin LiDoNothing <- function() {
24*8c35d5eeSXin Li  return(invisible(NULL))
25*8c35d5eeSXin Li}
26*8c35d5eeSXin Li```
27*8c35d5eeSXin Li
28*8c35d5eeSXin LiThe names of private functions should begin with a dot. This helps communicate
29*8c35d5eeSXin Liboth the origin of the function and its intended use.
30*8c35d5eeSXin Li
31*8c35d5eeSXin Li```
32*8c35d5eeSXin Li# Good
33*8c35d5eeSXin Li.DoNothingPrivately <- function() {
34*8c35d5eeSXin Li  return(invisible(NULL))
35*8c35d5eeSXin Li}
36*8c35d5eeSXin Li```
37*8c35d5eeSXin Li
38*8c35d5eeSXin LiWe previously recommended naming objects with `dot.case`. We're moving away from
39*8c35d5eeSXin Lithat, as it creates confusion with S3 methods.
40*8c35d5eeSXin Li
41*8c35d5eeSXin Li### Don't use attach()
42*8c35d5eeSXin Li
43*8c35d5eeSXin LiThe possibilities for creating errors when using `attach()` are numerous.
44*8c35d5eeSXin Li
45*8c35d5eeSXin Li## Pipes
46*8c35d5eeSXin Li
47*8c35d5eeSXin Li### Right-hand assignment
48*8c35d5eeSXin Li
49*8c35d5eeSXin LiWe do not support using right-hand assignment.
50*8c35d5eeSXin Li
51*8c35d5eeSXin Li```
52*8c35d5eeSXin Li# Bad
53*8c35d5eeSXin Liiris %>%
54*8c35d5eeSXin Li  dplyr::summarize(max_petal = max(Petal.Width)) -> results
55*8c35d5eeSXin Li```
56*8c35d5eeSXin Li
57*8c35d5eeSXin LiThis convention differs substantially from practices in other languages and
58*8c35d5eeSXin Limakes it harder to see in code where an object is defined. E.g. searching for
59*8c35d5eeSXin Li`foo <-` is easier than searching for `foo <-` and `-> foo` (possibly split over
60*8c35d5eeSXin Lilines).
61*8c35d5eeSXin Li
62*8c35d5eeSXin Li### Use explicit returns
63*8c35d5eeSXin Li
64*8c35d5eeSXin LiDo not rely on R's implicit return feature. It is better to be clear about your
65*8c35d5eeSXin Liintent to `return()` an object.
66*8c35d5eeSXin Li
67*8c35d5eeSXin Li```
68*8c35d5eeSXin Li# Good
69*8c35d5eeSXin LiAddValues <- function(x, y) {
70*8c35d5eeSXin Li  return(x + y)
71*8c35d5eeSXin Li}
72*8c35d5eeSXin Li
73*8c35d5eeSXin Li# Bad
74*8c35d5eeSXin LiAddValues <- function(x, y) {
75*8c35d5eeSXin Li  x + y
76*8c35d5eeSXin Li}
77*8c35d5eeSXin Li```
78*8c35d5eeSXin Li
79*8c35d5eeSXin Li### Qualifying namespaces
80*8c35d5eeSXin Li
81*8c35d5eeSXin LiUsers should explicitly qualify namespaces for all external functions.
82*8c35d5eeSXin Li
83*8c35d5eeSXin Li```
84*8c35d5eeSXin Li# Good
85*8c35d5eeSXin Lipurrr::map()
86*8c35d5eeSXin Li```
87*8c35d5eeSXin Li
88*8c35d5eeSXin LiWe discourage using the `@import` Roxygen tag to bring in all functions into a
89*8c35d5eeSXin LiNAMESPACE. Google has a very big R codebase, and importing all functions creates
90*8c35d5eeSXin Litoo much risk for name collisions.
91*8c35d5eeSXin Li
92*8c35d5eeSXin LiWhile there is a small performance penalty for using `::`, it makes it easier to
93*8c35d5eeSXin Liunderstand dependencies in your code. There are some exceptions to this rule.
94*8c35d5eeSXin Li
95*8c35d5eeSXin Li*   Infix functions (`%name%`) always need to be imported.
96*8c35d5eeSXin Li*   Certain `rlang` pronouns, notably `.data`, need to be imported.
97*8c35d5eeSXin Li*   Functions from default R packages, including `datasets`, `utils`,
98*8c35d5eeSXin Li   `grDevices`, `graphics`, `stats` and `methods`. If needed, you can `@import`
99*8c35d5eeSXin Li   the full package.
100*8c35d5eeSXin Li
101*8c35d5eeSXin LiWhen importing functions, place the `@importFrom` tag in the Roxygen header
102*8c35d5eeSXin Liabove the function where the external dependency is used.
103*8c35d5eeSXin Li
104*8c35d5eeSXin Li## Documentation
105*8c35d5eeSXin Li
106*8c35d5eeSXin Li### Package-level documentation
107*8c35d5eeSXin Li
108*8c35d5eeSXin LiAll packages should have a package documentation file, in a
109*8c35d5eeSXin Li`packagename-package.R` file.
110