R
JSON

【Rメモ】13日の金曜日、JSONって何?

More than 1 year has passed since last update.

前回記事で、Rを通じてJSONデータを取扱いました。
その関係で、尊敬する知り合いの方からtwitterで「ジェイソン怖い」というツイートを頂きました。笑

私もJSON形式のデータをまともに扱ったのは前回記事が初めてで、
しっかり勉強せねば!と思い、自習レベルで内容理解のための情報整理をしたいと思います。

慣れ親しんだRを使いながら、JSONの扱いを理解していこうと思います。
自身も詳しくないため、誤解を恐れずまとめていきます。

また、情報整理のため、色々な記事を参照させていただいています。
情報発信いただいているプロフェッショナルの方々に感謝申し上げます。

対象読者

・Rの基本的な機能がわかる
・JSON分からないけど、使ってみたい
・13日の金曜日が怖い

JSONって何?

wikipediaによれば以下のとおり

JSON(ジェイソン、JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptにおけるオブジェクトの表記法をベースとしているが、JSONはJavaScript専用のデータ形式では決してなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しに使えるよう設計されている。
JavaScript Object Notation_wikipedia

ふむ、軽量で互換性が高く、プログラムで扱いやすいデータのようですね。
どんな姿をしているのか見てみましょうか。
RESAS-APIから旧市町村一覧で参照してみようと思います。

OldCityName.json

{
    "message": null,
    "result": [{
        "prefCode": 2,
        "cityCode": "02201",
        "cityName": "青森市",
        "oldCityCode": "01",
        "oldCityName": "奥内村"
    }, {
        "prefCode": 2,
        "cityCode": "02201",
        "cityName": "青森市",
        "oldCityCode": "02",
        "oldCityName": "横内村"
    }, {
        "prefCode": 2,
        "cityCode": "02201",
        "cityName": "青森市",
        "oldCityCode": "03",
        "oldCityName": "原別村"
    }, {
        "prefCode": 2,
        "cityCode": "02201",
        "cityName": "青森市",
        "oldCityCode": "04",
        "oldCityName": "五郷村" 
    }]
}

ふむふむ、"message"と"result"があって、
さらに"result"の要素が配列になってて、それぞれ"prefCode"~"oldCityName"まで5つの成分があり、
これに対応した値が格納されているわけですね・・・。
あれ?Rのリストに似てますね?リストとして考えると、解釈が早いかも?
※一流プログラマの方々に怒られるかもしれません(汗)

JSONをRオブジェクトに変換する

RでJSONを扱うには、rjsonが便利だと耳にしました。
jsonliteというパッケージもあるので、もう少し勉強が必要ですね・・・)

【仕様はこちら】
rjsonパッケージ
jsonliteパッケージ

先ほどの、RESAS-APIを使った旧市町村一覧を、rjsonで読み込んでみます。
rjson::fromJSON()で、json形式のデータを、Rオブジェクトに変換してくれるみたいです。

oldCities.r
library(RCurl) #RCurl httpリクエストの作成が可能になるパッケージ
library(rjson) #jsonデータを扱うパッケージ

url <- 'https://opendata.resas-portal.go.jp' 
api.oldCities <- '/api/v1/oldCities'
key <- 'XXXXX' #登録したAPIキー

#APIでjsonデータを取得
oldCities.json <- RCurl::getURL(paste(url,api.oldCities,sep=''),httpheader = paste('X-API-KEY:',key))

#jsonをリストに変換
oldCities.list <- rjson::fromJSON(oldCities.json)


strで中身の確認をすると、出力はこんな感じになりますね。

oldCities_output.r

>str(oldCities.list, list.len = 5)

List of 2
 $ message: NULL
 $ result :List of 11617
  ..$ :List of 5
  .. ..$ prefCode   : num 1
  .. ..$ cityCode   : chr "01101"
  .. ..$ cityName   : chr "札幌市中央区"
  .. ..$ oldCityCode: chr "01"
  .. ..$ oldCityName: chr "琴似町4-1"
  ..$ :List of 5
  .. ..$ prefCode   : num 1
  .. ..$ cityCode   : chr "01101"
  .. ..$ cityName   : chr "札幌市中央区"
  .. ..$ oldCityCode: chr "02"
  .. ..$ oldCityName: chr "札幌市6-1"
  ..$ :List of 5
  .. ..$ prefCode   : num 1
  .. ..$ cityCode   : chr "01102"
  .. ..$ cityName   : chr "札幌市北区"
  .. ..$ oldCityCode: chr "01"
  .. ..$ oldCityName: chr "琴似町4-2"
  ..$ :List of 5
  .. ..$ prefCode   : num 1
  .. ..$ cityCode   : chr "01102"
  .. ..$ cityName   : chr "札幌市北区"
  .. ..$ oldCityCode: chr "02"
  .. ..$ oldCityName: chr "札幌市6-2"
  ..$ :List of 5
  .. ..$ prefCode   : num 1
  .. ..$ cityCode   : chr "01102"
  .. ..$ cityName   : chr "札幌市北区"
  .. ..$ oldCityCode: chr "03"
  .. ..$ oldCityName: chr "篠路村2-1"
  .. [list output truncated]

扱いやすいよう、データフレームにしてみます。

oldCities.r
#まずは各要素をベクトルに変換
prefCode <- as.numeric(lapply(oldCities.list$result,"[[",1))
cityCode <- as.character(lapply(oldCities.list$result,"[[",2))
cityName <- as.character(lapply(oldCities.list$result,"[[",3))
oldCityCode <- as.character(lapply(oldCities.list$result,"[[",4))
oldCityName <- as.character(lapply(oldCities.list$result,"[[",5))

#データフレーム化
oldCities.df <- data.frame(prefCode,cityCode,cityName,oldCityCode,oldCityName)

単純な構造だったので簡単な記述だけで大丈夫でした。

参考になる記事もありました。感謝です。
データフレーム ⇔ リスト の変換

おわりに

リストの扱いに習熟できれば、もっと複雑なデータも分析できそうですね。
データフレーム化はもっとスマートにできそうな気もします。

このあたりはもっと勉強したいと思います。