alternatywą dla flodel za odpowiedź w komentarzach może być
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:
I umieścić to do funkcji,
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
EDIT od Mateusza : Istnieje subtelny powód, dla którego metody mogą być w niektórych przypadkach szybsze niż i eval
\ quote
. Jednym z powodów, dla których grupowanie może być szybkie, jest to, że data.table
sprawdza j
, aby zobaczyć, z których kolumn korzysta, a następnie rozdziela tylko te używane kolumny (FAQ 1.12 i 3.1). Do tego celu używa on base::all.vars(j)
. Podczas korzystania get()
w j
kolumna używana jest ukryte przed all.vars
i data.table
wraca do podzbioru wszystkie kolumny na wszelki wypadek wyrażenie j
potrzebuje ich (podobnie jak przy .SD
symbol jest używany w j
, dla których .SDcols
dodano do rozwiązania) . Jeśli mimo to wszystkie kolumny są używane, to nie robi to różnicy, ale jeśli DT
mówi 1e7x100, zgrupowane j=sum(V1)
powinny być znacznie szybsze niż zgrupowane j=sum(get("V1"))
z tego powodu. Przynajmniej tak powinno się stać, a jeśli nie, to może to być błąd. Jeśli z drugiej strony wiele zapytań jest konstruowanych dynamicznie i powtarzalnie, może przyjść do nich czas na paste0
i parse
. Wszystko zależy naprawdę. Ustawienie verbose=TRUE
powinno wydrukować komunikat o wykrytych kolumnach używanych przez j
, aby można było to sprawdzić.
To może postawić cię na właściwej drodze: 'dt [, sum (get (v1), na.rm = TRUE), by = v2]' lub zaproponuj alternatywne podejście, jeśli jesteś elastyczny. – flodel
Thx. Udało się, co się stało? Funkcja pobiera obiekt o nazwie v1. Co funkcja zastępcza zrobiła dla tego wyrażenia? Czy to nic nie dało i próbowało zastąpić v1 wartością znaku "Sepal.Length"? – user1157129