Вот более оригинальная версия вашего оригинала:
br <- function(){
andf = do.call(rbind,lapply(unique(df$group), function(g){
an = anova(lm(y~sex*time, data=df[df$group==g,]))
setNames(an[-nrow(an),"Pr(>F)"],rownames(an)[-nrow(an)])
}))
andf = data.frame(andf)
andf$group = unique(df$group)
andf
}
Я не уверен, почему вы использовали «which», чтобы выбрать столбец «Pr (> F)», потому что может быть только один,так подмножество это прямо.Также обратите внимание на базовое подмножество для групп и -nrow(an)
для удаления последних строк вещей.
Я также оставил как можно больше вне цикла, поэтому преобразование в фрейм данных и добавление идентификатора группывне петли.rbind
in lapply возвращает матрицу, а rbind.data.frame
медленнее, поэтому мне нужно преобразовать матрицу вне цикла.
Ваш код переупорядочивает столбцы:
> head(op())
sex sex:time time group
1 0.8396437 0.283887315 0.4983305 A
2 0.4137317 0.626673282 0.5004230 B
3 0.6422066 0.469439754 0.4297816 C
но мой сохраняет порядок от anova
:
> head(br())
sex time sex.time group
1 0.8396437 0.4983305 0.283887315 A
2 0.4137317 0.5004230 0.626673282 B
3 0.6422066 0.4297816 0.469439754 C
вы не говорите, что порядок столбцов важен для вас или нет.
Скорость: сравнение вашего кода с моим с помощью jyjek'sкод:
> benchmark(op(), jy(), br())
test replications elapsed relative user.self sys.self user.child sys.child
3 br() 100 4.737 1.000 4.732 0.004 0 0
2 jy() 100 5.368 1.133 5.363 0.004 0 0
1 op() 100 12.769 2.696 12.767 0.000 0 0
Реальная скорость может быть достигнута при параллельной обработке, поскольку каждая сгруппированная анова независима - сколько у вас процессорных ядер?Использование parallel:mclapply
в моем коде сократило затраченное время только до 4,4 с, но ваше улучшение может варьироваться в зависимости от размера ваших данных и количества процессоров.