一つのコードファイル中での複数パッケージの読み込みを容易にする

  • 15
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

Rの機能を拡張させるパッケージ(ライブラリ)を読み込むにはlibrary()require()といった標準関数を利用するのですが、コード中に利用するパッケージは複数になることがほとんどで、時には何度もlibrary()を実行することになります。

例えば次のようなコードです。

library(foreach)
library(dplyr)
library(ggplot2)
library(DT)

1つのパッケージの読み込みを記述するのに1行を要し、すべてのパッケージを読み込むのに4行使いました。利用するパッケージ数が多くなると面倒な感じです。これ以外の方法としてRでは、セミコロンによる区切りを与えることで複数のコードの実行を記述することができますが、それはそれで見にくいという欠点があります。

そうした場合に便利なのが、{needs}パッケージです。データサイエンティストのコンペティションの1つであるKaggleで利用している方がいたので使い方を調べてみました。

{needs}パッケージ

{needs}パッケージはライブラリの読み込みとインストールを容易に実行できる関数を提供しています。今回利用したバージョンはCRANに登録されている0.0.3(2016年5月25日現在... こっちが最新状態 👉CRAN_Status_Badge)ですが、GitHubから開発版を利用することも可能です。(開発者のJosh KatzさんはThe New York Timesの中の人らしい)

# install.packages("needs")
# devtools::install_github("joshkatz/needs", ref = "development") # 開発版

library(needs)
# Should `needs` load itself when it's... needed?
#   (this is recommended) 
# 
# 1: No
# 2: Yes

パッケージをインストールしてきて最初に{needs}パッケージを読み込むと次のような出力がされます。ここで2とタイプすると、次回以降は、needs()関数を使用することでlibrary()install.package()を使用せずにパッケージの読み込みやインストールが実行可能になります。

関数needs()は、引数に与えたパッケージを環境中に読み込む関数です。この時、インストールされていないパッケージがあれば自動的にインストールされます。次のコードは、冒頭のパッケージ読み込みの結果と同じもので、関数を実行すると4つのパッケージが利用可能な状態になります。

glimpse(iris) # まだパッケージが読み込まれていない状態
# Error: could not find function "glimpse"

needs(foreach, dplyr, ggplot2, DT)

glimpse(iris)
## Observations: 150
## Variables: 5
## $ Sepal.Length (dbl) 5.1, 4.9, 4.7, 4.6, 5.0, 5.4, 4.6, 5.0, 4.4, 4.9,...
## $ Sepal.Width  (dbl) 3.5, 3.0, 3.2, 3.1, 3.6, 3.9, 3.4, 3.4, 2.9, 3.1,...
## $ Petal.Length (dbl) 1.4, 1.4, 1.3, 1.5, 1.4, 1.7, 1.4, 1.5, 1.4, 1.5,...
## $ Petal.Width  (dbl) 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1,...
## $ Species      (fctr) setosa, setosa, setosa, setosa, setosa, setosa, ...

わかりやすいし1行で記述できて楽ですね。

パッケージの優先順位を変更する

R でパッケージの優先順位を変えたい #rstatsj」であげられている問題です。これを解決するための関数が{needs}に用意されていました。

dplyr パッケージの select() を使いたいのに、いつの間にか MASS パッケージが読み込まれてしまい、select() が上書きされたためにエラーになる

問題を再現してみましょう。

needs(dplyr, MASS) # 2つのパッケージを読み込む

iris %>% select(Species) %>% head()
# Error in select(., Species) : unused argument (Species)

パッケージの優先順位を変えるための関数、prioritize()を用います。

prioritize(dplyr)
iris %>% select(Species) %>% head()
##   Species
## 1  setosa
## 2  setosa
## 3  setosa
## 4  setosa
## 5  setosa
## 6  setosa

きちんとできました。

インストールされているパッケージを更新する

最初の投稿では、内容に勘違いがありました。needs()関数では「特定のバージョンのパッケージをインストールする」のではなく、「インストールされているパッケージで更新可能なものがあれば更新する」というものになります。(指摘してくれた @yutannihilation さん、ありがとう!)

needs()関数では、インストールされていないパッケージがあれば自動的にインストールしてくる仕様になっています。確認のために架空のパッケージ {foo}をインストールしてみましょう。

needs(foo)
# installing packages:
# foo

# Error in FUN(X[[i]], ...) : there is no package called ‘foo’
# In addition: Warning message:
# package ‘foo’ is not available (for R version 3.3.0) 

{foo}はCRANに登録されていないパッケージなのでインストールの途中でエラーとなりました。

では今度はパッケージの更新を実行します。

packageVersion("AF")
# [1] ‘0.1.1’

# https://cran.rstudio.com/web/packages/AF/
needs(AF) # この時はパッケージが読み込まれるだけで更新されない
needs(AF = "0.1.2") # 現在インストールされているバージョンよりも大きな値を与えることでパッケージが最新のバージョンに更新される
# updating packages:
#   AF
packageVersion("AF")
# [1] ‘0.1.2’

パッケージの特定バージョンをインストールするには「ggplot2 1.0.1が懐かしいときはdevtools::install_version() - Technically, technophobic.」で紹介されているようにdevtools::install_version()関数を使うのが良さげです。