Một thay thế cho flodel của câu trả lời trong các ý kiến có thể là
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:
Và để đưa điều này vào một chức năng,
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 từ Matthew : Có một lý do tại sao các phương pháp paste0
và eval
\ quote
cũng có thể nhanh hơn get
trong một số trường hợp. Một trong những lý do nhóm có thể nhanh chóng là data.table
kiểm tra j
để xem cột nào sử dụng, sau đó chỉ đặt các cột được sử dụng (Câu hỏi thường gặp 1.12 và 3.1). Nó sử dụng base::all.vars(j)
để làm điều đó. Khi sử dụng get()
trong j
cột đang được sử dụng là ẩn từ all.vars
và data.table
rơi trở lại Subsetting tất cả các cột chỉ trong trường hợp biểu thức j
cần họ (giống như khi biểu tượng .SD
được sử dụng trong j
, mà .SDcols
đã được bổ sung để giải quyết) . Nếu tất cả các cột được sử dụng dù sao thì nó không tạo sự khác biệt, nhưng nếu DT
là 1e7x100 thì một nhóm j=sum(V1)
phải nhanh hơn nhiều so với nhóm j=sum(get("V1"))
vì lý do đó. Ít nhất, đó là những gì đáng lẽ phải xảy ra, và nếu không thì đó có thể là một lỗi. Mặt khác, nếu nhiều truy vấn đang được xây dựng động và lặp lại thì thời gian tới paste0
và parse
có thể xuất hiện trong đó. Tất cả phụ thuộc thực sự. Thiết lập verbose=TRUE
sẽ in ra một thông báo về các cột đã được phát hiện như được sử dụng bởi j
, do đó có thể được kiểm tra.
Điều này có thể giúp bạn đi đúng hướng: 'dt [, tổng (get (v1), na.rm = TRUE), theo = v2]' hoặc đề xuất phương pháp thay thế nếu bạn linh hoạt. – flodel
Thx. Nó hoạt động, chuyện gì đã xảy ra? Hàm nhận đối tượng có tên v1. Chức năng thay thế đã làm gì với biểu thức này? Nó không làm bất cứ điều gì và cố gắng thay thế v1 với giá trị ký tự "Sepal.Length"? – user1157129