Reputation: 298
I wonder how is is the dot alias (.
) for the list
constructor function implemented in the data.table
package. Just to be clear I am thinking about this functionality:
library(data.table)
D = data.table(iris)
x1 = D[, .(Sepal.Length, Sepal.Width)] # dot alias
x2 = D[, list(Sepal.Length, Sepal.Width)] # standard name
identical(x1, x2) # TRUE
I tried to find it in the source code on github, but it is too dense for me to understand it in any reasonable amount of time.
EDIT.
I know this can be easily done by defining an alias like: . <- list
or . <- function(...) list(...)
. However, this is not exactly what I am looking for. I want to define such an alias, so it only works in the context of a given function/method.
Example.
L <- .(1) # This throws error
L <- func(.(1)) # This works
Actually I can get what I want using the rlang
tools for tidy evaluation. Below is a simple example.
library(rlang)
func <- function(...) {
. <- list
eval_tidy(enexpr(x))
}
x1 <- func(.(1))
x2 <- list(1)
identical(x1, x2) # TRUE
So I wonder how this kind of functionality is implemented in the data.table
specifically, since it was developed a way earlier than rlang
?
Upvotes: 3
Views: 271
Reputation: 132959
data.table replaces the dot in expressions before they are evaluated. It uses computing on the language.
The relevant function is replace_dot_alias
(note that reusing this function means that you need to conform to data.table's license):
replace_dot_alias = function(e) {
# we don't just simply alias .=list because i) list is a primitive (faster to iterate) and ii) we test for use
# of "list" in several places so it saves having to remember to write "." || "list" in those places
if (is.call(e) && !is.function(e[[1L]])) {
# . alias also used within bquote, #1912
if (e[[1L]] == 'bquote') return(e)
if (e[[1L]] == ".") e[[1L]] = quote(list)
for (i in seq_along(e)[-1L]) if (!is.null(e[[i]])) e[[i]] = replace_dot_alias(e[[i]])
}
e
}
An example of usage:
expr <- quote(.(a = b, c = .(sum(d))))
replace_dot_alias(expr)
#list(a = b, c = list(sum(d)))
The modified expression is then executed.
Upvotes: 4