Ответ 1
Альтернативой flolel-ответу в комментариях может быть
e <- parse(text = paste0("sum(", v1, ", na.rm = TRUE)"))
b <- parse(text = v2)
rDT2 <- dt[, eval(e), by = eval(b)]
# b V1
# [1,] setosa 250.3
# [2,] versicolor 296.8
# [3,] virginica 329.4
EDIT:
И чтобы поместить это в функцию,
getResult <- function(dt, expr, gby){
return(dt[, eval(expr), by = eval(gby)])
}
(dtR <- getResult(dt = dt, expr = e, gby = b))
# gives the same result as above
ИЗМЕНИТЬ от Мэтью:
Там тонкая причина, по которой методы paste0
и eval
\quote
могут быть быстрее, чем get
в некоторых случаях. Одна из причин, почему группировка может быть быстрой, заключается в том, что data.table
проверяет j
, чтобы увидеть, какие столбцы он использует, а затем подмножает только те используемые столбцы (FAQ 1.12 и 3.1). Для этого используется base::all.vars(j)
. При использовании get()
в j
используемый столбец скрыт от all.vars
, а data.table
возвращается к подмножеству всех столбцов на всякий случай, если им требуется выражение j
(подобно тому, как символ .SD
используемый в j
, для которого был добавлен .SDcols
). Если все столбцы используются в любом случае, это не имеет никакого значения, но если DT
говорит 1e7x100, то сгруппированная j=sum(V1)
должна быть намного быстрее, чем сгруппированная j=sum(get("V1"))
по этой причине. По крайней мере, то, что должно произойти, и если это не так, это может быть ошибкой. Если, с другой стороны, многие запросы строятся динамически и повторяются, тогда время в paste0
и parse
может войти в него. На самом деле все зависит. Настройка verbose=TRUE
должна распечатывать сообщение о том, какие столбцы были обнаружены, как используется j
, чтобы это можно было проверить.