Prepare a function that uses the data-dot mechanism. In case the
argument (usually, .data = (.)
) is missing or is not a data frame in a call
to a "data-dot" function, it is recalled after injection .
as first
argument.
prepare_data_dot(x, is_top_call = TRUE)
prepare_data_dot2(x, y, is_top_call = TRUE)
recall_with_data_dot(
call,
arg = ".data",
value = as.symbol("."),
env = parent.frame(2L),
abort_msg = gettextf("`%s` must be a 'data.frame'.", arg),
abort_msg2 = gettext("Implicit data-dot (.) not permitted"),
abort_frame = parent.frame()
)
recall_with_data_dot2(
call,
arg = "x",
arg2 = "y",
value = as.symbol("."),
env = parent.frame(2L),
abort_msg = gettextf("`%s` and `%s` must both be 'data.frame'.", arg, arg2),
abort_msg2 = gettext("Implicit data-dot (.) not permitted"),
abort_frame = parent.frame()
)
An argument to check.
A logical indicating if this is a top-level call (TRUE
by
default) that should be focused in the call stack in case of an error.
A second argument.
A call object, usually a function call. Could be omitted, and in
this case, sys.call()
is invoked.
The name of the argument to inject, usually '.data' (default). For
prepare_data_dot2()
, it is x
by default
The value to inject, usually the symbol .
(default).
The environment where the evaluation of the data-dot-injected call
should be evaluated (by default, parent.frame(2L)
, should rarely be
changed).
The message to use in case the '.data' argument is wrong.
An additional message to append to the error message in
case data-dot-injection is not permitted (when
.SciViews.implicit.data.dot != TRUE
, see example).
The environment to use for the error message, by default, the caller environment (should rarely be changed).
The name of the second argument, y
by default.
TRUE
if the preparation is correct for prepare_dzata_dot()
,
FALSE
otherwise. The result from evaluating the data-dot-injected call for
recall_with_data_dot()
.
The call is not checked if it is a correct function call. When called
from within a function, passing sys.call()
as call
, it should be always
correct.
prepare_data_dot2()
and recall_with_data_dot2()
are similar, but for
functions that have two first arguments that must be data frames, generally
called x
and y
.
# Here is how you create a data-dot function
my_subset <- function(.data = (.), i, j) {
# This makes it a data-dot function
if (!prepare_data_dot(.data))
return(recall_with_data_dot())
# Code of the function
# Second argument (i here) must not be a data.frame to avoid confusion
message(".env has ", paste(names(.env), collapse = ", "))
.data[i, j]
}
dtf1 <- data.frame(x = 1:3, y = 4:6)
my_subset(dtf1, 1, 'y')
#> .env has .__top_call__., .env, ., .data, i, j
#> [1] 4
# If .data is in '.', it can be omitted
.= dtf1
my_subset(1, 'y')
#> .env has .__top_call__., .env, ., .data, i, j
#> [1] 4
# This mechanism is potentially confusing. You can inactivate it anywhere:
.SciViews.implicit.data.dot <- FALSE
# This time next call is wrong
try(my_subset(1, 'y'))
#> .env has .__top_call__., .env, ., .data, i, j
#> [1] 4
# You must indicate '.' explicitly in that case:
my_subset(., 1, 'y')
#> .env has .__top_call__., .env, ., .data, i, j
#> [1] 4
rm(.SciViews.implicit.data.dot) # Reactivate it
my_subset(1, 'y') # Implicit again
#> .env has .__top_call__., .env, ., .data, i, j
#> [1] 4
# Note that, if you have not defined '.' and try to use it, you got
# an error:
rm(.)
try(my_subset(1, 'y'))
#> Error in eval(expr, envir) : object '.' not found