Update (eddi) Na version 1.8.11 zostało ustalone i .SD
nie jest potrzebne w przypadku, gdy ekspresja może być oceniana w miejscu, jak w PO. Ponieważ obecnie obecność .SD
wyzwala konstrukcję pełnego .SD
, w niektórych przypadkach spowoduje to znacznie większą szybkość.
Co się dzieje jest to, że rozmowy do eval()
są traktowane inaczej niż prawdopodobne wyobrazić w kodzie, który implementuje [.data.table()
. W szczególności, [.data.table()
zawiera specjalne gałęzie oceny dla wyrażeń i
i j
, które rozpoczynają się od symbolu eval
. Po zawinięciu wywołania do eval
w trakcie wywołania do sum()
, eval
nie jest już pierwszym elementem analizowanego/podstawionego wyrażenia, a specjalna gałąź oceny jest pomijana.
Oto fragment kodu w funkcji wyświetlane potwora wpisując getAnywhere("[.data.table")
sprawia, że specjalny zasiłek dla połączeń do eval()
przekazywanych przez [.data.table()
w „s j
-argument:
jsub = substitute(j)
...
# Skipping some lines
...
jsubl = as.list.default(jsub)
if (identical(jsubl[[1L]], quote(eval))) { # The test for eval 'on the outside'
jsub = eval(jsubl[[2L]], parent.frame(), parent.frame())
if (is.expression(jsub))
jsub = jsub[[1L]]
}
jako obejście, albo śledzić przykład w data.table FAQ 1.6 (pdf here) lub jawnie wskaż eval()
w kierunku .SD
, lokalnej zmiennej, która przechowuje kolumny niezależnie od danych, na których pracujesz (tutaj d
). (Aby uzyskać więcej informacji na temat roli .SD
, zobacz kilka pierwszych akapitów: this answer).
d[, sum(eval(quoted_a, envir=.SD))]
Dziś miałem taki problem; został rozwiązany za pomocą 'quote (sum (a))' zamiast 'expression (sum (a))'. Nie mam pojęcia, dlaczego to miało znaczenie. – rbatt