R Advent Calendar 2015の二日目です。
昨日は表形式のデータをR上で扱いやすく、さらに可視化やモデリングの関数との相性が良いtidy形式なデータフレームについての話をしました。昨日が表形式なら、今日はRでのデータ形式として主要なもう一つの形式、リスト形式のオブジェクトを扱ってみたいと思います。
私はGitHubが(進捗的な意味で)好きで、見つけたR関係のパッケージには割りと星をつけています(2015-12-01の時点で725のリポジトリ数)。GitHubには既存のRパッケージでなく、これからCRANに登録されるであろう原石のようなパッケージがあったりします。そういうものを見つけてはストーキングの対象に加えているわけです。
自分がスターをつけたリポジトリの情報は、以下のようなURLでGitHubのAPIを叩けば得ることができます。
https://api.github.com/users/uribo/starred
JSONフォーマットとして格納されています。表形式では無いデータですので、Rではリストとして扱われます。
表形式でないデータの操作については、今週末のJapan.R 2015でうさぎさんこと@sinhrks さんが講演してださるのですが、それはそれとして、私は私で浅はかな知識の限りであれこれやりたいと思います。
なお今回の内容は
このページにある情報でほとんどのことができてしまいます。他にもリストの扱いを容易にするための関数の使い方についてまとまっているので、どうぞご参考ください。
🎯 GitHub APIからR上にデータを取り込む
今回使用するパッケージを読み込みます。
library(rlist) library(magrittr) library(formattable)
GitHub APIで取得できる情報が100リポジトリごとに提供されているので、今回は8つ分のページを用意します。
# api ref. https://developer.github.com/v3/activity/starring/ # 更新があったリポジトリの順番、100リポジトリごと max_page <- 8 api_url <- "https://api.github.com/users/uribo/starred?per_page=%d&sort=updated&page=%d" %>% sprintf(100, 1:max_page) api_url
## [1] "https://api.github.com/users/uribo/starred?per_page=100&sort=updated&page=1"
## [2] "https://api.github.com/users/uribo/starred?per_page=100&sort=updated&page=2"
## [3] "https://api.github.com/users/uribo/starred?per_page=100&sort=updated&page=3"
## [4] "https://api.github.com/users/uribo/starred?per_page=100&sort=updated&page=4"
## [5] "https://api.github.com/users/uribo/starred?per_page=100&sort=updated&page=5"
## [6] "https://api.github.com/users/uribo/starred?per_page=100&sort=updated&page=6"
## [7] "https://api.github.com/users/uribo/starred?per_page=100&sort=updated&page=7"
## [8] "https://api.github.com/users/uribo/starred?per_page=100&sort=updated&page=8"
このような配列を用意して、R上にJSONファイルを読み込ませます。使用するのは {rlist}
パッケージです。{rlist}
のおさらいとして、まずは1ページ分の情報を取得しましょう。
repo <- "https://api.github.com/users/uribo/starred?per_page=1&sort=updated&page=1" %>% list.load("json") %>% list.ungroup() repo %>% { print(list.names(.)) list.count(.) }
## [1] "id" "name" "full_name"
## [4] "owner" "private" "html_url"
## [7] "description" "fork" "url"
## [10] "forks_url" "keys_url" "collaborators_url"
## [13] "teams_url" "hooks_url" "issue_events_url"
## [16] "events_url" "assignees_url" "branches_url"
## [19] "tags_url" "blobs_url" "git_tags_url"
## [22] "git_refs_url" "trees_url" "statuses_url"
## [25] "languages_url" "stargazers_url" "contributors_url"
## [28] "subscribers_url" "subscription_url" "commits_url"
## [31] "git_commits_url" "comments_url" "issue_comment_url"
## [34] "contents_url" "compare_url" "merges_url"
## [37] "archive_url" "downloads_url" "issues_url"
## [40] "pulls_url" "milestones_url" "notifications_url"
## [43] "labels_url" "releases_url" "created_at"
## [46] "updated_at" "pushed_at" "git_url"
## [49] "ssh_url" "clone_url" "svn_url"
## [52] "homepage" "size" "stargazers_count"
## [55] "watchers_count" "language" "has_issues"
## [58] "has_downloads" "has_wiki" "has_pages"
## [61] "forks_count" "mirror_url" "open_issues_count"
## [64] "forks" "open_issues" "watchers"
## [67] "default_branch"
## [1] 67
取得した情報は次のような配列になっています。ownerの中にさらに情報がネストされています。
- id
- name
- full_name
- ...
- owner
- login
- id
- avatar_url
- ...
- site_admin
- ...
- default_branch
先ほど用意したURLを渡して、Rに取り組みましょう。list.load()
を使います。
repos <- api_url %>% list.load(type = "json") %>% list.ungroup()
🔨 リストの操作
リストについて操作を加えます。こういったリスト操作は {rlist}
の得意とするところです。リスト版の {dplyr}
という感じでしょうか。以下のような操作を行います。
list.filter()
絞り込み: 今回対象にしたいのはR言語で書かれたリポジトリなので、対象を絞り込みますlist.select()
選択: リストの要素が多いため、必要なものだけを使えるようにしますlist.sort()
並び替え: リストの並びを入れ替えますlist.update()
新たな要素の追加: CRANに登録されているパッケージかどうかの真偽値を与えますlist.map()
抽出: リストから値を取り出します。ベクトル形式で帰り値を得たい時にはlist.mapv()
とします
# CRANに登録されているパッケージ名のベクトルを作成しておきます pkg_name <- available.packages() %>% data.frame() %$% Package %>% as.vector() repos %<>% list.filter(!fork, language == "R") %>% list.select(name, owner = owner$login, description, stargazers_count, open_issues_count) %>% list.sort(-stargazers_count) %>% list.update(CRAN = ifelse(name %in% pkg_name, TRUE, FALSE))
279リポジトリが該当しました。
一覧表を作るために、リストの内容をデータフレームオブジェクトにしましょう。リストに格納されている各要素をlist.mapv()
で取り出し、データフレームの変数として代入します。つけられている星の数が多い15のリポジトリだけを抽出します。
df_gh_star <- data.frame(name = list.mapv(repos, name) %>% list.take(15), owner = list.mapv(repos, owner) %>% list.take(15), star = list.mapv(repos, stargazers_count) %>% list.take(15), issues = list.mapv(repos, open_issues_count) %>% list.take(15), CRAN = list.mapv(repos, CRAN) %>% list.take(15))
テーブルになったので、出力してみましょう。{rlist}
と同じパッケージの開発者であるrenkun-kenの{formattable}
を使います。
df_gh_star %>% formattable( list(owner = formatter("span", style = x ~ ifelse(x == "hadley", style(color = "darkorchid", font.weight = "bold"), ifelse(x == "rstudio", style(color = "royalblue", font.weight = "bold"), NA))), star = color_tile("white", "greenyellow"), issues = color_bar("pink", 0.2), CRAN = formatter("span", style = x ~ style(color = ifelse(x, "forestgreen", "tomato")), x ~ icontext(ifelse(x, "ok", "remove"), ifelse(x, "Yes", "No"))) ))
name | owner | star | issues | CRAN |
---|---|---|---|---|
ggplot2 | hadley | 1556 | 20 | Yes |
shiny | rstudio | 1504 | 166 | Yes |
devtools | hadley | 1140 | 55 | Yes |
awesome-R | qinwf | 1024 | 12 | No |
dplyr | hadley | 986 | 169 | Yes |
slidify | ramnathv | 625 | 139 | No |
SparkR-pkg | amplab-extras | 547 | 21 | No |
ggvis | rstudio | 501 | 163 | Yes |
ggthemes | jrnold | 493 | 4 | Yes |
rvest | hadley | 449 | 20 | Yes |
CausalImpact | 424 | 2 | No | |
rmarkdown | rstudio | 413 | 128 | Yes |
r-ninja | yihui | 410 | 6 | No |
DiagrammeR | rich-iannone | 401 | 30 | Yes |
ProjectTemplate | johnmyleswhite | 369 | 27 | Yes |
若干、starとissuesの数が実際の値とずれている気がしなくもないですが...まあよしとしましょう 😸
🎁 この開発者がすごい2015
去年もやっていたので、今年はGitHubでストーキングの対象になっているパッケージの開発者の方々についてこの場で公開してみたいと思います。年の瀬ですしお寿司。
有名なパッケージと、ストーキングの理由について簡単に書いておきます。敬称略。
- @renkun-ken... 日本人のR利用者にも人気のある開発者の一人です。今回使わせていただいた
{rlist}
や{formatrable}
だけでなくパイプ処理を行う{pipeR}
も有名です。 - @hadley... 神なので。今年も
{purrr}
や{multidplyr}
といった新しいパッケージを世に出して信者たちに救いを与えたそうな。 - @yutannihilation... 今年はこの人の年でした。
{chartist}
、{estatapi}
、{qiitr}
などのパッケージがあります。ブログもストーキングしていますが未だに名称を覚えられません(え。 - @dichika... ジャパニーズシリパク。
{sinchokur}
,{doudesuka}
,{jaguchi}
などのパッケージがあります。yeah::doudesuka()
を.Rprofileに追加したら、knitの際に辛くなったのもいい思い出です。 - @hoxo-m...
{dplyrr}
{lambdaR}
など、世界のRパッケージ開発者に引けを取らないパッケージを開発されています。中でも{pforeach}
が超便利で使っています。CRANにあげてくれよなー、頼むよー。 - @kos59125 ... typoを指摘してくれる
{DYM}
や並び替えをよしなにしてくれる{naturalsort}
など利用者の視点になって、あったら嬉しい、渋いパッケージを作ってくれています。{DYM}
は.Rprofileで設定しておくのがおすすめです。 - @sinhrks... ggplot2の拡張パッケージである
{ggfortify}
が便利でよく使わせてもらっています。 - @gaborcsardi... ユーティリティ系のパッケージを数多く開発されています。
{seer}
、{gh}
など。 - @timelyportfolio... D3.js とRを連携させたパッケージを中心に開発をされています。
{svgPanZoom}
、{d3vennR}
など。 - @hrbrmstr... 師匠です。Rだけでなく、外部サービスと連携させたパッケージ、地図を作成するパッケージなどが豊富です。
{slackr}
{docxtractr}
、{ggalt}
、{lineworkmaps}
などなど。
GitHub上のRパッケージをまとめる、通称gepuro task viewというのもあります。新たにRパッケージを探したい方はこちらが良いかもしれません。
紹介しきれませんでしたが、以下のパッケージもおすすめです。気になるものがありましたら、ぜひGitHubのページを見てください
- https://github.com/gastonstat/colortools
- https://github.com/baptiste/gridextra
- https://github.com/cboettig/knitcitations
- https://github.com/mtennekes/tmap
- https://github.com/paulhendricks/describer
- https://github.com/kaz-yos/tableone
- https://github.com/sailthru/tidyjson
- https://github.com/leeper/colourlovers
- https://github.com/sckott/cowsay
- https://github.com/xfim/ggmcmc
- https://github.com/stefano-meschiari/latex2exp
- https://github.com/sjmgarnier/viridis
- https://github.com/dgrtwo/broom
- https://github.com/ropensci/taxize
- https://github.com/dill/emoGG
- https://github.com/norimune/glmmstan
- https://github.com/richfitz/remoji
- https://github.com/dgrtwo/snippr
- https://github.com/renkun-ken/formattable
というわけで、R Advent Calendar 明日は kaneshin さんです。よろしくお願いします。