[R] jqコマンドをRから呼び出し、JSONをデータフレームに格納する

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

外部のコマンドから呼び出したJSON形式の結果をデータフレーム形式に変換しておくと後々の処理に便利そうだと思い、今回は お天気WebサービスのJSONからjqコマンド経由でデータフレームまで格納するまでをやってみました。

jqコマンドでCSVに適した出力に加工

下記のコマンドを叩けば

$ curl -s http://weather.livedoor.com/forecast/webservice/json/v1?city=130010 | jq -r '.forecasts[] | [.dateLabel, .telop, .date] | @csv' 

以下のような出力を得ます。

"今日","曇り","2015-11-29"
"明日","曇のち晴","2015-11-30"
"明後日","晴時々曇","2015-12-01"

curl -s ... コマンドではダウンロードの進行中を示す出力なしでJSONの出力を行っています。

その後、パイプで jq -r ... コマンドに渡し、JSONの加工を行っています。jqコマンドの詳細や@csvによるCSVライクな形式への変換はそれぞれ、軽量JSONパーサー『jq』のドキュメント:『jq Manual』をざっくり日本語訳してみました, jqコマンドでJSONをCSVに変換する が参考になりました。

Rでのデータフレームへの変換

systemコマンド経由でRの配列に渡す

Rからシステムのコマンドを呼び出す際には、system関数

system(command, intern = FALSE,
       ignore.stdout = FALSE, ignore.stderr = FALSE,
       wait = TRUE, input = NULL, show.output.on.console = TRUE,
       minimized = FALSE, invisible = TRUE)

を用います。

先ほどのコマンドをこのsystem関数に渡します。その際、先ほどの出力と同様の文字列の配列データが得られます。

> text <- system("curl -s http://weather.livedoor.com/forecast/webservice/json/v1?city=130010 | jq -r '.forecasts[] | [.dateLabel, .telop, .date] | @csv' ", intern = TRUE)
> text
[1] "\"今日\",\"曇り\",\"2015-11-29\""       "\"明日\",\"曇のち晴\",\"2015-11-30\""  
[3] "\"明後日\",\"晴時々曇\",\"2015-12-01\""

引数に渡すintern = TRUEは出力をRのデータに文字列の配列データとしてバインドするかどうかを表します。FALSE(デフォルト)の場合はバインドされないです。

配列にラベルをつけてcsv形式にする

このままではラベルを持たない不完全なCSV形式のため、append関数で配列の先頭にラベルを追加します。

> csvText <- append("\"いつ\", \"天気\", \"日付\"", text)

read.csvでデータフレームに格納する

ラベルを追加した後は以下のようにcsvとして文字列の配列データを読み込み、データフレームに変換します。

> csv <- read.csv(text = csvText)
> csv
    いつ     天気       日付
1   今日     曇り 2015-11-29
2   明日 曇のち晴 2015-11-30
3 明後日 晴時々曇 2015-12-01

引数に渡すtext = csvTextでファイルとしてファイル名を指定するような要領で、文字列配列を関数の入力値として指定できます。

参考