group_by() + summarise() でgroupごとにベクトルを結合する
目的
library(tidyverse) # これを data <- tribble(~x, ~y, "a", c(1, 2), "a", c(), "a", c(3), "b", c(), "c", c(4), "c", c(5) ) # こうしたい tribble(~x, ~y, "a", c(1, 2, 3), "b", c(), "c", c(4, 5) )
これが簡単そうにみえて意外と手こずったのでメモ。
結論
list(do.call(c, y))
試行錯誤録
失敗
data |> group_by(x) |> summarise(y = c(y)) #> `summarise()` has grouped output by 'x'. You can override using the `.groups` #> argument. #> # A tibble: 6 × 2 #> # Groups: x [3] #> x y #> <chr> <list> #> 1 a <dbl [2]> #> 2 a <NULL> #> 3 a <dbl [1]> #> 4 b <NULL> #> 5 c <dbl [1]> #> 6 c <dbl [1]>
普通にc()
で結合しようとしてもうまくいかない。
面倒くさい方法
data |> group_by(x) |> summarise(y = list(y)) |> mutate(y = map(y, flatten_dbl)) #> # A tibble: 3 × 2 #> x y #> <chr> <list> #> 1 a <dbl [3]> #> 2 b <dbl [0]> #> 3 c <dbl [2]>
できてるっちゃできてるんだけど一見「なんでわざわざlist()
した後にflatten()
してるの?」と思うし、わざわざmutate()
せずにsummarise()
だけでできる方法がある気がする。
成功
data |> group_by(x) |> summarise(y = list(do.call(c, y))) #> # A tibble: 3 × 2 #> x y #> <chr> <list> #> 1 a <dbl [3]> #> 2 b <NULL> #> 3 c <dbl [2]>
これでOK。