ewaluacja i wycena w danych.tabela
Co mi umyka?
d = data.table(a = 1:5)
d[, a] # 1 2 3 4 5
d[, sum(a)] # 15
d[, eval(quote(a))] # 1 2 3 4 5
d[, sum(eval(quote(a)))] # 15
quoted_a = quote(a)
d[, eval(quoted_a)] # 1 2 3 4 5
d[, sum(eval(quoted_a))] # Error in eval(expr, envir, enclos) : object 'a' not found
Co się dzieje? Biegam R 2.15.0
i data.table 1.8.9
. 1 answers
UPDATE (eddi): od Wersja 1.8.11 to zostało naprawione i {[2] } nie jest potrzebne w przypadkach, w których wyrażenie może być obliczone w miejscu, jak w OP. ponieważ obecnie OBECNOŚĆ .SD
wyzwala budowę pełnego .SD
, spowoduje to znacznie szybsze prędkości w niektórych przypadkach.
Chodzi o to, że wywołania do eval()
są traktowane inaczej niż można sobie wyobrazić w kodzie implementującym [.data.table()
. W szczególności [.data.table()
zawiera specjalną ocenę gałęzie dla i
i j
wyrażeń zaczynających się od symbolu eval
. Kiedy zawijasz połączenie do eval
wewnątrz połączenia do sum()
, eval
nie jest już pierwszym elementem parsowanego / podstawionego wyrażenia, a specjalna gałąź oceny jest pomijana.
Oto bit kodu w funkcji potwora wyświetlany przez wpisanie getAnywhere("[.data.table")
, który zapewnia specjalne ograniczenie dla wywołań do eval()
przekazywanych przez [.data.table()
' 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 podążaj za przykładem w danych.table FAQ 1.6 (PDF here ), lub wprost skierować eval()
w stronę .SD
, zmiennej lokalnej, która przechowuje kolumny dowolnych danych.tabela, na której operujesz (tutaj d
). (Aby dowiedzieć się więcej o roli .SD
, Zobacz kilka pierwszych akapitów tej odpowiedzi).
d[, sum(eval(quoted_a, envir=.SD))]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:17:46