Writing functions and pipelines

Session 7

2024-09-05

1 Functions

How to create a custom function in R

Why functions?

  1. Make your code easier to understand
  2. Update code in one place, instead of many
  3. Reduce chance of making copy and paste mistakes
  4. Reuse work from project-to-project

What is refactoring?

Refactoring is the process of making code:

  • easier to understand
  • cheaper to modify

…without changing behavior.

Types of functions

  1. Vector functions take one or more vectors as input and return a vector as output.
  2. Data frame functions take a data frame as input and return a data frame as output.
  3. Plot functions that take a data frame as input and return a plot as output.

Writing a function

  • Look for repeated sections of code.
  • What parts are constant?
  • What parts vary?

Writing a function

To turn code into a function you need three things:

  1. A name.
  2. The arguments.
  3. The body.

Writing a function

To turn code into a function you need three things:

name <- function(arguments) {
  body
}

Writing a function

Adapted from the tidyverse style guide:

  1. Naming functions
  2. Formatting functions
  3. Using return()
  4. Using comments

Naming functions

Strive to use verbs for function names:

# Good
add_row()
Error in add_row(): argument ".data" is missing, with no default
permute()
Error in permute(): could not find function "permute"
# Bad
row_adder()
Error in row_adder(): could not find function "row_adder"
permutation()
Error in permutation(): could not find function "permutation"

Using return()

Only use return() for early returns.

Use early returns to avoid else and “nested” logic.

# Good
is_it_wednesday <- function(x) {
  wday <- wday(x, label = TRUE)

  if (identical(wday, "Wed")) {
    return("Yes!")
  }

  "No..."
}

# Bad
is_it_wednesday <- function(x) {
  wday <- wday(x, label = TRUE)

  if (identical(wday, "Wed")) {
    return("Yes!")
  } else {
    return("No...")
  }
}

Using comments

Use comments to explain the “why” not the “what” or “how”.

Types of vector functions

  • “mutate” functions: functions that work well inside of mutate() and filter() because they return an output of the same length as the input.
  • summary functions: functions that return a single value for use in summarize().

Example of vector functions

If a function is type-stable it satisfies two conditions:

  • You can predict the output type based only on the input types (not their values).

  • If the function uses …, the order of arguments in does not affect the output type.

Designing a “tidy” function

Four guiding principles for the “tidyverse”:

  1. human centered
  2. consistent
  3. composable
  4. inclusive

2 Pipelines