
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 = quote((.)),
env = parent.frame(2L),
abort_msg = gettextf("`%s` must be a 'data.frame'.", arg),
abort_msg2 = gettext("Implicit data-dot (.) not permitted"),
abort_msg3 = gettext("Data-dot mechanism activated, but no `.` object found."),
abort_msg4 =
gettext("{.code {deparse(call0)}} rewritten as:\n{.code {deparse(call)}}"),
abort_msg5 = gettextf("Define `.` before this call, or provide `%s =` explicitly.",
arg),
abort_msg6 = gettextf("See {.help svBase::data_dot_mechanism} for more infos."),
abort_frame = parent.frame()
)
recall_with_data_dot2(
call,
arg = "x",
arg2 = "y",
value = quote((.)),
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_msg3 = gettext("Data-dot mechanism activated, but no `.` object found."),
abort_msg4 =
gettext("{.code {deparse(call0)}} rewritten as:\n{.code {deparse(call)}}"),
abort_msg5 = gettextf("Define `.` before this call, or provide `%s =` explicitly.",
arg),
abort_msg6 = gettextf("See {.help svBase::data_dot_mechanism} for more infos."),
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).
An error message when . is not found.
Before and after data-dot replacement message.
An additional explanation when .is not found.
A hint to read the documentation of the data-dot mechanism.
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_data_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 xand y.
library(svBase)
# Use this (rename) function to get extra-info in the error message about the
# data-dot mechanism automatically
stop <- stop_
# Here is how you create a data-dot function
my_subset <- function(.data = (.), i, j) {
if (!prepare_data_dot(.data))
return(recall_with_data_dot())
if (!is.numeric(i))
stop("{.arg i} must be numeric") # Use this function
if (i == 1)
message(".env has ", paste(names(.env), collapse = ", "))
.data[i, j]
}
dtf1 <- data.frame(x = 1:3, y = 4:6)
# The message shows the objects available in the function environment
my_subset(dtf1, 1, 'y')
#> .env has .__top_call__., .env, ., .data, i, j
#> [1] 4
# This is wrong
try(my_subset(dtf1, 'y'))
#> Error in my_subset(dtf1, "y") : `i` must be numeric
.= dtf1
my_subset(2, 'y')
#> [1] 5
# Error message with indication that the data-dot mechanism is activated
try(my_subset('y'))
#> Error in my_subset(.data = (.), "y") : `i` must be numeric
#> ℹ The data-dot mechanism was activated (see `?svMisc::data_dot_mechanism()`).
#> • `.` is a data frame with 3 rows and 2 columns: 'x', 'y'
# Data-dot mechanism not activate, but dot object used
try(my_subset(., 'y'))
#> Error in my_subset(., "y") : `i` must be numeric
#> • `.` is a data frame with 3 rows and 2 columns: 'x', 'y'
# Wrong .data=
try(my_subset(.data = 'y'))
#> Error in my_subset(.data = "y") : `.data` must be a 'data.frame'.
# When data-dot is not permitted...
.SciViews.implicit.data.dot <- FALSE
try(my_subset(2, 'y'))
#> [1] 5
rm(.SciViews.implicit.data.dot)
# When `.` is not found...
rm(.)
try(my_subset(2, 'y'))
#> Error in my_subset(2, "y") :
#> Data-dot mechanism activated, but no `.` object found.
#> ✖ `my_subset(2, "y")` rewritten as: `my_subset(.data = (.), 2, "y")`
#> ℹ Define `.` before this call, or provide `.data =` explicitly.
#> ℹ See `?svBase::data_dot_mechanism()` for more infos.