Skip to content
AgileLogics
5 min read

Scope and Anonymous Functions

Prerequisites: Functions

Scope

Scope is where a name can be seen. Variables created inside a function are local: they exist only while the function runs.

tax_rate <- 0.2

total <- function(price) {
  tax <- price * tax_rate   # can read tax_rate from outside
  price + tax
}

total(100)
exists("tax")
[1] 120
[1] FALSE
  • A function can read variables defined outside it (tax_rate).
  • tax was created inside the function and is gone afterwards.
  • Assigning inside a function creates a local variable — it never changes the outside variable of the same name:
count <- 0
increment <- function() {
  count <- count + 1
  count
}

increment()
count
[1] 1
[1] 0

Functions that depend only on their arguments, and return a result instead of changing outside variables, are much easier to test and reuse. Pass values in; return values out.

Anonymous functions

A function without a name is useful when you only need it once. R 4.1 added a short form, \(x), meaning function(x):

square <- \(x) x^2
square(4)

sapply(1:5, \(n) n * 10)
[1] 16
[1] 10 20 30 40 50

sapply() applies a function to every element — the apply family is covered properly in Level 2.

The native pipe: |>

The pipe passes the value on its left as the first argument of the function on its right, so code reads left to right, step by step:

c(1.234, 5.678, 9.1011) |> mean() |> round(2)
[1] 5.34

That's the same as round(mean(c(1.234, 5.678, 9.1011)), 2), but reads in the order the steps happen. You'll use the pipe constantly with the tidyverse. (Older code uses %>% from the magrittr package, which works similarly.)