R Code Style Guide
Source:.github/STYLE_GUIDE.md
This style guide emphasis writing R code that other programmers can edit.
General
- When coding, emphasize accessibility for readers over brevity, trendiness, and speed. Given our work environment, even if you are working alone on a project, someone else should be able to take over your code. You may be surprised how often you return to your own code to discover you feel like a different person than the person who wrote it.
- Inline comments should, at a minimum give a general outline of what is going on.
- Any tricky / potentially confusing code should have comments explaining what is going on.
- If you do optimize something and make it more difficult to read, it can help to keep the original code and indicate that it achieves the same goal.
- For functions you expect others to use (exported functions in a package) write complete documentation, including:
- At least one working example of every function (excepting trivial functions such as print functions).
- The coverage of examples included should reviewed by another programmer who did not program the function. This provides independent validation.
- A complete “returns” section in the R documentation that specifies the class and meaning of the returned object.
- When that object has a data.frame or matrix, the column names and meanings are described.
- When that object has a list, each element of that list is described with details similar to if it was the only thing being returned.
- When the function returns nothing (e.g. a print function) this section can be omitted.
- At least one working example of every function (excepting trivial functions such as print functions).
The five types of functions their placement in code
- Main exported functions. These are the functions that people use the package to get access to (e.g.
lm.sdf
). Put these in a .R file named [functionname].R - Helper exported functions. These are functions that make the main functions work (e.g.
print.lm.sdf
). These are placed in [functionname]Helpers.R or [functionname].R at the programmers discretion. - Non-exported exclusive “subroutines.” These are code chunks that you remove from code because you either repeat a task or want to isolate some code for another reason. These get used in calls from exactly one function. Place these in [functionname.R]
- Functions similar to those in 2 except that the functions are used by multiple functions. These are treated similar to main functions. functions of this type should include documentation.
- R S3/S4 OO calls, e.g. calls to setMethod. These are either placed in functionname.R or all.R or zzz.R when required to do so by CRAN/the compiler or when it is not clear which file they should go in.
Variables
- All function names and arguments are in camel case (
likeThis
)- However function names use dots when required to do so by the R specification (e.g.
print.objectName
)
- However function names use dots when required to do so by the R specification (e.g.
- Inside functions, shorter variable names can be used but the logic should be explained when not immediately apparent (e.g. #
od
is short for “original data”)
Type setting
- Indenting is accomplished with two spaces
- Opening a function call or conditional leads to an increase of one level indenting
- If/else statements always use curly braces, e.g., {}, and appear on multiple lines
- Open curly braces appear on the same line as the function / conditional that they open and are closed on their own line e.g.
if(foo) {
[code]
} else {
[more code]
}
Details
- Use
TRUE/FALSE
in preference toT/F
becauseT
andF
can be redefined and yield surprising results. - Avoid using other packages when a minor bit of functionality is required. This decreases issues due to others functions having surprising changes in their API that cause our package to malfunction.
- All long conditionals should indicate, when closed, what statement is being closed e.g.
if(bar) {
[a bunch of code]
} else { # end if(bar)
[more code]
} # end else if(bar)