2013-04-09 19 views
17

Czego mi tu brakuje?eval i wycena w data.table

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? Używam R 2.15.0 i data.table 1.8.9.

+0

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

Odpowiedz

20

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))] 
+0

ok, jak mogę to naprawić? Chciałbym przekazać nazwę "data.table" i nazwę zmiennej do funkcji, która mogłaby obliczyć np. "suma". Używałem powyższego kodu przed (i mógłbym przysiąc, że kiedyś działało z poprzednią wersją 'R' lub' data.table'), ale to chyba nie wchodzi w grę ...? – eddi

+1

Co powiedzieliśmy na 'quoted_a <- quote (sum (a))' jak pokazano w [** faq 1.6 **] (http://datatable.r-forge.r-project.org/datatable-faq.pdf) ? – Arun

+0

który nie zadziała dla mnie, ktokolwiek wywołuje funkcję nie wie, jakie oceny będą się tam dziać – eddi