ベクトルが[でリストが[[で

ひとりアドベントカレンダー3日目。
URLをスラッシュで分割し特定の要素を抽出したいとする。
文字列の分割は組み込み関数だとstr_split関数があるのでこれを使ってみる。

library("dplyr")

> (dat <- data.frame(URL=c("http://notchained.hatenablog.com/entry/2015/06/29/233237",
                           +                         "http://d.hatena.ne.jp/dichika/"),
                     +                   stringsAsFactors = FALSE))
URL
1 http://notchained.hatenablog.com/entry/2015/06/29/233237
2                           http://d.hatena.ne.jp/dichika/
  > (res <- dat %>% transmute(negitoro=strsplit(URL, split="/")))
negitoro
1 http:, , notchained.hatenablog.com, entry, 2015, 06, 29, 233237
2                                http:, , d.hatena.ne.jp, dichika

結果をみるとカンマなど入っていて見慣れない表記になっている。
これ、実は各要素がリストの入れ子構造になっている。

> res$negitoro
[[1]]
[1] "http:"                     ""                         
[3] "notchained.hatenablog.com" "entry"                    
[5] "2015"                      "06"                       
[7] "29"                        "233237"                   

[[2]]
[1] "http:"          ""               "d.hatena.ne.jp" "dichika"   

このnegitoro列の1行目の3番目の要素(notchained/hatenablog.com)にアクセスしたい時は以下のように書く。

> res$negitoro[[1]][3]
[1] "notchained.hatenablog.com"

ここで演算子と[演算子が両方登場している。
リストに格納されている要素を抽出する時は[[演算子を使う。
そして格納されている文字列ベクトルから要素を抽出する時は[演算子を使う。
原則として[演算子を使って、リストで変な挙動をしたら[[演算子を使うくらいに覚えてたら良い。
ちなみにAdvanced Rには以下のような格言が紹介されている。
> “If list x is a train carrying objects, then x[[5
is the object in car 5; x[4:6] is a train of cars 4-6.”
> — @RLangTip
この辺の違いについて頭を整理したい人はAdvanced Rを一読することをお勧めする。邦訳も出るらしいし。

R言語徹底解説

R言語徹底解説

さて、全ての行から3つ目の要素を抽出したい場合、私ならlapplyとunlistを使う。
各リストに対してlapplyで3つ目の要素を抽出する関数を適用し、返ってきた結果(リスト)をunlist関数でベクトルに変換している。

> (res <- res %>% transmute(domain=unlist(lapply(negitoro, function(x)x[3]))))
                     domain
1 notchained.hatenablog.com
2            d.hatena.ne.jp||<

一歩先へ

上ではlapplyとunlistを組み合わせて書いたがtidyrを使うともう少しわかりやすく書ける。
その辺は下記記事を参照してほしい。
http://notchained.hatenablog.com/entry/2015/06/29/233237
当該記事に限らずこのブログは非常に有用なので興味をもった読者はぜひDigってみてほしい。

Rの文字列処理

最後に、str_split関数がでてきたのでRの文字列処理について一つ。
Rの文字列処理に関しては多くの記事がある中、私は下記を勧めたい。
http://yamano357.hatenadiary.com/entry/2015/07/19/175633
なぜならブログ主が非常に勤勉でほめると伸びる子だからだ。
私はまめにほめたり煽ったりしているので、皆さんにもぜひお願いしたい。