Я пытаюсь написать некоторые функции-оболочки, чтобы уменьшить дублирование кода с помощью data.table
.
Вот пример использования mtcars
. Во-первых, настройте некоторые данные:
library(data.table)
data(mtcars)
mtcars$car <- factor(gsub("(.*?) .*", "\\1", rownames(mtcars)), ordered=TRUE)
mtcars <- data.table(mtcars)
Теперь, вот что я обычно пишу, чтобы получить сводку подсчетов по группам. В этом случае я группирую по car
:
mtcars[, list(Total=length(mpg)), by="car"][order(car)]
car Total
AMC 1
Cadillac 1
Camaro 1
...
Toyota 2
Valiant 1
Volvo 1
Сложность заключается в том, что, поскольку аргументы i
и j
оцениваются в рамках data.table
, нужно использовать eval(...)
, если вы хотите передать переменные:
Это работает:
group <- "car"
mtcars[, list(Total=length(mpg)), by=eval(group)]
Но теперь я хочу упорядочить результаты по одна и та же переменная группировки. Я не могу получить какой-либо вариант следующего, чтобы дать мне правильные результаты. Обратите внимание, что я всегда получаю одну строку результатов, а не упорядоченный набор.
mtcars[, list(Total=length(mpg)), by=eval(group)][order(group)]
car Total
Mazda 2
Я знаю почему: потому что group
оценивается в parent.frame
, а не во фрейме data.table
.
Как я могу оценить group
в контексте data.table
?
В более общем смысле, как я могу использовать это внутри функции? Мне нужна следующая функция, чтобы получить все результаты, а не только первую строку данных:
tableOrder <- function(x, group){
x[, list(Total=length(mpg)), by=eval(group)][order(group)]
}
tableOrder(mtcars, "car")