ave
- очень полезная функция base R
, которая является быстрой и эффективной для создания новых столбцов на основе применения функции по группам (ниже приведен простой пример, который создает mean
по группам столбцов с использованием ave
, dplyr
и data.table
методы).
set.seed(24)
df1 <- data.frame(grp = sample(LETTERS, 1e6, replace = TRUE), val = rnorm(1e6))
system.time(with(df1, ave(val, grp)))
# user system elapsed
# 0.070 0.004 0.073
library(dplyr)
system.time(df1 %>%
group_by(grp) %>%
mutate(new = mean(val)))
# user system elapsed
# 0.159 0.000 0.160
library(data.table)
system.time(setDT(df1)[, new := mean(val), by = grp])
# user system elapsed
# 0.056 0.000 0.057
, в то время как tapply
дает суммарный результат. Одним из основных преимуществ ave
является то, что нам не нужно беспокоиться о порядке вывода, поскольку он всегда дает вывод в том же порядке строк. Это может измениться даже в некоторых tidyverse
функциях. Вопрос о том, всегда ли sort
ed unique
значения ave
всегда равен tapply
- это зависит. Для некоторых функций мы можем получить суммарный вывод list
в tapply
tapply(1:10, rep(LETTERS[1:3], c(3, 3, 4)), FUN = range)
, тогда как ave
терпит неудачу здесь, потому что это не будет соответствовать длине каждой группы
ave(1:10, rep(LETTERS[1:3], c(3, 3, 4)), FUN = range)
и выдает предупреждение