2017-07-22 42 views
1

我想知道在data.table包中實現的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開發出一種早?

+0

也許相關:https://stackoverflow.com/questions/41228076/using-data-tables-shortcut-in-quoted-expressions Data.table有一些優化,適用於表達式在'DT [...] 「你可能會失去這種方式,順便說一句。 – Frank

回答

1

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)) { 
     if (e[[1L]] == ".") e[[1L]] = quote(list) 
     for (i in seq_along(e)[-1]) 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))) 

修飾表達然後執行。該函數的一個缺點是,它目前不分析該點是否爲bquote表達式的一部分,該表達式將點用於不同的目的。

+0

謝謝!這正是我所尋找的。現在我在我的應用程序(這激發了我的問題)中使用基於'rlang'的方法,我在編輯中描述了我的問題。但是,我仍然不確定它是如何使'list'比別名更快(作爲原語)?你可能會詳細說明一下嗎? – sztal

+0

https://cran.r-project.org/doc/manuals/r-release/R-ints.html#g_t_002eInternal-vs-_002ePrimitive – Roland

相關問題