マナティ

Rではじめよう![モダン]なデータ分析

Rパッケージのダウンロードランキングを作る

ビッグデータやデータサイエンティストのブームに乗り注目されている「R言語」。8000以上の登録があるRの拡張パッケージがどのぐらいダウンロードされているのかを調査してみます。

54417_ext_14_0.jpg

はじめに

近年、ビッグデータやデータサイエンティストのブームに乗り、「R言語」が注目されています。

R言語はニュージーランドのオークランド大学のRoss IhakaとRobert Clifford Gentlemanにより作られた、R Development Core teamによりメンテナンスと拡張がなされています。 R自体は無料で配布され、ユーザー数は大きく伸びており、SASやSPSSなどの従来の有償ソフトウェアに迫る勢いです。

Rの大きな特徴として、「パッケージ」による拡張が上げられます。 パッケージとは、ユーザー自身が関数(Function)を作成し、CRAN(Comprehensve R Archive Network) に公開することで、世界中のRユーザーに使ってもらうことができます。 現在このパッケージ数は8,000以上に上り、世界中のRユーザーに広く利用されています。 パッケージ数は以下のRプログラムにて確認することができます。

また、別のパッケージレポジトリとして、Githubも利用されつつあり、こちらのに登録されているパッケージ数を含めるとより多くのパッケージが公開されています。

# CRANに登録されている最新パッケージ数を取得
paste0(Sys.Date() , "時点")
 
## [1] "2016-05-28時点"
 
nrow(available.packages())
 
## [1] 8441

今回の目的は、このCRANに登録されているパッケージがどのぐらいダウンロードされているのかを調査します。

1. 今回のゴール

今回のゴールは、パッケージのダウンロード調査です。どのパッケージがどのぐらいダウンロードされているかを可視化することによって、Rでどのようなパッケージが流行しているのかが見えてきます。

また、今回利用するデータには、国別のコードも付与されているため、各国でどのパッケージがダウンロードされているのかが合わせてわかります。国別のダウンロードランキングを見ることで、各国のRの使い方の特色がみられるかもしれません。

つまり、今回作りたいアウトプットとしては、

1. 総パッケージダウンロード数ランキング
2. 国別パッケージダウンロード数ランキング

の2点を可視化していきます。

2. 手順

大まかな手順としては、以下のステップに則って、進めていきます。

3. データソース

今回利用するデータソースは、CRANが公開しているパッケージダウンロードサイトを利用します。

ここでは、毎日のパッケージダウンロード数と、Rのダウンロード数が公開されています。一番古いデータで2012年10から存在しています。また、デイリーで更新されているため、毎日追うことができます。 今回は 「Daily package downloads」の項目を使いましょう。

データダウンロード

幸いなことに、パッケージ数のダウンロード方法も公開してあります。「Downloading from R」を見てみると、以下のようなコードが公開されています。 (ファイルダウンロード、内容確認の部分は追記しています)

  # ほしい期間のデータのはじめと終わりを指定
  start <- as.Date('2016-05-01')
  today <- as.Date('2016-05-01')

  all_days <- seq(start, today, by = 'day')

  # ダウンロードしたい日付のURLを生成
  year <- as.POSIXlt(all_days)$year + 1900
  urls <- paste0('http://cran-logs.rstudio.com/', year, '/', all_days, '.csv.gz')
  # download.fileを使って、ファイルをダウンロード
  download.file(urls, "/Users/user/Desktop/testdl_cranpackage.tsv")
  
  # 持っていないデータがある場合、以下を実行してみてください。
  missing_days <- setdiff(all_days, tools::file_path_sans_ext(dir(), TRUE))
 
  # ファイルインポート
  check_file <- read.csv("/Users/user/Desktop/testdl_cranpackage.tsv")
  # 10列 29万行のデータ
  dim(check_file)
 
## [1] 292464     10
 
  # 先頭10行のデータを取得
  head(check_file)
 
##         date     time    size r_version r_arch    r_os    package  version
## 1 2016-05-01 14:48:19   36521     3.2.4 x86_64 mingw32     bitops    1.0-6
## 2 2016-05-01 14:48:22 4299738     3.2.4 x86_64 mingw32        XML 3.98-1.4
## 3 2016-05-01 14:48:22  123143              stringdist  0.9.4.1
## 4 2016-05-01 14:48:21   31760     3.2.3 x86_64 mingw32    Metrics    0.1.1
## 5 2016-05-01 14:48:24  112286                 packrat  0.4.7-1
## 6 2016-05-01 14:48:15  257109                 foreign   0.8-66
##   country ip_id
## 1      US     1
## 2      US     1
## 3      NL     2
## 4      GB     3
## 5      US     4
## 6      ID     5

1日分で10列 × 29万行、ファイルサイズ4MBとなりました。 これを1ヶ月分取得しようとすると、

# 行数
  formatC(nrow(check_file) * 30 , format="d" , big.mark = ',') 
 
## [1] "8,773,920"
 
# ファイルサイズ(MB)(4MBを30日分)
  4 * 30
 
## [1] 120

となり、とても大きなファイルサイズになりそうです。 最近のPCではメモリを多く積んでいるため、メモリで制約をうけるRではあまり影響はなさそうですが、 集計値など、複数のオブジェクトを利用する場合もあるため、扱うデータサイズを小さくしていくことも必要です。

そこで、長期間データを取得する際には、集計値、項目を減らし、扱うデータを小さくしていきます。 また、一日ずつダウンロードしていくのも非効率なため、for文を使って期間分のファイルをダウンロードするようにします。

4. 加工

1ヶ月分のデータを取得すると、とても大きなサイズになるため、データをためていく段階で加工も一緒に行います。 データ加工にはdplyrパッケージを利用します。

install.packages("dplyr")
 
## 
## The downloaded binary packages are in
## 	/var/folders/p6/mc4kcw3120b0s1khmp5g31x40000gn/T//Rtmpi0pNzl/downloaded_packages
 
library(dplyr)
 
## 
## Attaching package: 'dplyr'
 
##  以下のオブジェクトは 'package:stats' からマスクされています: 
## 
##      filter, lag
 
##  以下のオブジェクトは 'package:base' からマスクされています: 
## 
##      intersect, setdiff, setequal, union

項目は以下に絞り、これらの件数をダウンロード数としてカウントします。

  • date (日付 UTC)
  • r_arch (アーキテクチャ)
  • r_os (OS)
  • package (パッケージ名)
  • country (国名 ISO country codeに準拠)
  • パッケージダウンロード数(カウント)
# ダウンロードしたい期間を指定
start <- as.Date('2016-04-01')
today <- as.Date('2016-04-30')

all_days <- seq(start, today, by = 'day')

year <- as.POSIXlt(all_days)$year + 1900
urls <- paste0('http://cran-logs.rstudio.com/', year, '/', all_days, '.csv.gz')

# データを加工&まとめる
for(i in 1:length(urls)){
  tmp <- tempfile()
  download.file(urls[[i]], tmp)
  d <- read.csv(gzfile(tmp) , as.is = TRUE)
  d <- d %>% group_by(date  , r_arch , r_os , package  , country) %>% summarise(dlc_cnt = n()) 
  if (i == 1){dd <- d} else {dd <- rbind(dd , d)}
  rm(tmp)
  rm(d)
}

# 集計したデータ
glimpse(dd)
 
## Observations: 3,408,577
## Variables: 6
## $ date    (chr) "2016-04-01", "2016-04-01", "2016-04-01", "2016-04-01"...
## $ r_arch  (chr) "arm", "arm", "arm", "arm", "armv7l", "armv7l", "i386"...
## $ r_os    (chr) "linux-gnueabihf", "linux-gnueabihf", "linux-gnueabihf...
## $ package (chr) "ENiRG", "gtable", "lazyeval", "rstudioapi", "R.utils"...
## $ country (chr) "IN", "VN", "AU", "BY", "CA", "DE", "US", "US", "IN", ...
## $ dlc_cnt (int) 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...

6列、行数340万行のデータセットが完成しました。 これを元に集計をして、結果をまとめていきます。

5. ランキング作成

まずは、全体感を見てましょう。

4月の合計ダウンロード数は以下です。

# パッケージ種類
nrow(table(dd$package))
 
## [1] 9250
 
# ダウンロード回数
formatC(sum(dd$dlc_cnt) , format="d" , big.mark = ',')
 
## [1] "15,034,673"

9,250種類のパッケージが、1,500万回ダウンロードされています。 (現在はCRANでは公開されていないが、アーカイブからダウンロードされていると考えられます)

次に、2016年4月の日別の時系列データをチャート化してみましょう。 チャートはggplot2を利用します。

install.packages("ggplot2")
 
## 
## The downloaded binary packages are in
## 	/var/folders/p6/mc4kcw3120b0s1khmp5g31x40000gn/T//Rtmpi0pNzl/downloaded_packages
 
library(ggplot2)
 
## Warning: package 'ggplot2' was built under R version 3.2.4
 
# 日別にダウンロード数を集計
ts_dd <- dd %>% group_by(date) %>% summarise(cnt_dld = sum(dlc_cnt))
# 集計データの確認
glimpse(ts_dd)
 
## Observations: 30
## Variables: 2
## $ date    (chr) "2016-04-01", "2016-04-02", "2016-04-03", "2016-04-04"...
## $ cnt_dld (int) 539464, 307276, 293286, 525255, 608913, 609408, 609535...
 
# 日別棒グラフ
ggplot(ts_dd , aes(as.Date(date) , cnt_dld/10000)) + geom_bar(stat = "identity") + scale_x_date(date_labels = "%b %d")

chunk-10-1.png

ダウンロード数はおおよそ30~60万ほどの間で日毎に波があり、周期的に動いていそうです。 ちなみに日付はUTCで記録されていることもあり、日本時間(JST)ではないことをご注意ください。

それでは続いて、当初の目的であるランキングの作成に移りましょう。

rank_dd <- dd %>% group_by(package) %>% summarise(dlc_packages = sum(dlc_cnt)) %>% 
  mutate(rank = dense_rank(desc(dlc_packages)) , share = dlc_packages / sum(dd$dlc_cnt)) %>% 
  arrange(rank) %>% 
  select(rank , package , dlc_packages , share)
head(rank_dd , 10)
 
## Source: local data frame [10 x 4]
## 
##     rank       package dlc_packages       share
##    (int)         (chr)        (int)       (dbl)
## 1      1 RcppArmadillo       353992 0.023545042
## 2      2          Rcpp       254575 0.016932527
## 3      3       ggplot2       219765 0.014617212
## 4      4        digest       179117 0.011913595
## 5      5       stringr       171733 0.011422463
## 6      6          plyr       170953 0.011370583
## 7      7       stringi       170182 0.011319302
## 8      8        scales       167722 0.011155680
## 9      9      magrittr       159638 0.010617989
## 10    10        gtable       150171 0.009988312

C++が扱える、RcppArmadillo / Rcpp、チャート作成のggplot2、暗号化したデータを作成できるdigest、stringiのラッパーで文字列を扱えるstringr がランクインしています。個人的にはdplyrよりも、plyrが上位に入っていることに驚きました。

さて、続いて国別のランキング作成を行ってみましょう。 まず、Rのパッケージがダウンロードされている国の数をみてみましょう。

length(table(dd$country))
 
## [1] 212

ISO Country Codeで定義されている国・地域の数が249なので、実に85%の国と地域で利用されています。

では、各国のパッケージダウンロード数を見て行きましょう。 すべての国を見るのはとても大変なので、主要国とR言語の発祥の地、ニュージーランドを見てみましょう。

rank_dd_by_cntry <- dd %>% group_by(country , package) %>% summarise(dlc_packages = sum(dlc_cnt)) %>% 
  mutate(rank = dense_rank(desc(dlc_packages))) %>% 
  arrange(country , rank) %>% 
  select(country , rank , package , dlc_packages)
 
# 日本 TOP10 
rank_dd_by_cntry %>% filter(country == "JP") %>% head(10)
 
## Source: local data frame [10 x 4]
## Groups: country [1]
## 
##    country  rank  package dlc_packages
##      (chr) (int)    (chr)        (int)
## 1       JP     1     Rcpp         4871
## 2       JP     2  ggplot2         4393
## 3       JP     3   digest         3732
## 4       JP     4   scales         3511
## 5       JP     5  stringr         3361
## 6       JP     6  stringi         3302
## 7       JP     7 magrittr         3183
## 8       JP     8   gtable         3092
## 9       JP     9     plyr         3074
## 10      JP    10  munsell         3059
 
# アメリカ
rank_dd_by_cntry %>% filter(country == "US") %>% head(10)
 
## Source: local data frame [10 x 4]
## Groups: country [1]
## 
##    country  rank  package dlc_packages
##      (chr) (int)    (chr)        (int)
## 1       US     1     Rcpp        95024
## 2       US     2  ggplot2        82262
## 3       US     3   digest        67295
## 4       US     4     plyr        66736
## 5       US     5   scales        63274
## 6       US     6  stringr        62537
## 7       US     7  stringi        60882
## 8       US     8 magrittr        59034
## 9       US     9   gtable        56739
## 10      US    10  munsell        55938
 
# ニュージーランド
rank_dd_by_cntry %>% filter(country == "NZ") %>% head(10)
 
## Source: local data frame [10 x 4]
## Groups: country [1]
## 
##    country  rank   package dlc_packages
##      (chr) (int)     (chr)        (int)
## 1       NZ     1      Rcpp         1225
## 2       NZ     2   ggplot2          922
## 3       NZ     3    digest          775
## 4       NZ     4   stringr          716
## 5       NZ     5   stringi          712
## 6       NZ     6      plyr          711
## 7       NZ     7  magrittr          673
## 8       NZ     8    scales          581
## 9       NZ     9 htmltools          569
## 10      NZ    10     knitr          563

6. 結果

世界中でよく利用されているパッケージは、C++が利用できるパッケージ、チャート作成ができるggplot2、暗号化や文字列処理ができるdigest、stringrなどでした。

また、各国別では上位は全体傾向とほとんど変わらないものの、TOP5以降ではそれぞれ各国で異なるパッケージがダウンロードされているようです。

まとめ

今回は、RStudioのCRANミラーサーバーをのダウンロードログを使い、パッケージ数のランキングを作成してみました。 世界的には2016年4月はC++が利用できるパッケージや、ggplot2、暗号化、文字列処理ができるパッケージが上位に入っていることがわかりました。

使っているパッケージは以下です。

  • dplyr
  • ggplot2
  • knitr (この文章はknitrを使って作成しました)

7. 参考文献、引用資料

著者プロフィール

簑田高志(著者)
ヤフー株式会社に所属。インターネット業界で十年以上に渡りネット広告関連の企画・分析業務に携わる。最近ではEコマース関連の分析に軸足を移し、広告・CRM・サイト分析など事業を幅広くカバーする業務を行う。