5  Rパッケージ

5.1 パッケージとは

 Rには様々な関数 (functions) が用意されている。少しだけ例を挙げると、平均値を求めるmean()、合計を求めるsum()、線形回帰分析を行うlm()、平均値の検定を行うt.test()などがある。他にも多くの関数があり、ここにすべてを列挙することはできない。

 Rの関数は、誰にでも作ることができる。データ分析の方法は日々進歩し、Rがあらかじめ提供する関数だけでは数百行のコードが必要で、不便なときもある。そんな分析を、たった1行のコードで実行できるようにする便利な関数を、Rユーザはたくさん作ってきた。そのような関数をひとまとめにして他のユーザと共有できるようにしたものがパッケージである。    これまでに、グラフ作成に特化したパッケージ、機械学習に特化したパッケージ、テキスト分析に特化したパッケージなど、数千のRパッケージが開発されてきた。新たなパッケージの開発が、Rが幅広い問題に対応することを容易にしている。パッケージの豊富さがR最大のメリットであると言ってもよい。誰かが新しい分析手法を提案したら、数日内、あるいは提案と同時に(ときには、論文が公式に出版される前に!)Rパッケージとして公開されるケースが多い。

 本章ではパッケージをインストールし、読み込む方法について説明する。また、パッケージの管理をアシストするパッケージ、{pacman}の使い方についても紹介する。

5.2 パッケージのインストール

 Rの環境は何かを作るための作業台に似ている。作業台にはモノを作るための材料だけでなく、工具・道具セットなども置かれる。この作業台がRにおける「環境 (environment) 」であり、材料がベクトルや行列、データフレームなどのオブジェクト、工具セットがパッケージである。オブジェクトについては後で説明することにして、ここではパッケージについて考えよう。

 何かを作るとき、素材・材料だけでなく、なんらかの道具が必要となることが多い。Rにはあらかじめいくつかの必須道具セットが用意されているが、さらに様々な道具セットを追加して使うこともできる。そして、それらの道具セットの各々には、複数の道具が含まれている。道具セット(Rのパッケージ)に含まれるひとつひとつの道具のことを、Rでは「関数 (function) 」と呼ぶ。それらの道具セットを購入し、作業台の近くの棚に収納することがパッケージをインストールすることにあたる。

install.packages("パッケージ名")

 これらのパッケージは、CRANというRの公式道具屋1からダウンロードし、インストールすることができる。もう一つの大きな道具屋として、GitHubがある2GitHubは個人経営の道具屋が集まっているモールのようなものである。GitHubを利用するためには、あらかじめCRANから{devtools}、または{remotes}というパッケージをインストールしておく必要がある。

 ここでは{devtools}というパッケージをインストールしてみよう。CRANからパッケージをインストールするには、install.packages() という関数を使う。{devtools}はCRANに登録されているので、install.packages()関数でインストールする。パッケージ名を"(引用符)で囲む必要があるので、注意されたい。

install.packages("devtools")

 CRANに登録されていないパッケージをGitHubからインストールするときは、{devtools}または{remotes}のinstall_github()関数を使う。

# あらかじめ{devtools}、または{remotes}をインストールしておく
# {remotes}をインストールした場合は、remotes::install_github()を使用する
devtools::install_github("作成者のGitHubのID/パッケージ名")

 たとえば、筆者 (Song) が作成した{BalanceR}パッケージをインストールするために、以下のコードを入力して実行する。

# {remotes}をインストールした場合は、
# remotes::install_github("JaehyunSong/BalanceR")
devtools::install_github("JaehyunSong/BalanceR")

 ここでJaehyunSongはSongのGitHub IDであり、BalanceRはパッケージ名である。

5.3 パッケージの読み込み

 先ほど述べたように、パッケージのインストールは道具セットの購入と収納に似ている。ただし、実際に道具セットを使うためには、それを自分の作業台に乗せなければならない3 4。この作業がパッケージの読み込み (load) である。インストールしたパッケージを読み込むにはlibrary()またはrequire()関数を使う。require()は関数内に使う目的で設計された関数だが、パッケージを読み込むという点ではどちらを使っても大差ない。

図 5.1: Rパッケージと作業環境
library(パッケージ名)
#または
require(パッケージ名)

 読み込まれたパッケージはセッションが開かれている間のみ有効である。一通りの作業が終わり、作業部屋から退出すると、作業台上の道具セットは収納棚に自動的に戻される。つまり、RまたはRStudioを閉じると、どのパッケージを読み込んでいたかという情報がリセットされる。したがって、次にRStudio を使うときに同じパッケージを利用するなら、それを読み込む作業をあらためて行う必要がある。

 もしかすると、作業の途中に読み込んだパッケージを作業台から取り除きたいときがあるかもしれない。そんなときは、detach()関数を使う。対象となるパッケージ名の前に package: と付け加える必要があることに注意されたい。

detach("package:パッケージ名")

5.4 パッケージのアップデート

 Rパッケージはバグが修正されたり、新しい機能 (=関数) が追加されるなど、日々更新される。基本的には[^ex-packs]、利用するパッケージを最新版に更新(アップデート)した方が良いだろう。パッケージの更新方法は、パッケージのインストール方法と同じである。{dplyr}というパッケージを最新版にアップデートしたい場合、install.packages("dplyr")を実行すればよい。   [^ex-packs]: ただし、分析の再生性 (reproducibility) という観点から、パッケージを更新したくない(古いバーションを維持したい)ということもあり得る。分析過程を記録する際には、どのバージョンを使ったかということまで含めて記録をとるべきである。

 しかし、Rを使い続けるとインストール済みのパッケージの数はどんどん増える。そうなると、ひとつひとつのパッケージを個別にアップデートするのは面倒になってくる。そもそも既に最新版が入っていて(または開発休止/中止により)アップデートが不要なパッケージもあるかもしれない。そんなときは、RStudioでアップデートが必要なパッケージのリストを表示し、それらを一挙にアップデートすることができる。RStudioのPackagesペインにある “Update” をクリックすると、アップデート可能なパッケージの一覧が表示される。ここでアップデートしたいパッケージの左にチェックをするか、下段の “Select All” を選択して “Install Updates” をクリックすれば、チェックされているすべてのパッケージがアップデートされる。

 ただし、場合によってはアップデート時に以下のようなメッセージがコンソールに表示されるかも知れない。

  There are binary versions available but the source versions
  are later:
      binary source needs_compilation
terra 1.5-17 1.5-21              TRUE
yaml   2.2.2  2.3.4              TRUE

Do you want to install from sources the packages which need compilation? (Yes/no/cancel)

このようなメッセージが表示されたら、コンソール (Console) にYes、no、cancelのいずれかを入力してReturn (Enter) キーを押す必要がある。どうしても最新のパッケージが欲しい場合はYesを入力すれば良いが、インストールに時間がかかる場合がある。一方、noを入力した場合は、若干古いバージョンがインストールされるが、インストールに必要な時間が短いため、基本的にはnoで問題ないだろう。cancelを入力した場合はアップデートがすべてキャンセルされる。

5.5 {pacman}によるパッケージ管理

 CRANとGitHubを合わせると、数千のRパッケージが公開されている。Rの使用歴が長くなればインストール済みパッケージの数は増え、1つのスクリプト内で使用するパッケージも多くなるだろう。あるパッケージが他のパッケージの機能に依存することもよくあるので、自分が想像するよりも多くのパッケージがインストールされているかもしれない5。このように膨大な数のパッケージを管理するためのパッケージが{pacman}である。{pacman}はCRANから入手可能である。

install.packages("pacman")

5.5.1 インストール

 パッケージをCRANからインストールにはp_install()関数を使用する。使い方はinstall.packages()と同じであり、複数のパッケージをインストールしたい場合はパッケージ名の箇所にc(パッケージ名1, パッケージ名2, ...)を入れる。パッケージ名は"で囲んでも、囲まなくても良い。GitHubに公開されているパッケージはp_install_gh()関数を使用する。これは{devtools}、または{remotes}のinstall_github()と同じ使い方となり、必ず"で囲む必要がある。

 {pacman}の関数は、通常1つのファイルのなかで1度か2度しか使わないので、わざわざlibrary(pacman)で読み込まなくてもよい。{pacman}を読み込む代わりに、pacman::関数名()で使うことができる。

# CRANからインストール
pacman::p_install(パッケージ名)
# githubからインストール
pacman::p_install_gh("作成者のGitHubのID/パッケージ名") 

5.5.2 読み込み

 パッケージの読み込みにはp_load()関数を使う。実はこの関数が{pacman}を使う最大の利点である。p_load()関数の使い方は以下の通りである。

pacman::p_load(パッケージ名)

 p_load()の便利なところは (1) 複数のパッケージが指定可能であることと、 (2) インストールされていないパッケージを指定するとそれをCRANから自動的にインストールして読み込んでくれることだ。たとえば、{tidyverse}と{broom}、{estimatr}という3つのパッケージを読み込む場合、library()関数を使うと次のコードを使うことになる。

# library() を使う場合
library(tidyverse)
library(broom)
library(estimatr)

それに対して{pacman}のp_load()を使えば、以下のようになる。

# {pacman}のp_load() を使う場合
pacman::p_load(tidyverse,
               broom, 
               estimatr)

 また、p_load()内のパッケージがインストールされていない場合、CRANのパッケージリストから検索し、そのパッケージをインストールしてくれる。したがって、上で紹介したp_install()を使うケースはほぼない。

 ただし、GitHub上のパッケージは自動的にインストールしてくれない。たとえば、GitHubのみで公開されている{BalanceR}パッケージがインストールされていない場合、p_load(BalanceR)を実行しても{BalanceR}はインストールされない。あらかじめp_install_gh()でインストールしておく必要がある。しかし、GitHub上のパッケージを検索し、インストールしてから読み込みをするp_load_gh()という関数もある。ユーザー名JaehyunSongのBalanceRレポジトリーのパッケージを読み込む場合は以下のように入力する。

pacman::p_load_gh("JaehyunSong/BalanceR")

 このコードは{BalanceR}パッケージがインストールされていると読み込みのみ行い、インストールされていない場合はJaehyunSongのBalanceRレポジトリからパッケージをインストールし、読み込む。書くのがやや面倒であるが、便利な関数である。

5.5.3 アップデート

 {pacman}には、アップデートが可能なパッケージをすべてアップデートしてくれるp_update()という関数も用意されている。使い方は簡単で、コンソール上にp_update()のみの入力すれば良い。ただし、一部のパッケージのみをアップデートしたいのであれば、RStudioが提供するアップデート機能を使う方が簡単かもしれない6

 また、同じ機能の関数としてp_up()があるが、p_update()の方がアップデートしていることがわかりやすいのでp_update()の使用を推奨する7

pacman::p_update()

5.6 必須パッケージのインストール

 ここでは、現在Rでデータ分析をするにあたって必須のパッケージであるといえる{tidyverse}をインストールする。{tidyverse}は{dplyr}、{ggplot2}、{tidyr}など、Rにおいて不可欠なパッケージを含むパッケージである。また、上で紹介した{devtools}も今のうちにインストールしておこう。既に導入済みの読者は、以下のコードを実行しなくてよい。

install.packages("tidyverse")
install.packages("devtools")

5.7 名前空間の衝突

 Rパッケージは各種関数、データセット、ドキュメント(ヘルプ、ヴィネット)などを一つにまとめたものであり、Rユーザーであれば誰でもパッケージを開発し、配布することができる。「誰でも」Rパッケージ開発に関われることはRが持つ最大の利点ではあるが、統一された生態系を維持することが難しいことも事実だ。たとえば宋が開発した{mycat}というパッケージと矢内が開発した{myKitty}パッケージがあるとしよう。猫好きにはたまらないパッケージなので、両方インストールし、両方読み込みもするだろう。もし、この2つのパッケージで同じ名前を持つ、異なる構造・機能をする関数、nya()があればどうなるだろう。nya()関数を使用する場合、それが{mycat}のnya()なのか、{myKitty}のnya()なのかの問題が発生する。これが名前空間(namespace)の衝突(conflict)、またはパッケージ間の衝突と呼ばれるものである。

 一つの例を確認してみよう。Rを起動した直後、print(.packages())を入力すると、現在、読み込み済みのパッケージが確認できる。

print(.packages())
[1] "stats"     "graphics"  "grDevices" "utils"     "datasets"  "methods"  
[7] "base"     

Rにはいくつかのコア・パッケージが存在し、これらはR起動と同時に読み込まれる。続きて、この状態で{tidyverse}パッケージを読み込んでみよう。

library(tidyverse)
── Attaching core tidyverse packages ───────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.5
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.5.1     ✔ tibble    3.2.1
✔ lubridate 1.9.3     ✔ tidyr     1.3.1
✔ purrr     1.0.2     
── Conflicts ─────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package to force all conflicts to become errors

ここで注目するしたいのは「Conflicts」の箇所だ。

✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()

関数名は場合によってパッケージ名::関数名()と表記される。以上の例は{dplyr}のfilter()lag()関数が{stats}のfilter()lag()関数を上書きしたことを意味する。{stats}パッケージはRのコア・パッケージの1つであり、R起動と同時に読み込まれるパッケージだ。このメッセージは現在の作業環境内に読み込まれているパッケージに同じ名前の関数が複数ある場合に表示される。もう一度、読み込み済みのパッケージのリストが出してみよう。

私は{dplyr}パッケージを読み込んだ覚えがございません。

 {tidyverse}を読み込むと{dplyr}パッケージが読み込まれる。この{tidyverse}は{dplyr}、{readr}、{ggplot2}など「今どき」のRのおける必須級パッケージを一気に読み込むパッケージに過ぎない。

print(.packages())
 [1] "lubridate" "forcats"   "stringr"   "dplyr"     "purrr"     "readr"    
 [7] "tidyr"     "tibble"    "ggplot2"   "tidyverse" "stats"     "graphics" 
[13] "grDevices" "utils"     "datasets"  "methods"   "base"     

たしかに{dplyr}と{stats}が読み込まれている。この2つのパッケージにはfilter()という名前の関数があるようだが、パッケージ内の関数の目録はls("package:パッケージ名")で確認できる。

ls("package:stats")
  [1] "acf"                  "acf2AR"               "add.scope"           
  [4] "add1"                 "addmargins"           "aggregate"           
  [7] "aggregate.data.frame" "aggregate.ts"         "AIC"                 
 [10] "alias"                "anova"                "ansari.test"         
 [13] "aov"                  "approx"               "approxfun"           
 [16] "ar"                   "ar.burg"              "ar.mle"              
 [19] "ar.ols"               "ar.yw"                "arima"               
 [22] "arima.sim"            "arima0"               "arima0.diag"         
 [25] "ARMAacf"              "ARMAtoMA"             "as.dendrogram"       
 [28] "as.dist"              "as.formula"           "as.hclust"           
 [31] "as.stepfun"           "as.ts"                "asOneSidedFormula"   
 [34] "ave"                  "bandwidth.kernel"     "bartlett.test"       
 [37] "BIC"                  "binom.test"           "binomial"            
 [40] "biplot"               "Box.test"             "bw.bcv"              
 [43] "bw.nrd"               "bw.nrd0"              "bw.SJ"               
 [46] "bw.ucv"               "C"                    "cancor"              
 [49] "case.names"           "ccf"                  "chisq.test"          
 [52] "cmdscale"             "coef"                 "coefficients"        
 [55] "complete.cases"       "confint"              "confint.default"     
 [58] "confint.lm"           "constrOptim"          "contr.helmert"       
 [61] "contr.poly"           "contr.SAS"            "contr.sum"           
 [64] "contr.treatment"      "contrasts"            "contrasts<-"         
 [67] "convolve"             "cooks.distance"       "cophenetic"          
 [70] "cor"                  "cor.test"             "cov"                 
 [73] "cov.wt"               "cov2cor"              "covratio"            
 [76] "cpgram"               "cutree"               "cycle"               
 [79] "D"                    "dbeta"                "dbinom"              
 [82] "dcauchy"              "dchisq"               "decompose"           
 [85] "delete.response"      "deltat"               "dendrapply"          
 [88] "density"              "density.default"      "deriv"               
 [91] "deriv3"               "deviance"             "dexp"                
 [94] "df"                   "df.kernel"            "df.residual"         
 [97] "DF2formula"           "dfbeta"               "dfbetas"             
[100] "dffits"               "dgamma"               "dgeom"               
[103] "dhyper"               "diffinv"              "dist"                
[106] "dlnorm"               "dlogis"               "dmultinom"           
[109] "dnbinom"              "dnorm"                "dpois"               
[112] "drop.scope"           "drop.terms"           "drop1"               
[115] "dsignrank"            "dt"                   "dummy.coef"          
[118] "dummy.coef.lm"        "dunif"                "dweibull"            
[121] "dwilcox"              "ecdf"                 "eff.aovlist"         
[124] "effects"              "embed"                "end"                 
[127] "estVar"               "expand.model.frame"   "extractAIC"          
[130] "factanal"             "factor.scope"         "family"              
[133] "fft"                  "filter"               "fisher.test"         
[136] "fitted"               "fitted.values"        "fivenum"             
[139] "fligner.test"         "formula"              "frequency"           
[142] "friedman.test"        "ftable"               "Gamma"               
[145] "gaussian"             "get_all_vars"         "getCall"             
[148] "getInitial"           "glm"                  "glm.control"         
[151] "glm.fit"              "hasTsp"               "hat"                 
[154] "hatvalues"            "hclust"               "heatmap"             
[157] "HoltWinters"          "influence"            "influence.measures"  
[160] "integrate"            "interaction.plot"     "inverse.gaussian"    
[163] "IQR"                  "is.empty.model"       "is.leaf"             
[166] "is.mts"               "is.stepfun"           "is.ts"               
[169] "is.tskernel"          "isoreg"               "KalmanForecast"      
[172] "KalmanLike"           "KalmanRun"            "KalmanSmooth"        
[175] "kernapply"            "kernel"               "kmeans"              
[178] "knots"                "kruskal.test"         "ks.test"             
[181] "ksmooth"              "lag"                  "lag.plot"            
[184] "line"                 "lm"                   "lm.fit"              
[187] "lm.influence"         "lm.wfit"              "loadings"            
[190] "loess"                "loess.control"        "loess.smooth"        
[193] "logLik"               "loglin"               "lowess"              
[196] "ls.diag"              "ls.print"             "lsfit"               
[199] "mad"                  "mahalanobis"          "make.link"           
[202] "makeARIMA"            "makepredictcall"      "manova"              
[205] "mantelhaen.test"      "mauchly.test"         "mcnemar.test"        
[208] "median"               "median.default"       "medpolish"           
[211] "model.extract"        "model.frame"          "model.frame.default" 
[214] "model.matrix"         "model.matrix.default" "model.matrix.lm"     
[217] "model.offset"         "model.response"       "model.tables"        
[220] "model.weights"        "monthplot"            "mood.test"           
[223] "mvfft"                "na.action"            "na.contiguous"       
[226] "na.exclude"           "na.fail"              "na.omit"             
[229] "na.pass"              "napredict"            "naprint"             
[232] "naresid"              "nextn"                "nlm"                 
[235] "nlminb"               "nls"                  "nls.control"         
[238] "NLSstAsymptotic"      "NLSstClosestX"        "NLSstLfAsymptote"    
[241] "NLSstRtAsymptote"     "nobs"                 "numericDeriv"        
[244] "offset"               "oneway.test"          "optim"               
[247] "optimHess"            "optimise"             "optimize"            
[250] "order.dendrogram"     "p.adjust"             "p.adjust.methods"    
[253] "pacf"                 "Pair"                 "pairwise.prop.test"  
[256] "pairwise.t.test"      "pairwise.table"       "pairwise.wilcox.test"
[259] "pbeta"                "pbinom"               "pbirthday"           
[262] "pcauchy"              "pchisq"               "pexp"                
[265] "pf"                   "pgamma"               "pgeom"               
[268] "phyper"               "plclust"              "plnorm"              
[271] "plogis"               "plot.ecdf"            "plot.spec.coherency" 
[274] "plot.spec.phase"      "plot.stepfun"         "plot.ts"             
[277] "pnbinom"              "pnorm"                "poisson"             
[280] "poisson.test"         "poly"                 "polym"               
[283] "power"                "power.anova.test"     "power.prop.test"     
[286] "power.t.test"         "PP.test"              "ppoints"             
[289] "ppois"                "ppr"                  "prcomp"              
[292] "predict"              "predict.glm"          "predict.lm"          
[295] "preplot"              "princomp"             "printCoefmat"        
[298] "profile"              "proj"                 "promax"              
[301] "prop.test"            "prop.trend.test"      "psignrank"           
[304] "psmirnov"             "pt"                   "ptukey"              
[307] "punif"                "pweibull"             "pwilcox"             
[310] "qbeta"                "qbinom"               "qbirthday"           
[313] "qcauchy"              "qchisq"               "qexp"                
[316] "qf"                   "qgamma"               "qgeom"               
[319] "qhyper"               "qlnorm"               "qlogis"              
[322] "qnbinom"              "qnorm"                "qpois"               
[325] "qqline"               "qqnorm"               "qqplot"              
[328] "qsignrank"            "qsmirnov"             "qt"                  
[331] "qtukey"               "quade.test"           "quantile"            
[334] "quasi"                "quasibinomial"        "quasipoisson"        
[337] "qunif"                "qweibull"             "qwilcox"             
[340] "r2dtable"             "rbeta"                "rbinom"              
[343] "rcauchy"              "rchisq"               "read.ftable"         
[346] "rect.hclust"          "reformulate"          "relevel"             
[349] "reorder"              "replications"         "reshape"             
[352] "resid"                "residuals"            "residuals.glm"       
[355] "residuals.lm"         "rexp"                 "rf"                  
[358] "rgamma"               "rgeom"                "rhyper"              
[361] "rlnorm"               "rlogis"               "rmultinom"           
[364] "rnbinom"              "rnorm"                "rpois"               
[367] "rsignrank"            "rsmirnov"             "rstandard"           
[370] "rstudent"             "rt"                   "runif"               
[373] "runmed"               "rweibull"             "rwilcox"             
[376] "rWishart"             "scatter.smooth"       "screeplot"           
[379] "sd"                   "se.contrast"          "selfStart"           
[382] "setNames"             "shapiro.test"         "sigma"               
[385] "simulate"             "smooth"               "smooth.spline"       
[388] "smoothEnds"           "sortedXyData"         "spec.ar"             
[391] "spec.pgram"           "spec.taper"           "spectrum"            
[394] "spline"               "splinefun"            "splinefunH"          
[397] "SSasymp"              "SSasympOff"           "SSasympOrig"         
[400] "SSbiexp"              "SSD"                  "SSfol"               
[403] "SSfpl"                "SSgompertz"           "SSlogis"             
[406] "SSmicmen"             "SSweibull"            "start"               
[409] "stat.anova"           "step"                 "stepfun"             
[412] "stl"                  "StructTS"             "summary.aov"         
[415] "summary.glm"          "summary.lm"           "summary.manova"      
[418] "summary.stepfun"      "supsmu"               "symnum"              
[421] "t.test"               "termplot"             "terms"               
[424] "terms.formula"        "time"                 "toeplitz"            
[427] "toeplitz2"            "ts"                   "ts.intersect"        
[430] "ts.plot"              "ts.union"             "tsdiag"              
[433] "tsp"                  "tsp<-"                "tsSmooth"            
[436] "TukeyHSD"             "uniroot"              "update"              
[439] "update.default"       "update.formula"       "var"                 
[442] "var.test"             "variable.names"       "varimax"             
[445] "vcov"                 "weighted.mean"        "weighted.residuals"  
[448] "weights"              "wilcox.test"          "window"              
[451] "window<-"             "write.ftable"         "xtabs"               
ls("package:dplyr")
  [1] "%>%"                   "across"                "add_count"            
  [4] "add_count_"            "add_row"               "add_rownames"         
  [7] "add_tally"             "add_tally_"            "all_equal"            
 [10] "all_of"                "all_vars"              "anti_join"            
 [13] "any_of"                "any_vars"              "arrange"              
 [16] "arrange_"              "arrange_all"           "arrange_at"           
 [19] "arrange_if"            "as_data_frame"         "as_label"             
 [22] "as_tibble"             "as.tbl"                "auto_copy"            
 [25] "band_instruments"      "band_instruments2"     "band_members"         
 [28] "bench_tbls"            "between"               "bind_cols"            
 [31] "bind_rows"             "c_across"              "case_match"           
 [34] "case_when"             "changes"               "check_dbplyr"         
 [37] "coalesce"              "collapse"              "collect"              
 [40] "combine"               "common_by"             "compare_tbls"         
 [43] "compare_tbls2"         "compute"               "consecutive_id"       
 [46] "contains"              "copy_to"               "count"                
 [49] "count_"                "cross_join"            "cumall"               
 [52] "cumany"                "cume_dist"             "cummean"              
 [55] "cur_column"            "cur_data"              "cur_data_all"         
 [58] "cur_group"             "cur_group_id"          "cur_group_rows"       
 [61] "current_vars"          "data_frame"            "db_analyze"           
 [64] "db_begin"              "db_commit"             "db_create_index"      
 [67] "db_create_indexes"     "db_create_table"       "db_data_type"         
 [70] "db_desc"               "db_drop_table"         "db_explain"           
 [73] "db_has_table"          "db_insert_into"        "db_list_tables"       
 [76] "db_query_fields"       "db_query_rows"         "db_rollback"          
 [79] "db_save_query"         "db_write_table"        "dense_rank"           
 [82] "desc"                  "dim_desc"              "distinct"             
 [85] "distinct_"             "distinct_all"          "distinct_at"          
 [88] "distinct_if"           "distinct_prepare"      "do"                   
 [91] "do_"                   "dplyr_col_modify"      "dplyr_reconstruct"    
 [94] "dplyr_row_slice"       "ends_with"             "enexpr"               
 [97] "enexprs"               "enquo"                 "enquos"               
[100] "ensym"                 "ensyms"                "eval_tbls"            
[103] "eval_tbls2"            "everything"            "explain"              
[106] "expr"                  "failwith"              "filter"               
[109] "filter_"               "filter_all"            "filter_at"            
[112] "filter_if"             "first"                 "full_join"            
[115] "funs"                  "funs_"                 "glimpse"              
[118] "group_by"              "group_by_"             "group_by_all"         
[121] "group_by_at"           "group_by_drop_default" "group_by_if"          
[124] "group_by_prepare"      "group_cols"            "group_data"           
[127] "group_indices"         "group_indices_"        "group_keys"           
[130] "group_map"             "group_modify"          "group_nest"           
[133] "group_rows"            "group_size"            "group_split"          
[136] "group_trim"            "group_vars"            "group_walk"           
[139] "grouped_df"            "groups"                "id"                   
[142] "ident"                 "if_all"                "if_any"               
[145] "if_else"               "inner_join"            "intersect"            
[148] "is_grouped_df"         "is.grouped_df"         "is.src"               
[151] "is.tbl"                "join_by"               "lag"                  
[154] "last"                  "last_col"              "last_dplyr_warnings"  
[157] "lead"                  "left_join"             "location"             
[160] "lst"                   "make_tbl"              "matches"              
[163] "min_rank"              "mutate"                "mutate_"              
[166] "mutate_all"            "mutate_at"             "mutate_each"          
[169] "mutate_each_"          "mutate_if"             "n"                    
[172] "n_distinct"            "n_groups"              "na_if"                
[175] "near"                  "nest_by"               "nest_join"            
[178] "new_grouped_df"        "new_rowwise_df"        "nth"                  
[181] "ntile"                 "num_range"             "one_of"               
[184] "order_by"              "percent_rank"          "pick"                 
[187] "progress_estimated"    "pull"                  "quo"                  
[190] "quo_name"              "quos"                  "recode"               
[193] "recode_factor"         "reframe"               "relocate"             
[196] "rename"                "rename_"               "rename_all"           
[199] "rename_at"             "rename_if"             "rename_vars"          
[202] "rename_vars_"          "rename_with"           "right_join"           
[205] "row_number"            "rows_append"           "rows_delete"          
[208] "rows_insert"           "rows_patch"            "rows_update"          
[211] "rows_upsert"           "rowwise"               "same_src"             
[214] "sample_frac"           "sample_n"              "select"               
[217] "select_"               "select_all"            "select_at"            
[220] "select_if"             "select_var"            "select_vars"          
[223] "select_vars_"          "semi_join"             "setdiff"              
[226] "setequal"              "show_query"            "slice"                
[229] "slice_"                "slice_head"            "slice_max"            
[232] "slice_min"             "slice_sample"          "slice_tail"           
[235] "sql"                   "sql_escape_ident"      "sql_escape_string"    
[238] "sql_join"              "sql_select"            "sql_semi_join"        
[241] "sql_set_op"            "sql_subquery"          "sql_translate_env"    
[244] "src"                   "src_df"                "src_local"            
[247] "src_mysql"             "src_postgres"          "src_sqlite"           
[250] "src_tbls"              "starts_with"           "starwars"             
[253] "storms"                "summarise"             "summarise_"           
[256] "summarise_all"         "summarise_at"          "summarise_each"       
[259] "summarise_each_"       "summarise_if"          "summarize"            
[262] "summarize_"            "summarize_all"         "summarize_at"         
[265] "summarize_each"        "summarize_each_"       "summarize_if"         
[268] "sym"                   "symdiff"               "syms"                 
[271] "tally"                 "tally_"                "tbl"                  
[274] "tbl_df"                "tbl_nongroup_vars"     "tbl_ptype"            
[277] "tbl_vars"              "tibble"                "top_frac"             
[280] "top_n"                 "transmute"             "transmute_"           
[283] "transmute_all"         "transmute_at"          "transmute_if"         
[286] "tribble"               "type_sum"              "ungroup"              
[289] "union"                 "union_all"             "validate_grouped_df"  
[292] "validate_rowwise_df"   "vars"                  "where"                
[295] "with_groups"           "with_order"            "wrap_dbplyr_obj"      

いずれもfilter()という関数があることが分かる。これを名前空間の衝突と呼ぶ。それではfilter()関数を実行すると、どのパッケージのfilter()関数が呼ばれるだろうか。正解は「あとに読み込んだパッケージのfilter()関数」だ。{stats}はR起動と同時に読み込まれ、{dplyr}を含む{tidyverse}は起動後に読み込んだため、{dplyr}のfilter()の優先順位が高くなる。

 ここで更に{MASS}パッケージを読み込んでみよう。

library(MASS)
Attaching package: ‘MASS’

The following object is masked from ‘package:dplyr’:

    select

ここでは{MASS}のselect()関数が{dplyr}のselect()関数を上書きしたとのメッセージが表示される。実際、{dplyr}にも、{MASS}にもselect()関数が存在する。また、{MASS}を{tidyverse}より後に読み込んだため、{MASS}のselect()の優先順位が高い。以下のコードはirisというデータセットからSepal.LengthSepal.WidthSpecies列を抽出し、最初の6行を出力するコードであるが、エラーが出る。

iris |> 
  select(Sepal.Length, Sepal.Width, Species) |> 
  head()
Error in select(iris, Sepal.Length, Sepal.Width, Species): unused arguments (Sepal.Length, Sepal.Width, Species)

もし、このselect()関数が{dplyr}のselect()関数であれば、以上のコードは正しいコードだ。しかし、{MASS}のselect()が呼ばれたので、エラーが生じた。

 データハンドリングの際、よく使われるのは{dpylr}のselect()である。しかし、{MASS}も{dplyr}もよく使われるパッケージである。{dplyr}のselect()を優先したい場合は、{dplyr}を{MASS}より後に読み込んでも良いが、確実な方法は「どのパッケージの関数か」を明記することだ。パッケージ名を指定した関数を書き方がパッケージ名::関数名()である。以下のコードは{dplyr}パッケージのselect()関数を使うことを明記したコードであり、問題なく動くことが分かる。

iris |> 
  dplyr::select(Sepal.Length, Sepal.Width, Species) |> 
  head()
  Sepal.Length Sepal.Width Species
1          5.1         3.5  setosa
2          4.9         3.0  setosa
3          4.7         3.2  setosa
4          4.6         3.1  setosa
5          5.0         3.6  setosa
6          5.4         3.9  setosa

現在の作業環境における名前空間の衝突はconflicts()関数で確認できる。

conflicts()
 [1] "npk"           "%>%"           "%>%"           "%>%"          
 [5] "all_of"        "any_of"        "contains"      "ends_with"    
 [9] "everything"    "intersect"     "matches"       "num_range"    
[13] "one_of"        "select"        "setdiff"       "starts_with"  
[17] "union"         "vars"          "where"         "%>%"          
[21] "%>%"           "all_of"        "any_of"        "as_tibble"    
[25] "contains"      "ends_with"     "everything"    "last_col"     
[29] "matches"       "num_range"     "one_of"        "starts_with"  
[33] "tibble"        "tribble"       "%>%"           "add_row"      
[37] "as_data_frame" "as_tibble"     "data_frame"    "glimpse"      
[41] "lst"           "tibble"        "tribble"       "type_sum"     
[45] "as_label"      "enexpr"        "enexprs"       "enquo"        
[49] "enquos"        "ensym"         "ensyms"        "expr"         
[53] "quo"           "quo_name"      "quos"          "sym"          
[57] "syms"          "vars"          "filter"        "lag"          
[61] "Arith"         "Compare"       "show"          "%||%"         
[65] "as.difftime"   "body<-"        "date"          "intersect"    
[69] "kronecker"     "plot"          "Position"      "setdiff"      
[73] "setequal"      "union"        

一部の関数は全く同じ機能をする関数なので来にしなくても良いが、select()関数などは{dplyr}のselect()と{MASS}のselect()は全く別物なので注意が必要である。


  1. 道具「屋」とは言っても、パッケージは無料である。↩︎

  2. 他にもGitLabBitbucketなどがある。↩︎

  3. mean()sum()lm()のようによく使われる関数(=工具) はRの起動と同時に作業台の上に乗せられる。↩︎

  4. 作業台上に乗せずに、収納棚から必要なときだけ道具を取り出して使うこともできる。この場合、パッケージ名::関数名()のように関数を使う。頻繁に使うパッケージなら読み込む方が効率的だが、1、2回くらいしか使わないパッケージなら、このような使い方をしてもよいだろう。↩︎

  5. AというパッケージがBというパッケージに依存する場合、Aをインストール際にBもインストールされる。↩︎

  6. p_update(ask = TRUE)を実行すれば個々のパッケージに対してアップデートするかどうかを決めることができるが、ひとつひとつのパッケージについて回答を求められるので、かえって面倒である。↩︎

  7. コードの長さとわかりやすさの間にはトレードオフがある。短いほうがタイプが楽だが何を表しているかがわかりにくい一方で、長いとタイプするのは面倒だが何を表しているかはわかりやすい。↩︎