まずは蝋の翼から。

学んだことを書きながら確認・整理するためのメモブログ。こういうことなのかな?といったことをふわっと書いたりしていますが、理解が浅いゆえに的はずれなことも多々あると思うのでツッコミ歓迎

acrossを用いて、Rで列ごとに別の集約関数をまとめて適応させる

dplyr1.0.0から追加されるacrossで条件に当てはまる列に対して個別に集約関数の適用ができるようになった。

今までもsummarise_atでもできたがこの場合は1条件にしか適用できなかったが、acrossでは複数条件での適用が可能。

summarise_atではSepalで始まる場合はmeanPetalで始まる場合はsumを適用している。まとめて1回ではできないので2回に分けるか、summarise_allでまとめて出す必要がある。

iris %>%
  group_by(Species) %>%
  summarise_at(vars(starts_with("Sepal")),
               funs(mean))

# # A tibble: 3 x 3
# Species    Sepal.Length Sepal.Width
# * <fct>             <dbl>       <dbl>
#   1 setosa             5.01        3.43
# 2 versicolor         5.94        2.77
# 3 virginica          6.59        2.97



iris %>%
  group_by(Species) %>%
  summarise_at(vars(starts_with("Petal")),
               funs(mean))

# # A tibble: 3 x 3
# Species    Petal.Length Petal.Width
# * <fct>             <dbl>       <dbl>
#   1 setosa             1.46       0.246
# 2 versicolor         4.26       1.33 
# 3 virginica          5.55       2.03 

iris %>% 
  group_by(Species) %>%
  summarise_all(funs(mean, sum))

# # A tibble: 3 x 9
# Species Sepal.Length_me… Sepal.Width_mean Petal.Length_me… Petal.Width_mean Sepal.Length_sum Sepal.Width_sum Petal.Length_sum
# * <fct>              <dbl>            <dbl>            <dbl>            <dbl>            <dbl>           <dbl>            <dbl>
#   1 setosa              5.01             3.43             1.46            0.246             250.            171.             73.1
# 2 versic…             5.94             2.77             4.26            1.33              297.            138.            213  
# 3 virgin…             6.59             2.97             5.55            2.03              329.            149.            278. 
# # … with 1 more variable: Petal.Width_sum <dbl>

acrossを使うと、summarise内で個別に適用できる。

iris %>%
  group_by(Species) %>%
  summarise(across(starts_with("Sepal"), mean),
            across(starts_with("Petal"), sum))

# # A tibble: 3 x 5
# Species    Sepal.Length Sepal.Width Petal.Length Petal.Width
# * <fct>             <dbl>       <dbl>        <dbl>       <dbl>
#   1 setosa             5.01        3.43         73.1        12.3
# 2 versicolor         5.94        2.77        213          66.3
# 3 virginica          6.59        2.97        278.        101. 

なお、acrossなしと混在させることも可能。

iris %>%
  group_by(Species) %>%
  summarise(across(c(Sepal.Length, Sepal.Width), mean),
            sum_Petal.Length = sum(Petal.Length))

# Species    Sepal.Length Sepal.Width sum_Petal.Length
# * <fct>             <dbl>       <dbl>            <dbl>
#   1 setosa             5.01        3.43             73.1
# 2 versicolor         5.94        2.77            213  
# 3 virginica          6.59        2.97            278. 

余談

everythingを使うと全列を指定できる。

iris %>%
  group_by(Species) %>%
  summarise(across(everything(), mean),
            sum_Petal.Length = sum(Petal.Length))

# Species    Sepal.Length Sepal.Width Petal.Length Petal.Width sum_Petal.Length
# * <fct>             <dbl>       <dbl>        <dbl>       <dbl>            <dbl>
#   1 setosa             5.01        3.43         1.46       0.246             1.46
# 2 versicolor         5.94        2.77         4.26       1.33              4.26
# 3 virginica          6.59        2.97         5.55       2.03              5.55