概要
師走が近づく今日この頃、アドベントカレンダーの準備に勤しんでいらっしゃる方々もいらっしゃるとか思いますが、先日「tidyポエム Advent Calendar」なるものが募集を開始したようでR界隈の一部が騒めいたりもしました。
なお「tidyってなに?」という方は事前に下記のリンク先をご覧いただきますよう、よろしくお願いいたします。
さて、以前にRパッケージ群をもっとも支えるパッケージという記事でRパッケージの参照関係を可視化したことがありますが、今回はRユーザーの方々が日頃お世話になっているであろうtidyverseパッケージ「を」支えているパッケージ群はどういうものかをきちんと知り、皆で感謝をしようという啓蒙記事です。
具体的には、CRANのパッケージページ(下記画像)のImports/Suggestsにある黒枠で囲んだパッケージと、それらがさらに参照するパッケージが対象になります。

また、今回の記事はtidyverseに関してですので、せっかくですからグラフの処理を{igraph}ではなく{tidygraph}でやっています。
定義・設定
対象パッケージ名の指定と、パッケージのリストを取得するCRANリポジトリ、ならびに使用するパッケージ名を定数として設定。
TARGET_PACKAGE <- "tidyverse"
PACKAGE_REPOSITRY <- "https://mran.revolutionanalytics.com/snapshot/2017-11-15/"
LOAD_PACKAGE <- c("tidyverse", "miniCRAN", "tidygraph", "visNetwork", "ggraph")
{pacman}を利用してライブラリを読み込む。
このとき、install
を TRUE にしておくことで、パッケージがインストールされていない場合にインストールしてくれる(ただし、GitHubまでは見にいかないのでCRANで公開されているものに限定)。
pacman::p_load(char = LOAD_PACKAGE, install = TRUE, character.only = TRUE)
実行部
前回の記事は、reverse dependencyだったのでパッケージをひとつひとつ辿っていきましたが、今回はそのままで大丈夫です。
# CRANパッケージリストをオブジェクト化して取得
pdb <- miniCRAN::pkgAvail(repos = c(CRAN = PACKAGE_REPOSITRY))
# 依存パッケージリストの取得とtidygraphへのオブジェクト化
tidyvese_graph <- miniCRAN::makeDepGraph(
pkg = TARGET_PACKAGE, availPkgs = pdb, suggests = FALSE, enhances = FALSE
) %>%
tidygraph::as_tbl_graph(x = .) %>%
# コミュニティ抽出
dplyr::mutate(community = as.factor(x = tidygraph::group_spinglass()))
{visNetwork}を用いて可視化することで、インタラクティブにデータを見ることができるようにしています。
visNetwork::visNetwork(
nodes = tidyvese_graph %>%
tidygraph::activate(nodes) %>%
dplyr::mutate(shape = dplyr::case_when(name == TARGET_PACKAGE ~ "circle", TRUE ~ "box")) %>%
tibble::as_data_frame() %>%
tibble::rownames_to_column(var = "id") %>%
dplyr::mutate(label = name, group = community),
edges = tidyvese_graph %>%
tidygraph::activate(edges) %>%
dplyr::mutate(
color = dplyr::case_when(
type == "Imports" ~ "blue", type == "LinkingTo" ~ "red"
)
) %>%
dplyr::mutate(smooth = TRUE, shadow = FALSE, arrows = "middle") %>%
tibble::as_data_frame(),
width = 1800, height = 1800
) %>%
visNetwork::visLayout(randomSeed = 71) %>%
visNetwork::visOptions(highlightNearest = TRUE, selectedBy = list(variable = "label"))

いい感じにプロットできました。
{Rcpp}の奮闘っぷりに、{dplyr}, {tidyr}, {tibble}などがそれに続くコミュニティはとてもお世話になっているパッケージが多そうですね。ありがとうございます。
これらとは対照的に、{ggplot2}と{scales}や{reprex}と{markdown}が属するコミュニティは牧歌的ですね。
可視化や固有の処理で利用されるパッケージが多いですが、{dplyr}や{tidyr}などと比べて常時使うというほどでもないというところでしょうか。
tidygraphを少し試す
抽出したコミュニティでPageRankが上位Top1のパッケージを表示してみましょう。
tidyvese_graph_pgr <- tidyvese_graph %>%
tidygraph::activate(nodes) %>%
dplyr::mutate(pg = tidygraph::centrality_pagerank(damping = 0.85)) %>%
tibble::as_data_frame() %>%
dplyr::mutate(pg_order = dplyr::row_number(x = -pg)) %>%
dplyr::arrange(dplyr::desc(x = pg))
# 各コミュニティでTop1を表示
tidyvese_graph_pgr %>%
dplyr::group_by(community) %>%
dplyr::arrange(community, dplyr::desc(x = pg)) %>%
dplyr::top_n(n = 1, wt = pg) %>%
dplyr::arrange(pg_order)
knitr::kable(format = "markdown")
name | community | pg | pg_order |
---|---|---|---|
tidyverse | 6 | 0.2457331 | 1 |
reprex | 1 | 0.0624882 | 2 |
ggplot2 | 2 | 0.0456633 | 3 |
broom | 7 | 0.0373804 | 5 |
modelr | 3 | 0.0348920 | 6 |
rvest | 5 | 0.0195122 | 11 |
bindrcpp | 4 | 0.0108860 | 17 |
{reprex}や{modelr}などは使いこなしていないですが、tidyverseパッケージであるのは読んでおりました。これらのパッケージは知っておくと、今後も役に立つかもしれませんね。
ですが、恥ずかしながらこちらの{bindrcpp}はまったく知りませんでした。少し調べてみるとこちらはtidyverseパッケージではなく、{dplyr}を支えているRcppを書くのを手助けするパッケージのようですね。
このように誰かが作ったパッケージを新しく知れるのも、なかなか楽しいと思います。
引き続き、上位のパッケージを見ていきましょう。
# ただし、先ほど確認したコミュニティでのTop1は除く
tidyvese_graph_pgr %>%
dplyr::top_n(n = 15, wt = pg) %>%
dplyr::group_by(community) %>%
dplyr::filter(max(pg) != pg) %>%
knitr::kable(format = "markdown")
name | community | pg | pg_order |
---|---|---|---|
rmarkdown | 1 | 0.0437352 | 4 |
scales | 2 | 0.0299618 | 7 |
dplyr | 3 | 0.0260143 | 8 |
tidyr | 3 | 0.0212359 | 9 |
knitr | 1 | 0.0206302 | 10 |
dbplyr | 3 | 0.0181432 | 12 |
psych | 7 | 0.0173873 | 13 |
httr | 5 | 0.0166775 | 14 |
readxl | 6 | 0.0129946 | 15 |
比較的よく目にする機会が多いパッケージが並んでいますね。
しいて馴染みがないパッケージを挙げるなら{psych}でしょうか。多様な因子分析をサポートするパッケージで、{broom}がこちらをImportしていますね。
このように{tidygraph}を用いるとグラフを手軽に扱えるようですが、可視化のときもそうでしたが途中でデータフレームに変換しないとうまく動作していません。このあたりがシームレスにいけると使い勝手がいいですね。
tidyvese_graph %>%
tidygraph::activate(nodes) %>%
dplyr::mutate(pg = tidygraph::centrality_pagerank(damping = 0.85)) %>%
# tibble::as_data_frame() %>%
dplyr::group_by(community) %>%
dplyr::arrange(community, dplyr::desc(x = pg)) %>%
dplyr::top_n(n = 3, wt = pg)
# A tbl_graph: 22 nodes and 27 edges
#
# A directed acyclic multigraph with 2 components
#
# Node Data: 77 x 3 (active)
# Groups: community [7]
name community pg
* <chr> <fctr> <dbl>
1 reprex 1 0.062488188
2 rmarkdown 1 0.043735188
3 knitr 1 0.020630189
4 caTools 1 0.008622276
5 htmltools 1 0.006264189
6 clipr 1 0.004660690
# ... with 71 more rows
#
# Edge Data: 27 x 3
from to type
<int> <int> <chr>
1 14 11 Imports
2 14 11 LinkingTo
3 11 13 Imports
# ... with 24 more rows
紹介の記事であったように、{ggraph}で可視化してみる。
tidyvese_graph %>%
ggraph::ggraph(layout = "kk") +
ggraph::geom_edge_link() +
ggraph::geom_node_point(mapping = ggplot2::aes(colour = community, group = community)) +
ggraph::geom_node_text(mapping = ggplot2::aes(label = name), colour = "black", vjust = 0.4) +
ggraph::theme_graph()
なるほど、こちらの可視化はもう少しこなれる必要がありそうです。
まとめ
以前のRcppで行なった処理を流用して、tidyverse「を」支えるパッケージ群を可視化しました。敬虔なRユーザーの方々はtidyverseへの感謝の念が増したと思いますので、tidyポエム Advent Calendarに参加する気持ちが高まったことでしょう。まだ空きがあるようですので、一枠いかがでしょうか。
また、{tidygraph}を利用することでデータ取得からコミュニティ抽出まで流れるようにでき、ネットワーク指標を適用もスムーズにできました。
ただ、{tidygraph}のオブジェクトの扱いが癖があり、そのままでは型が違うと怒られるので、データフレームに変換して後続の可視化まで繋いでいます。
この辺りがそのままできるとますます使い勝手が良くなっていいですね。
なお、MRAN(Microsoft R Application Network)で、パッケージのDependencies Graphは可視化されていたりもしますが、このように依存パッケージが多くなると視認性が悪いのが難点ですね。
https://mran.microsoft.com/package/tidyverse

参考ページなど
実行環境
> devtools::session_info()
Session info ------------------------------------------------------------------------------------------------
setting value
version R version 3.4.2 (2017-09-28)
system x86_64, darwin15.6.0
ui RStudio (1.1.383)
language (EN)
collate ja_JP.UTF-8
tz <NA>
date 2017-11-21
Packages ----------------------------------------------------------------------------------------------------
package * version date source
assertthat 0.2.0 2017-04-11 CRAN (R 3.4.2)
base * 3.4.2 2017-10-20 local
bindr 0.1 2016-11-13 CRAN (R 3.4.2)
bindrcpp * 0.2 2017-06-17 CRAN (R 3.4.2)
broom 0.4.2 2017-02-13 CRAN (R 3.4.2)
cellranger 1.1.0 2016-07-27 CRAN (R 3.4.2)
cli 1.0.0 2017-11-05 CRAN (R 3.4.2)
colorspace 1.3-2 2016-12-14 CRAN (R 3.4.2)
compiler 3.4.2 2017-10-20 local
concaveman 1.0.0 2017-07-25 cran (@1.0.0)
crayon 1.3.4 2017-09-16 cran (@1.3.4)
datasets * 3.4.2 2017-10-20 local
deldir 0.1-14 2017-04-22 CRAN (R 3.4.2)
devtools 1.13.3 2017-08-02 CRAN (R 3.4.2)
digest 0.6.12 2017-01-27 CRAN (R 3.4.2)
dplyr * 0.7.4 2017-09-28 CRAN (R 3.4.2)
forcats * 0.2.0 2017-01-23 CRAN (R 3.4.2)
foreign 0.8-69 2017-06-22 CRAN (R 3.4.2)
ggforce 0.1.1 2017-10-28 Github (thomasp85/ggforce@045c762)
ggplot2 * 2.2.1.9000 2017-10-28 Github (tidyverse/ggplot2@ffb40f3)
ggraph 1.0.0 2017-10-28 Github (thomasp85/ggraph@9d50611)
ggrepel 0.7.0 2017-09-29 CRAN (R 3.4.2)
glue 1.1.1 2017-06-21 CRAN (R 3.4.2)
graphics * 3.4.2 2017-10-20 local
grDevices * 3.4.2 2017-10-20 local
grid 3.4.2 2017-10-20 local
gridExtra 2.3 2017-09-09 cran (@2.3)
gtable 0.2.0 2016-02-26 CRAN (R 3.4.2)
haven 1.1.0 2017-07-09 CRAN (R 3.4.2)
hms 0.3 2016-11-22 CRAN (R 3.4.2)
htmltools 0.3.6 2017-04-28 cran (@0.3.6)
htmlwidgets 0.9 2017-07-10 cran (@0.9)
httr 1.3.1 2017-08-20 CRAN (R 3.4.2)
igraph 1.1.2 2017-07-21 CRAN (R 3.4.2)
jsonlite 1.5 2017-06-01 CRAN (R 3.4.2)
labeling 0.3 2014-08-23 CRAN (R 3.4.2)
lattice 0.20-35 2017-03-25 CRAN (R 3.4.2)
lazyeval 0.2.0 2016-06-12 CRAN (R 3.4.2)
lubridate 1.7.1 2017-11-03 CRAN (R 3.4.2)
magrittr 1.5 2014-11-22 CRAN (R 3.4.2)
MASS 7.3-47 2017-02-26 CRAN (R 3.4.2)
memoise 1.1.0 2017-04-21 CRAN (R 3.4.2)
methods * 3.4.2 2017-10-20 local
miniCRAN * 0.2.10 2017-10-22 CRAN (R 3.4.2)
mnormt 1.5-5 2016-10-15 CRAN (R 3.4.2)
modelr 0.1.1 2017-07-24 CRAN (R 3.4.2)
munsell 0.4.3 2016-02-13 CRAN (R 3.4.2)
nlme 3.1-131 2017-02-06 CRAN (R 3.4.2)
pacman 0.4.6 2017-05-14 CRAN (R 3.4.2)
parallel 3.4.2 2017-10-20 local
pkgconfig 2.0.1 2017-03-21 CRAN (R 3.4.2)
plyr 1.8.4 2016-06-08 CRAN (R 3.4.2)
polyclip 1.6-1 2017-03-22 CRAN (R 3.4.2)
psych 1.7.8 2017-09-09 CRAN (R 3.4.2)
purrr * 0.2.4 2017-10-18 CRAN (R 3.4.2)
R6 2.2.2 2017-06-17 CRAN (R 3.4.2)
Rcpp 0.12.13 2017-09-28 CRAN (R 3.4.2)
readr * 1.1.1 2017-05-16 CRAN (R 3.4.2)
readxl 1.0.0 2017-04-18 CRAN (R 3.4.2)
reshape2 1.4.2 2016-10-22 CRAN (R 3.4.2)
RevoUtils * 10.0.6 2017-10-17 local
rlang 0.1.4 2017-11-05 CRAN (R 3.4.2)
rstudioapi 0.7 2017-09-07 CRAN (R 3.4.2)
rvest 0.3.2 2016-06-17 CRAN (R 3.4.2)
scales 0.5.0.9000 2017-10-28 Github (hadley/scales@d767915)
stats * 3.4.2 2017-10-20 local
stringi 1.1.5 2017-04-07 CRAN (R 3.4.2)
stringr * 1.2.0 2017-02-18 CRAN (R 3.4.2)
tibble * 1.3.4 2017-08-22 CRAN (R 3.4.2)
tidygraph * 1.0.0 2017-07-07 CRAN (R 3.4.2)
tidyr * 0.7.2 2017-10-16 CRAN (R 3.4.2)
tidyverse * 1.2.1 2017-11-14 CRAN (R 3.4.2)
tools 3.4.2 2017-10-20 local
tweenr 0.1.5 2016-10-10 cran (@0.1.5)
udunits2 0.13 2016-11-17 CRAN (R 3.4.2)
units 0.4-6 2017-08-27 CRAN (R 3.4.2)
utils * 3.4.2 2017-10-20 local
viridis 0.4.0 2017-03-27 CRAN (R 3.4.2)
viridisLite 0.2.0 2017-03-24 CRAN (R 3.4.2)
visNetwork * 2.0.1 2017-07-30 CRAN (R 3.4.2)
withr 2.0.0 2017-10-28 Github (jimhester/withr@a43df66)
XML 3.98-1.9 2017-06-19 CRAN (R 3.4.2)
xml2 1.1.1 2017-01-24 CRAN (R 3.4.2)
yaml 2.1.14 2016-11-12 cran (@2.1.14)