eval y cita en data.table

¿Que me estoy perdiendo aqui?

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 

Que esta pasando? Estoy ejecutando R 2.15.0 y data.table 1.8.9 .

ACTUALIZACIÓN (eddi): a partir de la versión 1.8.11, esto se ha corregido y .SD no es necesario en los casos en que la expresión se puede evaluar en su lugar, como en OP. Dado que la presencia actual de .SD desencadena la construcción de .SD completo, esto dará lugar a velocidades mucho más rápidas en algunos casos.


Lo que sucede es que las llamadas a eval() se tratan de forma diferente a lo que probablemente se imagina en el código que implementa [.data.table() . Específicamente, [.data.table() contiene twigs de evaluación especiales para las expresiones i y j que comienzan con el símbolo eval . Cuando ajusta la llamada a eval dentro de una llamada a sum() , eval ya no es el primer elemento de la expresión analizada / sustituida, y se omite la twig de evaluación especial.

Aquí está el bit de código en la función de monstruo que se muestra al escribir getAnywhere("[.data.table") que hace una concesión especial para las llamadas a eval() pasado a través de [.data.table() ‘s-argumento:

 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]] } 

Como solución temporal, siga el ejemplo en data.table FAQ 1.6 ( pdf aquí ), o explícitamente apunte eval() hacia .SD , la variable local que contiene columnas de cualquier data.table en la que esté operando (aquí d ). (Para obtener más información sobre el .SD de .SD , consulte los primeros párrafos de esta respuesta ).

 d[, sum(eval(quoted_a, envir=.SD))]