separate() / separate_rows()
要約
・文字列をセパレータで分けるtidyr::separateには2種類
・separate()はstringr::str_split()と同様に列方向(横)に展開
・separate_rows()は行方向(縦)に展開、他の列は値が複製される
以前の記事
separateは2種類あった
ご存じtidyr::separate()は、例えばCSVのようにセパレータで複数の要素がつながった1つの文字列を、セパレータ区切りで分割・展開する関数だ。
今さら何を言っているんだという話はさておき、よくよく調べてみたら分割した文字列を、縦方向に展開するseparate_rows()があったのでメモ代わりに残しておく。
seaparate_rows()
このメリットは、分割後の文字列がいくつあるかを確定させなくてよいこと。separate()ではあらかじめ展開先の列を確保しておく、つまり分割後の要素の数=セパレータの数+1だけ列をinto = で指定しておく必要があった(もちろん厳密には、最後の列に残った文字列を全部押し込めておくようなオプションはあるのだけど)。
というわけで、実際に使ってみるとこうなる。hoge列の文字列を分割するのだが、separate_rows()では列を必要な分だけ勝手に増やしていってくれている。
もちろん、separate()のような横長形式にしたければ、pivot_wider()を使ってやればよい。
> hoge.df
NO hoge
1 1 1|2|3|4|5|6|7|8|9|10
2 2 A|B|C
> hoge.df %>% separate(hoge, into = paste0("X", c(1:9)), sep = "\\|",
fill = "right", extra = "merge")
NO X1 X2 X3 X4 X5 X6 X7 X8 X9
1 1 1 2 3 4 5 6 7 8 9|10
2 2 A B C <NA> <NA> <NA> <NA> <NA> <NA>
> hoge.df %>% separate_rows(hoge, sep = "\\|")
# A tibble: 13 x 2
NO hoge
<chr> <chr>
1 1 1
2 1 2
3 1 3
4 1 4
5 1 5
6 1 6
7 1 7
8 1 8
9 1 9
10 1 10
11 2 A
12 2 B
13 2 C
どうして気づかなかったのか
separate()に関する記事って、だいたいseparate()しか載せてないからかなあ…。単純に需要がニッチなのかもしれない。
以上。