メモ:dplyr::mutate()の中でstr_split()したいと思ったとき、使うのはtidyr::separate()だ
定期的に忘れるのでメモ。たぶんまた忘れるけど。
uri氏の素晴らしいパッケージJapan.useRにこういうデータがあります。
library(dplyr) library(stringr) library(Japan.useR) slides <- Japan.useR::materials() %>% filter(str_detect(Slide, "slideshare|rpubs")) %>% select(Slide) head(slides) #> Slide #> 1 https://rpubs.com/kazutan/hijiyamar1 #> 2 http://www.slideshare.net/sakaue/hiroshimar-1-12 #> 3 http://www.slideshare.net/sakaue/hiroshimar-1-13-lt #> 4 http://www.slideshare.net/KojiKosugi/psych-8342608 #> 5 http://www.slideshare.net/springking/ss-8342938 #> 6 http://www.slideshare.net/sakaue/hiroshimar-2
これが、あなたの目には、
https://サイト/ユーザ名/スライド
と見えるとします。
この各要素をうまいこと取り出したい。
思いつくシンプルな発想は、"/"
でstr_split()
し、ネギトロめいた配列に分解することです。
が、うまくいきません。
slides %>% mutate(negitoro = str_split(Slide, "/"), site = negitoro[3]) #> Error: not compatible with STRSXP
そんなときは、tidyrにseparate()
という関数があるのでこれを使えるみたいです。
library(tidyr) slides %>% separate(Slide, into = c("protocol", "_", "site", "username", "title"), sep = "/", extra = "drop") %>% head #> protocol _ site username title #> 1 https: rpubs.com kazutan hijiyamar1 #> 2 http: www.slideshare.net sakaue hiroshimar-1-12 #> 3 http: www.slideshare.net sakaue hiroshimar-1-13-lt #> 4 http: www.slideshare.net KojiKosugi psych-8342608 #> 5 http: www.slideshare.net springking ss-8342938 #> 6 http: www.slideshare.net sakaue hiroshimar-2
ちなみにextra
は、into
に指定したカラム数と実際に分かれた数が違う時にどうするかの挙動を指定するオプションです。
"drop"
を指定すると、実際に分かれた数が指定より多い場合ははみ出た要素を無視して、少ない場合はNA
で埋めてくれます。
デフォルトだと、長さが違うとエラーになります。一番最後に/
がついているものとついていないものが混じっているからです。
slides %>% separate(Slide, into = c("protocol", "_", "site", "username", "title"), sep = "/") #> Error: Values not split into 5 pieces at 16, 20, 119, 357, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385 slides[16,] #> [1] http://www.slideshare.net/tmr_kohei/kashiwa-r/ #> 465 Levels: http://1drv.ms/1sbZsIb http://bit.ly/eabQki ... https://www.slideshare.net/yurieoka37/ss-35866478
"merge"
を指定すると、実際に分かれた数が指定より多い場合ははみ出た要素は分割せず、少ない場合はNA
で埋めてくれます。
slides %>% filter(row_number() == 16) %>% separate(Slide, into = c("protocol", "_", "site", "username", "title"), sep = "/", extra = "merge") #> protocol _ site username title #> 1 http: www.slideshare.net tmr_kohei kashiwa-r/