Rパッケージ群をもっとも支えるパッケージ

  • 14
    Like
  • 0
    Comment
More than 1 year has passed since last update.

概要

 週末用のLT資料を作成中に「Rパッケージで最も多く他から参照されているパッケージ」が気になったので、Rのリハビリを兼ねて確認に用いたコードをメモとして残します。
 (公開後に追記しました)

定数定義部
# 読み込むパッケージ
SET_LOAD_PACKAGE <- c("dplyr", "miniCRAN", "iterators", "pforeach", "tools", "knitr")

# パッケージリストを用いるCRANリポジトリ
# 再現性を持たせるため、スナップショットを指定
SET_PACKAGE_REPOSITRY <- "https://mran.revolutionanalytics.com/snapshot/2016-08-13/"

# パッケージ数を求める依存関係の種類
SET_DEP_TYPE <- c("Depends", "Imports", "LinkingTo", "Suggests", "Enhances")

# 並列処理用定数
SET_SPLIT_CHUNKSIZE <- 5
SET_PARALLEL_N <- 3
関数定義部
# 依存パッケージ数の算出用関数
# @param pkgs 依存関係を求めるパッケージ群
# @param type, pdb, recursive tools::package_dependenciesの引数を参照
dependsOnPkgsLen <- function (pkgs, type, pdb, recursive = TRUE, fun = length) {
  return(
    sapply(
      X = tools::package_dependencies(
        packages = pkgs, db = pdb, which = type, 
        recursive = recursive, reverse = TRUE         
      ),
      FUN = fun
    )
  )
}
メイン処理
# 今回使用するパッケージを読み込み
pacman::p_load(char = SET_LOAD_PACKAGE, install = FALSE, character.only = TRUE)

# CRANパッケージリストを取得
pdb <- miniCRAN::pkgAvail(repos = c(CRAN = SET_PACKAGE_REPOSITRY))


# 引数chunksizeが使うためにmatrixに変換
pkgs_iter <- iterators::iter(
  obj = as.matrix(x = rownames(x = pdb)), by = "row",
  chunksize = SET_SPLIT_CHUNKSIZE
)

# 並列処理
depends_reverse_count <- pforeach::pforeach(
  pkgs_m = pkgs_iter, .c = "rbind", .parallel = TRUE, .cores = SET_PARALLEL_N, 
  .export = c("SET_DEP_TYPE", "dependsOnPkgsLen", "pdb"), .packages = SET_LOAD_PACKAGE
) ({
  pkgs <- pkgs_m[, 1]

  dplyr::bind_cols(
    dplyr::data_frame(pkgs),
    dplyr::bind_rows(
      setNames(
        object = lapply(X = SET_DEP_TYPE, FUN = dependsOnPkgsLen, pkgs = pkgs, pdb = pdb),
        nm = SET_DEP_TYPE
      )
    )
  )

})
結果表示用
# 合計数のTOP100を表示
dplyr::bind_cols(
  depends_reverse_count,
  dplyr::data_frame(
    Dependency = depends_reverse_count %>%
      dplyr::select(-pkgs) %>% 
      rowSums
  )
) %>% 
  dplyr::arrange(dplyr::desc(x = Dependency)) %>% 
  dplyr::top_n(n = 100, wt = Dependency) %>% 
  knitr::kable(format = "markdown")
pkgs Depends Imports LinkingTo Suggests Enhances Dependency
Rcpp 165 1886 725 3138 0 5914
MASS 586 1264 0 3138 4 4992
lattice 327 1419 0 3138 0 4884
Matrix 419 855 4 3138 8 4424
magrittr 11 1186 0 3138 1 4336
stringi 4 1066 0 3141 0 4211
stringr 44 1020 0 3138 0 4202
plyr 61 995 0 3138 0 4194
digest 16 950 2 3138 0 4106
ggplot2 285 636 0 3138 3 4062
RColorBrewer 54 770 0 3144 4 3972
colorspace 21 757 0 3138 1 3917
reshape2 20 741 0 3138 0 3899
scales 7 694 0 3138 0 3839
dichromat 1 695 0 3138 0 3834
R6 1 663 0 3138 0 3802
mvtnorm 238 311 1 3166 0 3716
jsonlite 9 557 0 3138 0 3704
survival 325 199 0 3157 3 3684
foreach 128 401 0 3138 0 3667
codetools 2 498 0 3139 0 3639
nlme 158 322 0 3138 4 3622
iterators 46 415 0 3138 0 3599
DBI 40 368 0 3138 1 3547
sp 196 199 2 3138 9 3544
zoo 124 277 0 3138 4 3543
XML 59 216 0 3226 0 3501
dplyr 29 318 1 3138 2 3488
curl 1 346 0 3138 0 3485
doParallel 25 309 0 3138 2 3474
httr 26 294 0 3138 0 3458
mgcv 52 253 0 3138 12 3455
nnet 21 288 0 3138 2 3449
cluster 54 251 0 3138 3 3446
chron 19 285 0 3138 2 3444
coda 107 190 0 3146 0 3443
data.table 34 268 0 3138 2 3442
igraph 97 206 0 3138 0 3441
bitops 62 150 0 3226 0 3438
RCurl 54 139 0 3226 0 3419
gtools 44 203 0 3140 0 3387
rpart 53 176 0 3138 12 3379
xtable 40 193 0 3138 3 3374
quantreg 41 189 0 3138 2 3370
boot 76 148 0 3138 0 3362
gridExtra 14 204 0 3138 0 3356
numDeriv 46 163 0 3147 0 3356
htmltools 3 214 0 3138 0 3355
gridBase 2 213 0 3138 0 3353
abind 54 159 0 3139 0 3352
foreign 20 182 0 3141 0 3343
MatrixModels 0 191 0 3138 9 3338
yaml 2 192 0 3138 0 3332
sandwich 60 130 0 3138 0 3328
car 68 106 0 3138 4 3316
shiny 25 135 0 3138 11 3309
gdata 29 135 0 3143 0 3307
ape 85 78 0 3138 1 3302
mnormt 18 136 0 3142 0 3296
class 23 129 0 3139 0 3291
httpuv 2 150 0 3139 0 3291
rgl 74 77 0 3138 0 3289
Hmisc 46 101 0 3138 0 3285
raster 55 90 0 3138 1 3284
latticeExtra 13 129 0 3138 0 3280
Formula 85 51 0 3138 0 3274
rJava 73 57 0 3143 0 3273
KernSmooth 23 108 0 3138 0 3269
fields 39 79 0 3143 0 3261
lme4 45 67 0 3138 5 3255
e1071 26 89 0 3138 0 3253
knitr 12 97 0 3138 5 3252
robustbase 49 62 0 3138 3 3252
gplots 47 66 0 3138 0 3251
markdown 2 111 0 3138 0 3251
pbkrtest 0 111 0 3138 0 3249
glmnet 47 55 0 3138 2 3242
reshape 19 81 0 3139 2 3241
rgdal 25 62 0 3152 2 3241
maps 77 23 0 3138 2 3240
minqa 1 97 0 3139 0 3237
evaluate 0 98 0 3138 0 3236
multcomp 11 85 0 3138 0 3234
nloptr 8 84 0 3138 0 3230
xts 24 63 2 3138 1 3228
png 5 74 0 3145 3 3227
RUnit 12 4 0 3203 6 3225
lubridate 10 75 0 3138 0 3223
base64enc 2 82 0 3138 0 3222
BH 0 0 84 3138 0 3222
SparseM 61 13 0 3139 9 3222
deldir 11 69 0 3139 0 3219
scatterplot3d 11 59 0 3148 0 3218
htmlwidgets 0 78 0 3138 1 3217
expm 2 75 0 3138 0 3215
maptools 29 46 0 3138 1 3214
sfsmisc 38 29 0 3138 9 3214
randomForest 22 53 0 3138 0 3213
RcppEigen 1 2 72 3138 0 3213
xml2 3 70 0 3138 0 3211

まとめ

 今回の調査方法では、MRANの2016-08-13のスナップショットにあるCRANパッケージ(合計8952)のうち、{Rcpp}が「Rパッケージで最も多く他から参照されているパッケージ」でした。
 ただし、tools::package_dependenciesの引数 recursive をTRUEにしているため、被参照数の多いパッケージが依存していると依存関係の数が大きくなります(それらを含めた支えるパッケージが知りたかったので、TRUEを指定しております)。
 また、今回は対象をCRANのみに限定しており、GitHubは含んでおりません。GitHubにしか上げられていないパッケージも数多くあり、それらのパッケージ依存を加えると順位が大幅に変わるかもしません。

 {Rcpp}に限定して、依存パッケージの中で代表的なパッケージをネットワーク分析で抽出する試みもしました。興味がある方はご覧ください。
  {Rcpp}が支える代表的なパッケージの抽出


追記

 ツイッターのタイムラインで「Suggestsの値が3138前後に集まるのはなぜか」と疑問になられた方がおり、「{testthat}にだいたい行き着くのではないか」と違う方が返答をしていらっしゃったので確認してみました。
 その結果が次の表です。作成は今回定義したdependsOnPkgsLenの引数 recursive をFALSEにして再実行するだけです(指定したCRANリポジトリが同じなら、CRANにあるパッケージのページに記載がある数値と同じになるかと)。
 Suggestsの値が大きい{testthat}, {knitr}, {ggplot2}, {rmarkdown}を単純に足すと3299(1300 + 1215 + 268 + 516)になるので、これらのパッケージをSuggestsしているとこのような結果になるのではないでしょうか(パッケージ間の重複を除けば近い数値になりそうでです)。

pkgs Depends Imports LinkingTo Suggests Enhances Dependency
Rcpp 129 571 718 9 0 1427
testthat 6 12 1 1300 1 1320
knitr 11 54 0 1215 5 1285
MASS 411 459 0 337 4 1211
ggplot2 202 405 0 268 2 877
rmarkdown 2 29 0 516 1 548
Matrix 222 240 4 62 6 534
lattice 185 162 0 171 0 518
plyr 55 344 0 56 0 455
mvtnorm 176 174 1 83 0 434
survival 208 108 0 102 3 421
dplyr 25 234 1 78 2 340
sp 113 151 2 48 6 320
stringr 37 227 0 18 0 282
reshape2 18 207 0 54 0 279
httr 25 227 0 13 0 265
igraph 89 132 0 43 0 264
RcppArmadillo 6 5 247 5 0 263
foreach 62 155 0 41 0 258
XML 51 147 0 54 0 252
jsonlite 9 211 0 18 0 238
rgl 66 70 0 85 0 221
shiny 25 111 0 64 10 210
RColorBrewer 35 110 0 57 3 205
coda 67 104 0 30 0 201
nlme 63 74 0 60 4 201
RCurl 53 117 0 24 0 194
boot 59 75 0 52 0 186
zoo 59 84 0 38 3 184
data.table 32 127 0 20 2 181
magrittr 9 129 0 32 1 171
xtable 37 50 0 80 3 170
Hmisc 37 71 0 61 0 169
doParallel 24 104 0 38 2 168
lme4 40 53 0 61 3 157
raster 51 76 0 26 1 154
numDeriv 37 78 0 37 0 152
rgdal 23 56 0 67 2 148
car 37 50 0 57 1 145
mgcv 38 65 0 38 3 144
scales 7 97 0 34 0 138
cluster 38 63 0 33 1 135
RUnit 11 4 0 117 3 135
e1071 24 62 0 47 0 133
gridExtra 13 77 0 43 0 133
fields 37 63 0 27 0 127
maptools 27 37 0 60 1 125
nnet 19 50 0 54 2 125
glmnet 47 49 0 26 2 124
randomForest 21 51 0 50 0 122
digest 9 92 2 13 0 116
rpart 24 35 0 51 3 113
gplots 31 54 0 24 0 109
maps 28 15 0 63 2 108
gtools 38 57 0 11 0 106
rJava 52 39 0 13 0 104
roxygen2 2 4 0 90 0 96
lubridate 10 66 0 16 0 92
tidyr 1 66 0 25 0 92
colorspace 16 48 0 26 1 91
devtools 1 13 0 76 1 91
plotrix 19 48 0 20 0 87
rgeos 12 40 0 31 1 84
Formula 32 41 0 9 0 82
reshape 17 38 0 25 2 82
vegan 31 32 0 17 0 80
covr 0 0 0 79 0 79
DBI 15 49 0 14 1 79
foreign 11 33 0 34 0 78
BH 0 0 74 2 0 76
quantreg 28 27 0 19 2 76
RcppEigen 1 2 71 2 0 76
robustbase 28 31 0 14 3 76
xts 21 31 2 19 1 74
corpcor 37 31 0 5 0 73
gdata 20 31 0 22 0 73
quadprog 22 41 0 10 0 73
KernSmooth 16 26 0 28 0 70
R.rsp 0 1 0 69 0 70
RSQLite 12 24 0 29 1 66
deSolve 33 26 0 6 0 65
mclust 22 20 0 21 2 65
png 5 32 0 24 3 64
RJSONIO 19 38 0 7 0 64
rjson 17 39 0 7 0 63
scatterplot3d 8 22 0 32 0 62
lazyeval 1 60 0 0 0 61
psych 19 35 0 7 0 61
lmtest 13 19 0 26 2 60
multcomp 10 19 0 29 0 58
network 27 17 1 13 0 58
spatstat 22 26 0 9 1 58
xml2 2 43 0 13 0 58
mnormt 18 34 0 5 0 57
VGAM 13 24 0 20 0 57
iterators 16 34 0 6 0 56
sandwich 15 25 0 16 0 56
stringi 1 43 0 12 0 56
htmltools 2 38 0 15 0 55
R.utils 10 39 0 5 0 54
spdep 12 20 0 19 3 54

注意

 今回の方法は依存関係間の重複は除外していません。そのため、例えばDependsとImportsで同じパッケージがあっても足しあわせた合計数では両方ともカウントアップされてしまい、多めの数値が出てきてしまいます。
 これに加えてtools::package_dependenciesの引数 recursive をTRUEにし、引数 which に"Depends"した場合は、再起で辿られる依存関係はDependsのもののみになります。
 すべての依存関係を辿りたい場合は、tools::package_dependenciesの引数 which に"all"を指定するばよさそうですが、これを実行するとほとんどのパッケージで差が出なくなります。
 下記に記載しているように、DependsとImportsに限定し、重複を除いて集計(data.table::uniqueNを使用)するのがよさげな結果になりそうです。

 参考にする際には以上のことをくれぐれもご留意ください。

DependsとImportsに限定
pkgs_iter <- iterators::iter(
  obj = as.matrix(x = rownames(x = pdb)), by = "row",
  chunksize = SET_SPLIT_CHUNKSIZE
)

depends_reverse_count <- pforeach::pforeach(
  pkgs_m = pkgs_iter, .c = "rbind", .parallel = TRUE, .cores = SET_PARALLEL_N, 
  .export = c("SET_DEP_TYPE", "dependsOnPkgsLen", "pdb"), .packages = SET_LOAD_PACKAGE
) ({
  pkgs <- pkgs_m[, 1]

  dep_pkgs_count <- dependsOnPkgsLen(
    pkgs = pkgs, pdb = pdb, type = c("Depends", "Imports"),
    fun = data.table::uniqueN
  )

  dplyr::data_frame(
    pkgs = names(x = dep_pkgs_count),  
    Dependency = dep_pkgs_count
  )
})

depends_reverse_count %>% 
  dplyr::arrange(dplyr::desc(x = Dependency)) %>% 
  dplyr::top_n(n = 100, wt = Dependency) %>% 
  knitr::kable(format = "markdown")
pkgs Dependency
lattice 3047
Rcpp 2763
MASS 2551
Matrix 2119
magrittr 1755
stringi 1628
stringr 1584
plyr 1559
digest 1558
RColorBrewer 1347
colorspace 1333
reshape2 1272
dichromat 1241
labeling 1240
munsell 1240
scales 1239
gtable 1217
ggplot2 1204
nlme 953
codetools 870
survival 815
cluster 812
R6 781
mvtnorm 748
iterators 735
foreach 721
jsonlite 644
xtable 593
mime 592
zoo 586
nnet 582
mgcv 528
chron 486
doParallel 471
bitops 461
DBI 460
sp 457
data.table 451
assertthat 442
SparseM 433
MatrixModels 412
quantreg 410
lazyeval 405
minqa 398
tibble 394
nloptr 392
rpart 392
curl 391
registry 386
gtools 385
coda 382
dplyr 373
foreign 367
lme4 364
pkgmaker 362
rngtools 360
irlba 359
gridExtra 357
gridBase 356
quadprog 355
NMF 349
igraph 345
openssl 341
httr 334
Formula 332
abind 324
boot 316
sandwich 301
XML 297
gdata 287
latticeExtra 274
numDeriv 268
htmltools 267
class 259
pbkrtest 249
KernSmooth 246
car 245
acepack 232
Hmisc 230
caTools 226
yaml 223
RCurl 210
maps 204
mnormt 200
httpuv 194
rgl 193
e1071 180
shiny 175
ape 167
DEoptimR 154
robustbase 153
gplots 151
raster 149
rJava 146
TH.data 138
multcomp 137
spam 136
markdown 134
formatR 124
plotrix 123

実行環境
> devtools::session_info()
Session info -----------------------------------------------------------------------------------
 setting  value                       
 version  R version 3.3.1 (2016-06-21)
 system   x86_64, darwin13.4.0        
 ui       RStudio (0.99.902)          
 language (EN)                        
 collate  ja_JP.UTF-8                 
 tz       Asia/Tokyo                  
 date     2016-08-16                  

Packages ---------------------------------------------------------------------------------------
 package    * version  date       source                            
 assertthat   0.1      2013-12-06 CRAN (R 3.3.1)                    
 chron        2.3-47   2015-06-24 CRAN (R 3.3.1)                    
 codetools    0.2-14   2015-07-15 CRAN (R 3.3.1)                    
 data.table * 1.9.6    2015-09-19 CRAN (R 3.3.1)                    
 DBI          0.4-1    2016-05-08 CRAN (R 3.3.1)                    
 devtools     1.12.0   2016-06-24 CRAN (R 3.3.0)                    
 digest       0.6.9    2016-01-08 CRAN (R 3.3.0)                    
 doParallel   1.0.10   2015-10-14 CRAN (R 3.3.1)                    
 doRNG        1.6      2014-03-07 CRAN (R 3.3.1)                    
 dplyr      * 0.5.0    2016-06-24 CRAN (R 3.3.1)                    
 evaluate     0.9      2016-04-29 CRAN (R 3.3.1)                    
 foreach      1.4.3    2015-10-13 CRAN (R 3.3.1)                    
 highr        0.6      2016-05-09 CRAN (R 3.3.1)                    
 httr         1.2.1    2016-07-03 CRAN (R 3.3.0)                    
 iterators  * 1.0.8    2015-10-13 CRAN (R 3.3.1)                    
 knitr      * 1.13     2016-05-09 CRAN (R 3.3.1)                    
 lazyeval     0.2.0    2016-06-12 CRAN (R 3.3.1)                    
 magrittr     1.5      2014-11-22 CRAN (R 3.3.1)                    
 memoise      1.0.0    2016-01-29 CRAN (R 3.3.0)                    
 miniCRAN   * 0.2.5    2016-04-13 CRAN (R 3.3.1)                    
 pacman       0.4.1    2016-03-30 CRAN (R 3.3.0)                    
 pforeach   * 1.3      2016-08-15 Github (hoxo-m/pforeach@2c44f3b)  
 pkgmaker     0.22     2014-05-14 CRAN (R 3.3.1)                    
 R6           2.1.2    2016-01-26 CRAN (R 3.3.0)                    
 Rcpp         0.12.5   2016-05-14 CRAN (R 3.3.1)                    
 registry     0.3      2015-07-08 CRAN (R 3.3.1)                    
 rngtools     1.2.4    2014-03-06 CRAN (R 3.3.1)                    
 rsconnect    0.4.3    2016-08-13 Github (rstudio/rsconnect@1665cb8)
 rstudioapi   0.6      2016-06-27 CRAN (R 3.3.0)                    
 stringi      1.1.1    2016-05-27 CRAN (R 3.3.1)                    
 stringr      1.0.0    2015-04-30 CRAN (R 3.3.1)                    
 tibble       1.1      2016-07-04 CRAN (R 3.3.1)                    
 withr        1.0.2    2016-06-20 CRAN (R 3.3.0)                    
 XML          3.98-1.4 2016-03-01 CRAN (R 3.3.1)                    
 xtable       1.8-2    2016-02-05 CRAN (R 3.3.1)