๐ŸŽ“ A1Learner
๐Ÿ”
0 of 27 lessons completed

R Eval and Non-Standard Evaluation

eval() runs code that was held as data. A helper can run a caller's expression inside a data frame, so the caller writes the test in bare column names.

Run held code with eval

eval() runs the quoted addition at once and gives 5. The second call runs the multiplication with values taken from the list.

print(eval(quote(2 + 3)))
print(eval(quote(x * y), list(x = 3, y = 4)))

Values come from a list

The list vals holds a and b. Each eval() call finds the names in the list and runs its expression there.

vals <- list(a = 10, b = 4)
print(eval(quote(a - b), vals))
print(eval(quote(a * b), vals))
print(eval(quote(a + b), vals))

Filter a frame with a bare test

keep_rows() captures the test with substitute() and runs it inside the frame with eval(). The caller writes score > 80 with no frame prefix, and rows 1 and 3 pass.

df <- data.frame(name = c("Ana", "Bo", "Cy"), score = c(92, 70, 85))
keep_rows <- function(data, expr) {
  keep <- eval(substitute(expr), data)
  return(data[keep, ])
}
print(keep_rows(df, score > 80))

A missing name stops eval

The list holds total but the expression names z. eval() cannot find z in the list, so the call stops with an error.

vals <- list(total = 10)
print(eval(quote(z + total), vals))

Example

df <- data.frame(name = c("Ana", "Bo", "Cy", "Dee"), score = c(92, 70, 85, 64))
read_col <- function(data, col) {
  return(eval(substitute(col), data))
}
keep_rows <- function(data, expr) {
  keep <- eval(substitute(expr), data)
  return(data[keep, ])
}
print(read_col(df, score))
print(keep_rows(df, score > 80))

Key points

  • eval() runs an expression that was held as data.
  • A list or data frame passed to eval() gives the names in the expression their values.
  • The pattern eval(substitute(expr), data) runs the caller's expression inside the data.
  • A caller using that pattern writes column names bare, with no frame prefix.
  • An expression that names a value the list does not hold stops with a not found error.
  • This style of running a caller's expression against supplied values is called non-standard evaluation.

In this example, read_col() returns the score column by running the captured name inside the frame. keep_rows() then keeps the two rows where the score passes 80.

Try it Yourself

Edit the code, then press Run.

Running is simulated ยท rdrr.io R Snippets

Exercise

What does eval(quote(x * y), list(x = 3, y = 4)) print?