Skip to content

The .data and .env pronouns make it explicit where to find objects when programming with data-masked functions.

m <- 10
mtcars %>% mutate(disp = .data$disp * .env$m)

  • .data retrieves data-variables from the data frame.

  • .env retrieves env-variables from the environment.

Because the lookup is explicit, there is no ambiguity between both kinds of variables. Compare:

disp <- 10
mtcars %>% mutate(disp = .data$disp * .env$disp)
mtcars %>% mutate(disp = disp * disp)

Note that .data is only a pronoun, it is not a real data frame. This means that you can't take its names or map a function over the contents of .data. Similarly, .env is not an actual R environment. For instance, it doesn't have a parent and the subsetting operators behave differently.

.data versus the magrittr pronoun .

In a magrittr pipeline, .data is not necessarily interchangeable with the magrittr pronoun .. With grouped data frames in particular, .data represents the current group slice whereas the pronoun . represents the whole data frame. Always prefer using .data in data-masked context.

Where does .data live?

The .data pronoun is automatically created for you by data-masking functions using the tidy eval framework. You don't need to import or use library(rlang) to work with this pronoun.

However, the .data object exported from rlang is useful to import in your package namespace to avoid a R CMD check note when referring to objects from the data mask. R does not have any way of knowing about the presence or absence of .data in a particular scope so you need to import it explicitly or equivalently declare it with utils::globalVariables(".data").

Note that is a "fake" pronoun. Do not refer to with the rlang:: qualifier in data masking code. Use the unqualified .data symbol that is automatically put in scope by data-masking functions.