Una alternativa a flodel de respuesta en los comentarios podría ser
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:
Y para poner esto en una función,
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
EDITAR de Mateo : Hay una razón sutil por la que los métodos paste0
y eval
\ quote
pueden ser más rápidos que get
en algunos casos, también. Una de las razones por las que la agrupación puede ser rápida es que data.table
inspeccione j
para ver qué columnas utiliza, y luego solo subconjuntos de esas columnas usadas (preguntas más frecuentes 1.12 y 3.1). Utiliza base::all.vars(j)
para hacer eso. Al utilizar get()
en j
la columna que se utiliza está oculto a all.vars
y data.table
cae de nuevo a subconjuntos de todas las columnas en caso de que la expresión j
los necesita (al igual que cuando el símbolo .SD
se utiliza en j
, para lo cual se añadió .SDcols
de resolver) . Si todas las columnas se utilizan de todos modos, entonces no hace la diferencia, pero si DT
es decir 1e7x100, entonces un j=sum(V1)
agrupado debería ser mucho más rápido que un j=sum(get("V1"))
agrupado por ese motivo. Al menos, eso es lo que se supone que debe suceder, y si no es así, puede ser un error. Si, por otro lado, muchas consultas se construyen dinámicamente y se repiten, puede que llegue el tiempo a paste0
y parse
. Todo depende realmente. La configuración verbose=TRUE
debe imprimir un mensaje sobre qué columnas se han detectado como utilizadas por j
, de modo que se puedan verificar.
Esto puede ponerlo en el camino correcto: 'dt [, sum (get (v1), na.rm = TRUE), by = v2]' o sugerir un enfoque alternativo si es flexible. – flodel
Thx. Funcionó, ¿qué pasó? La función obtiene el objeto llamado v1. ¿Qué le hizo la función sustituta a esta expresión? ¿No hizo nada e intentó reemplazar v1 con el valor de carácter "Sepal.Length"? – user1157129