この話の続き。
「Rを使ってYahoo!乗換案内から運賃や所要時間,乗換回数を取得するコード書いた」をscrapeRで書いてみたよ - XXXannex
前のエントリーに追記してもよかったのですが、内容的に独立したエントリーに分けた方がよさそう。
listから変換
applyから返ってきた結果をいい感じにデータフレームにしたい、という話について、コメントでアドバイスをいただきましたので試してみました。
実際にスクレイピングする必要はないのでコードは簡略化してます。
#出発駅と到着駅ベクトル station1 <- c("渋谷","表参道", "外苑前") station2 <- c("品川","大崎", "五反田") transit.search <- function(from, to){ Cost.v <- 1 Transfer.v <- 2 Time.in <- 3 Time.out <- 4 list(Origin=from, Destination=to, Cost=Cost.v, Timein=Time.in, Timeout=Time.out, Transfer=Transfer.v) } d <- data.frame(t(mapply(transit.search, station1, station2))) rownames(d) <- seq(nrow(d))
listで返して、t()で縦横を入れ替えて、データフレームにします。
> d Origin Destination Cost Timein Timeout Transfer 1 渋谷 品川 1 3 4 2 2 表参道 大崎 1 3 4 2 3 外苑前 五反田 1 3 4 2 >
うまくできた!文字列をread.tableするとかヘンなことをしなくてもできるんですね。
plyr パッケージを使う
で、本題なのですが。うまく行ったとはいえ、もう少し直感的にできたらいいなーと思って色々調べてみると、どうやらplyrパッケージの中にそういうモノがあるようです。
http://had.co.nz/plyr/plyr-intro-090510.pdf
今回の目的には、mdply()がピッタリのようです。mdply()を使って書き直すとこんな感じ。
library(plyr) #出発駅と到着駅ベクトル Origin <- c("渋谷","表参道", "外苑前") Destination <- c("品川","大崎", "五反田") transit.search <- function(Origin, Destination){ Cost <- "1" Transfer <- "2" Timein <- "3" Timeout <- "4" data.frame(Origin, Destination, Cost, Timein, Timeout, Transfer) } mdply(data.frame(Origin, Destination), transit.search)
実行結果。
Origin Destination Cost Timein Timeout Transfer 1 渋谷 品川 1 3 4 2 2 表参道 大崎 1 3 4 2 3 外苑前 五反田 1 3 4 2
完璧じゃないですか・・・。全く無駄のないコード。
しかしこの関数、使い勝手が独特で、どうやって使うのか小一時間悩んでしまいました。サンプル見てもよく分からないし・・・。
まず引数。
> args(mdply) function (.data, .fun = NULL, ..., .progress = "none")
"The m*ply functions are the plyr version of mapply" などとマニュアルには書いてあるくせに、入力するデータが1つしかない!なんだこれ!
仕方ないのでマニュアルとコードを見ながら調べていった結果、ざっくりまとめると「第2引数で指定した関数の引数に、第1引数のデータフレームをwithした名前を指定する」ということらしい。
例えばこういうデータに何かしたい時は、"Origin"、"Destination" という名前の引数を持つ関数を定義してやる。
> data.frame(Origin, Destination) Origin Destination 1 渋谷 品川 2 表参道 大崎 3 外苑前 五反田
うーん、まあ、言われてみれば確かに直感的なんだけど。直感的すぎて不気味というか、何となく黒魔術っぽいなーと思ってしまう。変数の名前とデータの値の区別が曖昧なところがそう感じさせるのかなあ。
なんにしても、やっぱRすごい。ここまで出来るんだったら、他のLLじゃなくてRでスクレイピングするメリットがかなり出てくる気がする。