Coding Practices

Published

September 16, 2025

CautionUnder construction

Coding

Create and share beautiful images of your source code.

https://carbon.now.sh

R

Coding: language agnostic

Function naming

Strive to use verbs for function names: to, add, remove, do, get, make, take, find, use, call, try, have, has, give, ask, go, put, let, help, move, turn, run, hold, write, read, include, set, change, watch, stop, start, create, open, close, save, build, wait, require, kill, pull, push, pass, stay, etc…

Use (lower) camelCase for self-defined functions that are not to be exported outside your project.

Class names, on the other hand, should use Pascal Casing.

This is to make a clear distinction between self-defined and imported functions.

# Class

Parameter <- R6Class("Parameter", ....)

# Variable

parameterToDelete <- ...

# Method and function

performSimulation <- function (...)
NoteDon’t hesitate to choose lengthy names for test functions.

Unlike regular functions, long names are less problematic for test functions because

  • They are not visible or accessible to the users
  • They are not called repeatedly throughout the codebase

Variable naming

Variable names should be nouns.

True constant variables should use ALL_CAPS Casing.

# Constant variables

DEFAULT_PERCENTILE <- 0.5

Names for Boolean variables or functions should make clear what true and false mean. This can be done using prefixes (is, has, can, etc.)

# not great
if (child) {
  if (parentSupervision) {
    watchHorrorMovie <- TRUE
  }
}

# better
if (isChild) {
  if (hasParentSupervision) {
    canWatchHorrorMovie <- TRUE
  }
}

Use positive terms for Booleans since they are easier to process.

# double negation - difficult
is_firewall_disabled <- FALSE

# better
is_firewall_enabled <- TRUE

Naming

https://indrajeetpatil.github.io/second-hardest-cs-thing/

https://style.tidyverse.org/syntax.html#sec-objectnames

The quality of a name can be assessed by how detailed the accompanying comment needs to be.

Good names:

  • Precise
  • Concise
  • Meaningful
  • Consistent
  • Difficult to misinterpret
  • Distinguishable
  • Searchable (i.e., updateable)
  • Pronounceable
  • Honor conventions (e.g. n for count)

Variable/object names should be nouns and function names should be verbs.

NoteMy own opinionated naming standards
  • Use snake_case for variable/object and (package)function names.
  • For custom non-exported functions (e.g., in an analysis script), use camelCase.
  • Use SCREAMING_SNAKE for constant variables (PI = 3.14)
# bad
t

# Not ideal - too imprecise
time

# Okay - can use more precision
days

# Good - middle ground
days_since_last_dose

# Not ideal - unnecessarily precise
days_since_last_dose_floor_4_lab_23
Note

Don’t hesitate to choose lengthy names for test functions.

Unlike regular functions, long names are less problematic for test functions because

  • They are not visible or accessible to the users
  • They are not called repeatedly throughout the codebase

If you find yourself attempting to cram data into variable names (e.g., model_2018, model_2019, model_2020), consider using a list or data frame instead.

Using generic names can improve code readability, but only if language or domain-specific conventions are followed. However, even when you think you need generic names, you are better off using descriptive names.

  • In type names, avoid using class, data, object, and type (e.g., bad: classShape, good: Shape)
  • But essential details should be kept (e.g., okay: child_height, better: child_height_cm)
Booleans or indicators

Boolean variable names should convey what true or false values represent. Generally, use positive terms for Booleans, as they are easier to process. But if the variable is only ever used in its false version (e.g., is_volcano_inactive), the negative version can be easier to work with.

Functions

Strive to use verbs for function names. Avoid using be, do, perform, etc. (e.g. bad: doAddition(), good: add())

Style

tidyverse style guide

NONMEM

  • Always MU-reference, in case EM-methods are needed.
    • Test all estimation methods.

Naming

Use descriptive variable names in snake_case or SCREAMING_SNAKE_CASE, not generic ones. Try to make them as concise as possible.

P = THETA(1) ; Don't do this
probability_no_event = THETA(1) ; Better
prob_no_event = THETA(1) ; Best

Style

Prefer to spell out the control record in full, i.e., no abbreviations.

$COVARIANCE ; Like this
$COV ; Not like this

Always use a newline before a control record.

Always use a newline after the following control records: $PRED, $PK, $DES, $ERROR.

$PK

A = 1

$ERROR

Y = DV

Control records that can be written on a single line, or only consist of options (e.g., $ESTIMATION), do not need a newline after the control record.

$PROBLEM dummy

$INPUT ID TIME DV EVID

$PK

A = 1

$ERROR

Y = DV

$ESTIMATION METHOD=1

$COVARIANCE MATRIX=R

Separate all infix operators by spaces, except exponentials.

A = 1 + 4 - 3 * 5 / 8**3

Adding extra spaces is ok if it improves the alignment of =.

Do not put spaces inside or outside parentheses for regular function calls.

; Good
LOG(A)

; Bad
LOG (A)
LOG( A )

Place a space before and after () when used with IF.

; Good
IF (A > B) THEN
  1+1
ENDIF

; Bad
IF(A > B) THEN
  1+1
ENDIF

References