【R】stringrをdplyr::mutateで使うときにリストでなく行列を返す
なにか文字列を切り出して、さらに細かい変数を作りたいシチュエーションでひっかかったのでメモ。
例えばこんなデータを
Names | *Age | *Country |
---|---|---|
Shinzo Abe | 65 | Japan |
Donald Trump | 73 | USA |
Erna Solberg | 58 | Norway |
Sanna Marin | 34 | Finland |
こういうふうにしたい
Names | *Age | *Country | *FirstName | *LastName |
---|---|---|---|---|
Shinzo Abe | 65 | Japan | Shinzo | Abe |
Donald Trump | 73 | USA | Donald | Trunp |
Erna Solberg | 58 | Norway | Erna | Solberg |
Sanna Marin | 34 | Finland | Sanna | Marin |
このとき、stringrパッケージのstr_extract_allを使って以下のようにする。
ちなみに"\\w+"というのは、正規表現で「単語」をピックアップする。+をつけているのは1回以上繰り返すためなので、この場合は含まれる単語をすべてピックアップする。
くわしくはこちらなど。(英語記事)
dat = data.frame( Names = c("Shinzo Abe", "Doland Trump", "Erna Solberg", "Sanna Marin"), Age = c(65, 73, 58, 34), Country = c("Japan","USA","Norway","Finland")) dat2 = dat %>% mutate(lastname = str_extract_all(Names,"\\w+")[1], firstname = str_extract_all(Names,"\\w+")[2])
こういう感じにすると、stringrの返すオブジェクトはリストなので
Names Age Country lastname firstname 1 Shinzo Abe 65 Japan Shinzo, Abe Doland, Trump 2 Doland Trump 73 USA Shinzo, Abe Doland, Trump 3 Erna Solberg 58 Norway Shinzo, Abe Doland, Trump 4 Sanna Marin 34 Finland Shinzo, Abe Doland, Trump
こんな感じで中身がベクターになってしまう。
かといってこうすると
dat2 = dat %>% mutate(lastname = str_extract_all(Names,"\\w+")[[1]][1], firstname = str_extract_all(Names,"\\w+")[[2]][2])
こうなる。
> dat2 Names Age Country lastname firstname 1 Shinzo Abe 65 Japan Shinzo Trump 2 Doland Trump 73 USA Shinzo Trump 3 Erna Solberg 58 Norway Shinzo Trump 4 Sanna Marin 34 Finland Shinzo Trump
しらべたら、simplifyという引数を使えば行列にできるようだ。
dat2 = dat %>% mutate(lastname = str_extract_all(Names,"\\w+",simplify = TRUE)[,1], firstname = str_extract_all(Names,"\\w+",simplify = TRUE)[,2]) > dat2 Names Age Country lastname firstname 1 Shinzo Abe 65 Japan Shinzo Abe 2 Doland Trump 73 USA Doland Trump 3 Erna Solberg 58 Norway Erna Solberg 4 Sanna Marin 34 Finland Sanna Marin
お気づきの方もいると思うが、この記事はフィンランドで34歳の女性首相が誕生したというニュースが出た翌日ぐらいに書きました。