在data.table包中实现点函数`.()`

Moo*_*per 3 r function data.table

来自?data.table::data.table:

表达式'.()'是list()的简写别名; 他们俩都是一样的

但是这个功能无处可寻:

data.table:::.
Run Code Online (Sandbox Code Playgroud)

get中的错误(name,envir = asNamespace(pkg),inherits = FALSE):
object'.' 未找到

所以我想输入是以某种方式解析的,它是如何完成的?我想在我自己的包中使用相同的功能.

以下工作也不错:

test  <- function(x) {
  eval(substitute(
    eval.parent(substitute(x, list(.=list)))
    ))
}

foo <- "bar"
test(.(foo))
# [[1]]
# [1] "bar"
identical(test(.(foo)), list(foo))
# [1] TRUE
Run Code Online (Sandbox Code Playgroud)

但是在这个点函数中会有一些点变量,这会失败:

. <- "baz"
test(.(foo,.))
# [[1]]
# [1] "bar"
# 
# [[2]]
# function (...)  .Primitive("list")
Run Code Online (Sandbox Code Playgroud)

预期:

# [[1]]
# [1] "bar"
# 
# [[2]]
# [1] "baz"
Run Code Online (Sandbox Code Playgroud)

duc*_*ayr 7

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)) {
    # . 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
}
Run Code Online (Sandbox Code Playgroud)

发现于R/data.table.R(目前在第173行).这就是为什么你找不到data.table:::.任何地方,以及他们如何完成你在帖子中提到的解析.

然后[.data.table" <- function (x, i, j,......他们可以做这种事情

if (!missing(j)) {
    jsub = replace_dot_alias(substitute(j))
    root = if (is.call(jsub)) as.character(jsub[[1L]])[1L] else ""
Run Code Online (Sandbox Code Playgroud)

....