我想知道 .
的点别名 ( list
) 怎么样? data.table
中实现的构造函数包裹。需要说明的是,我正在考虑此功能:
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
我试图在 github 上的源代码中找到它,但它太密集了,我无法在任何合理的时间内理解它。
编辑。
我知道这可以通过定义一个别名来轻松完成:. <- list
或 . <- function(...) list(...)
.但是,这并不是我想要的。我想定义这样一个别名,因此它只适用于给定函数/方法的上下文。
例子。
L <- .(1) # This throws error
L <- func(.(1)) # This works
实际上我可以使用 rlang
得到我想要的东西整齐评估的工具。下面是一个简单的例子。
library(rlang)
func <- function(...) {
. <- list
eval_tidy(enexpr(x))
}
x1 <- func(.(1))
x2 <- list(1)
identical(x1, x2) # TRUE
所以我想知道这种功能是如何在 data.table
中实现的具体来说,因为它的开发方式早于 rlang
?
最佳答案
data.table 在计算表达式之前替换表达式中的点。它在语言上使用计算。
相关函数是replace_dot_alias
(注意复用这个函数意味着你需要遵守data.table的许可):
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
}
用法示例:
expr <- quote(.(a = b, c = .(sum(d))))
replace_dot_alias(expr)
#list(a = b, c = list(sum(d)))
然后执行修改后的表达式。
关于r - 如何在 data.table 包中实现列表构造函数的点 (.) 别名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45254085/