そういえばこのパッケージの説明がまだなかったので。
以前、この記事
でさらっと触れているのですが、repurrrsiveパッケージってご存知でしょうか?
CRAN版: CRAN - Package repurrrsive
以下引用
Recursive lists in the form of R objects, 'JSON', and 'XML', for use in teaching and examples. Examples include color palettes, Game of Thrones characters, 'GitHub' users and repositories, and entities from the Star Wars universe. Data from the 'gapminder' package is also included, as a simple data frame and in nested and split forms.
とあるように、いろいろなデータが含まれています。
こちらに書かれてる方法で関数一覧を作って見てみると、 niszet.hatenablog.com
こんなかんじ
library(repurrrsive) ls("package:repurrrsive") #> [1] "gap_nested" "gap_simple" "gap_split" "gh_repos" #> [5] "gh_repos_json" "gh_repos_xml" "gh_users" "gh_users_json" #> [9] "gh_users_xml" "got_chars" "got_chars_json" "got_chars_xml" #>[13] "sw_films" "sw_people" "sw_planets" "sw_species" #>[17] "sw_starships" "sw_vehicles" "wesanderson" "wesanderson_json" #>[21] "wesanderson_xml"
上にあげたうち、末尾にjsonやxmlがついたものは実際は関数で、呼び出すと対応するjsonやxmlのファイルのありか(パス)を返してきます。あとはRのオブジェクト。
私の環境ではたとえばこんな感じです。
repurrrsive::gh_repos_json() #>[1] "C:/Users/niszet/Documents/R/win-library/3.4/repurrrsive/extdata/gh_repos.json"
repurrrsive::gh_repos_xml() #>[1] "C:/Users/niszet/Documents/R/win-library/3.4/repurrrsive/extdata/gh_repos.xml"
jsonはjsonlite::read_json()
で取り扱えますね。例えばこんな感じ。
# 返却値はlistなのでこのまま実行するとコンソールが文字まみれに… jsonlite::read_json(repurrrsive::got_chars_json())
Rはjsonの取り扱いも簡単に出来て良いですね。
しかし、この方法で得たRオブジェクト(リスト)と先のデータ(_jsonがついていないオブジェクト)は厳密には一致しておらず、下記のコードはFALSEを返します。
identical(jsonlite::read_json(repurrrsive::got_chars_json()), repurrrsive::gh_repos) #> FALSE
これはViewで見てみると、[[1]][["titles"]]
や [[1]][["aliases"]]
が異なります。
jsonの方は
無印は
という感じで、jsonの場合はここがリストになっているのですね。
xmlの場合はxml2::read_xml()
ですね。これを実際にやってみると、
xml2::read_xml(repurrrsive::gh_repos_xml()) #> {xml_document} #> <root> #> [1] <elem>\n <elem>\n <id>61160198</id>\n <name>after</name>\n <full_name>gab ... #> [2] <elem>\n <elem>\n <id>14756210</id>\n <name>2013-11_sfu</name>\n <full_na ... #> [3] <elem>\n <elem>\n <id>41645119</id>\n <name>advdatasci</name>\n <full_nam ... #> [4] <elem>\n <elem>\n <id>56019902</id>\n <name>2016-14</name>\n <full_name>j ... #> [5] <elem>\n <elem>\n <id>17120350</id>\n <name>ampolcourse</name>\n <full_na ... #> [6] <elem>\n <elem>\n <id>57878579</id>\n <name>aqi_pdf</name>\n <full_name>m ...
と、ちょっと趣が違いますね。とりあえずView()
で見てみると
となります。ふむ。ここで(▷)のアイコンを押しても展開されません。が、適当な要素にマウスカーソルをあてると[ ⇐]のアイコンが出ますね。1行目を押してみると
xml_child(xml2::read_xml(repurrrsive::gh_repos_xml()), 1)
という形で、なんと子要素を適切な形で抜き取れるようにRStudio IDEの方でよしなにしてくれました。ここでxml_child()'はxml2パッケージの関数なので、実行する際は
xml2::をつけるか
library(xml2)`を事前に実行しておきます。
どんな感じかなー。
library(xml2) xml_child(xml2::read_xml(repurrrsive::gh_repos_xml()), 1) #> {xml_node} #> <elem> #> [1] <elem>\n <id>61160198</id>\n <name>after</name>\n <full_name>gaborcsardi/after< ... #> [2] <elem>\n <id>40500181</id>\n <name>argufy</name>\n <full_name>gaborcsardi/arguf ... #> [3] <elem>\n <id>36442442</id>\n <name>ask</name>\n <full_name>gaborcsardi/ask</ful ... #> [4] <elem>\n <id>34924886</id>\n <name>baseimports</name>\n <full_name>gaborcsardi/ ... #> [5] <elem>\n <id>61620661</id>\n <name>citest</name>\n <full_name>gaborcsardi/cites ... #> [6] <elem>\n <id>33907457</id>\n <name>clisymbols</name>\n <full_name>gaborcsardi/c ... #> [7] <elem>\n <id>37236467</id>\n <name>cmaker</name>\n <full_name>gaborcsardi/cmake ... #> [8] <elem>\n <id>67959624</id>\n <name>cmark</name>\n <full_name>gaborcsardi/cmark< ... #> [9] <elem>\n <id>63152619</id>\n <name>conditions</name>\n <full_name>gaborcsardi/c ... #> [10] <elem>\n <id>24343686</id>\n <name>crayon</name>\n <full_name>gaborcsardi/crayo ... #> [11] <elem>\n <id>69169722</id>\n <name>debugme</name>\n <full_name>gaborcsardi/debu ... #> [12] <elem>\n <id>64197030</id>\n <name>diffobj</name>\n <full_name>gaborcsardi/diff ... #> [13] <elem>\n <id>25061555</id>\n <name>disposables</name>\n <full_name>gaborcsardi/ ... #> [14] <elem>\n <id>23227981</id>\n <name>dotenv</name>\n <full_name>gaborcsardi/doten ... #> [15] <elem>\n <id>23483249</id>\n <name>elasticsearch-jetty</name>\n <full_name>gabo ... #> [16] <elem>\n <id>22438731</id>\n <name>falsy</name>\n <full_name>gaborcsardi/falsy< ... #> [17] <elem>\n <id>61160771</id>\n <name>fswatch</name>\n <full_name>gaborcsardi/fswa ... #> [18] <elem>\n <id>37042992</id>\n <name>gh</name>\n <full_name>gaborcsardi/gh</full_ ... #> [19] <elem>\n <id>68708330</id>\n <name>gitty</name>\n <full_name>gaborcsardi/gitty< ... #> [20] <elem>\n <id>10396379</id>\n <name>ISA</name>\n <full_name>gaborcsardi/ISA</ful ... #> ...
と、このような形で得られました。これをまた'View()`で囲ってあげれば表示されるので、一応繰り返していけば目的の場所にたどり着けるのでは?と思います(ちょっと手間ですね。下の階層まで一度に表示されると良いのですが、多分listとかでないと展開できないだろうな…)
さて、これがどのclass(データ構造)ならRStudio IDEのView()
対応しているのか?などの情報はまだ押さえていませんが、とりあえずView()
して行を選択してみる。コンソール上に出てきたコマンドを実行してみて値が得られたらラッキー…!という使い方でも良いのではないかなと思います。これならRに不慣れな人でも、手間はかかるけど1つ1つ目で見て確認しながら作業が出来るのでは?と思います。
S4, R5, RCなどでどのような挙動になるのか確認したかったのですが、未調査です…。これもいずれ…。
ただし、対象となるデータの一番上の階層がdata.frameの場合はdata.frameとして扱われてしまうので要注意です。repurrrsiveにもあります。たとえばこのデータ。
repurrrsive::gap_nested #> # A tibble: 142 x 3 #> country continent data #> <fct> <fct> <list> #> 1 Afghanistan Asia <tibble [12 x 4]> #> 2 Albania Europe <tibble [12 x 4]> #> 3 Algeria Africa <tibble [12 x 4]> #> 4 Angola Africa <tibble [12 x 4]> #> 5 Argentina Americas <tibble [12 x 4]> #> 6 Australia Oceania <tibble [12 x 4]> #> 7 Austria Europe <tibble [12 x 4]> #> 8 Bahrain Asia <tibble [12 x 4]> #> 9 Bangladesh Asia <tibble [12 x 4]> #> 10 Belgium Europe <tibble [12 x 4]> #> # ... with 132 more rows
この場合は、
View(repurrrsive::gap_nested)
で表示すると
となります。
View(as.list(repurrrsive::gap_nested))
のように、as.list()
で囲えば
と出来ますので、データフレーム内にlistを格納しているような構成で、とりあえずViewで中身を覗きたいというときにはこの方法もありかなと思います。
Enjoy!!