Возможно, самый простой способ - использовать функцию dplyr::do()
, но можно также использовать group_map()
.Полный пример:
library(tidyverse)
#some complex function
func = function(x) {
mod = lm(Sepal.Length ~ Petal.Width, data = x)
mod_coefs = broom::tidy(mod)
tibble(
mean_sepal_length = mean(x$Sepal.Length),
mean_petal_width = mean(x$Petal.Width),
slope = mod_coefs[[2, 2]],
slope_p = mod_coefs[[2, 5]]
)
}
#plyr version
plyr::ddply(iris, "Species", func)
#dplyr with do()
iris %>%
group_by(Species) %>%
do(func(.))
#dplyr with group_map()
#have to rewrite the function to take a second argument, which is the grouping variable
func2 = function(x, y) {
mod = lm(Sepal.Length ~ Petal.Width, data = x)
mod_coefs = broom::tidy(mod)
tibble(
mean_sepal_length = mean(x$Sepal.Length),
mean_petal_width = mean(x$Petal.Width),
slope = mod_coefs[[2, 2]],
slope_p = mod_coefs[[2, 5]]
)
}
iris %>%
group_by(Species) %>%
group_map(func2)
Эти продукты:
Species mean_sepal_length mean_petal_width slope slope_p
1 setosa 5.006 0.246 0.9301727 5.052644e-02
2 versicolor 5.936 1.326 1.4263647 4.035422e-05
3 virginica 6.588 2.026 0.6508306 4.798149e-02
# A tibble: 3 x 5
# Groups: Species [3]
Species mean_sepal_length mean_petal_width slope slope_p
<fct> <dbl> <dbl> <dbl> <dbl>
1 setosa 5.01 0.246 0.930 0.0505
2 versicolor 5.94 1.33 1.43 0.0000404
3 virginica 6.59 2.03 0.651 0.0480
# A tibble: 3 x 5
# Groups: Species [3]
Species mean_sepal_length mean_petal_width slope slope_p
<fct> <dbl> <dbl> <dbl> <dbl>
1 setosa 5.01 0.246 0.930 0.0505
2 versicolor 5.94 1.33 1.43 0.0000404
3 virginica 6.59 2.03 0.651 0.0480
Есть 2 различия.Вывод ddply()
является стандартным фреймом данных, хотя функция выдает тиббл.Выходы dplyr сгруппированы, хотя группирование было «использовано».