LoginSignup
9
10

More than 5 years have passed since last update.

7行でRの依存ライブラリを全て入れる

Posted at

釣り臭あるタイトルだが、あるスクリプトに必要なライブラリに対し、ローカルに保存してあれば読み込み、なければinstall.packagesを実行する関数を作った。(というか調べた)

ライブラリを読みこむのにはlibraryとrequireがあるが、下記のように吐いてくる値が違う。

script.R
> print(library(hoge)) # => ライブラリが見つからないと処理が止まってしまう!
 library(hoge) でエラー:  hoge という名前のパッケージはありません 
> print(require(hoge)) # => ライブラリが見つからないとFALSEを返す!
 要求されたパッケージ hoge をロード中です 
[1] FALSE

これを利用して、require(hoge)がFALSEならinstall.packagesで該当パッケージをインストールしてrequireすれば良いのだが、ライブラリ名をベクトルに詰めてこんな感じでよしなに処理しようとすると、盛大にエラーを吐く。

gomi.R
> for(lib in libraries){
+  if(!require(lib)){
+    install.packages(lib)
+    require(lib)
+  } 
+ }
 要求されたパッケージ lib をロード中です 
Error in install.packages : Updating loaded packages
c(" 要求されたパッケージ eval をロード中です ", " 要求されたパッケージ lib をロード中です ")
Failed with error:   'package' は長さ 1 でなければなりません 
 要求されたパッケージ lib をロード中です 
Installing package into /Users/01010357/Library/R/3.2/library
(as lib is unspecified)

これはrequireやlibraryはオブジェクトも文字列も受け取ることができるため。
libにライブラリ名が詰まっているが、requireはlibパッケージを読み込もうとしてしまう。

なので、install.packagesにベクトルをもたせられる事を利用し、下のコードみたいに読み込むといける

install.packages.R
load.libs <- function(lib){
  lib.not.in.local <- lib[!(lib %in% installed.packages()[, "Package"])]
  if (length(lib.not.in.local)) 
    install.packages(lib.not.in.local, dependencies = TRUE)
  sapply(lib, require, character.only = TRUE)
}
load.libs(libraries)

めっちゃ楽になった。

9
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
10