rlang (version 0.2.2)

as_data_mask: Create a data mask

Description

A data mask is an environment (or possibly multiple environments forming an ancestry) containing user-supplied objects. Objects in the mask have precedence over objects in the environment (i.e. they mask those objects). Many R functions evaluate quoted expressions in a data mask so these expressions can refer to objects within the user data.

These functions let you construct a tidy eval data mask manually. They are meant for developers of tidy eval interfaces rather than for end users. Most of the time you can just call eval_tidy() with user data and the data mask will be constructed automatically. There are three main use cases for manual creation of data masks:

  • When eval_tidy() is called with the same data in a tight loop. Tidy eval data masks are a bit expensive to build so it is best to construct it once and reuse it the other times for optimal performance.

  • When several expressions should be evaluated in the same environment because a quoted expression might create new objects that can be referred in other quoted expressions evaluated at a later time.

  • When your data mask requires special features. For instance the data frame columns in dplyr data masks are implemented with active bindings.

Usage

as_data_mask(data, parent = base_env())

as_data_pronoun(data)

new_data_mask(bottom, top = bottom, parent = base_env())

Arguments

data

A data frame or named vector of masking data.

parent

The parent environment of the data mask.

bottom

The environment containing masking objects if the data mask is one environment deep. The bottom environment if the data mask comprises multiple environment.

top

The last environment of the data mask. If the data mask is only one environment deep, top should be the same as bottom.

Value

A data mask that you can supply to eval_tidy().

Building your own data mask

Creating a data mask for base::eval() is a simple matter of creating an environment containing masking objects that has the user context as parent. eval() automates this task when you supply data as second argument. However a tidy eval data mask also needs to enable support of quosures and data pronouns. These functions allow manual construction of tidy eval data masks:

  • as_data_mask() transforms a data frame, named vector or environment to a data mask. If an environment, its ancestry is ignored. It automatically installs a data pronoun.

  • new_data_mask() is a bare bones data mask constructor for environments. You can supply a bottom and a top environment in case your data mask comprises multiple environments.

    Unlike as_data_mask() it does not install the .data pronoun so you need to provide one yourself. You can provide a pronoun constructed with as_data_pronoun() or your own pronoun class.

  • as_data_pronoun() constructs a tidy eval data pronoun that gives more useful error messages than regular data frames or lists, i.e. when an object does not exist or if an user tries to overwrite an object.

To use a a data mask, just supply it to eval_tidy() as data argument. You can repeat this as many times as needed. Note that any objects created there (perhaps because of a call to <-) will persist in subsequent evaluations:

Life cycle

All these functions are now stable.

In early versions of rlang data masks were called overscopes. We think data mask is a more natural name in R. It makes reference to masking in the search path which occurs through the same mechanism (in technical terms, lexical scoping with hierarchically nested environments). We say that that objects from user data mask objects in the current environment.

Following this change in terminology, as_data_mask() and new_overscope() were soft-deprecated in rlang 0.2.0 in favour of as_data_mask() and new_data_mask().

Examples

Run this code
# NOT RUN {
# Evaluating in a tidy evaluation environment enables all tidy
# features:
mask <- as_data_mask(mtcars)
eval_tidy(quo(letters), mask)

# You can install new pronouns in the mask:
mask$.pronoun <- as_data_pronoun(list(foo = "bar", baz = "bam"))
eval_tidy(quo(.pronoun$foo), mask)

# In some cases the data mask can leak to the user, for example if
# a function or formula is created in the data mask environment:
cyl <- "user variable from the context"
fn <- eval_tidy(quote(function() cyl), mask)
fn()

# If new objects are created in the mask, they persist in the
# subsequent calls:
eval_tidy(quote(new <- cyl + am), mask)
eval_tidy(quote(new * 2), mask)
# }

Run the code above in your browser using DataCamp Workspace