【R】パッケージの更新時のエラーに対処する

# 1. 症状

こういうやつ。(Windows)

```R
update.packages(ask = F )
```

パッケージをアップデートしようとすると、山のようなエラーが発生。

```
警告:   パッケージ ‘glue’ の既存のインストールを取り除くことが出来ませんでした 
警告:   ‘glue’ を復帰させました 
警告:   パッケージ ‘Rcpp’ の既存のインストールを取り除くことが出来ませんでした 
警告:   ‘Rcpp’ を復帰させました 
```

# 2. 解決策

ハッキリとした原因自体はよく分からないんですけど大体このエラーを起こすパッケージはユーザーディレクトリにインストールされている傾向にある気がします。
というわけで、全部Program Files以下にインストールさせましょう。

## 2.1. アップデート出来なかったパッケージを特定
`update.packages()`が吐き出したエラー文を根こそぎ取得しておきましょう。
メモ帳なんかにコピーしておきます。

```R
warnings()
1: In file.copy(savedcopy, lib, recursive = TRUE) :
   C:\Users\user\Documents\R\win-library\3.6\00LOCK\glue\libs\x64\glue.dll の C:\Users\user\Documents\R\win-library\3.6\glue\libs\x64\glue.dll へのコピーに問題があります: Permission denied 
2: In file.copy(savedcopy, lib, recursive = TRUE) :
   C:\Users\user\Documents\R\win-library\3.6\00LOCK\Rcpp\libs\x64\Rcpp.dll の C:\Users\user\Documents\R\win-library\3.6\Rcpp\libs\x64\Rcpp.dll へのコピーに問題があります: Permission denied 
3:  install.packages(update[instlib == l, "Package"], l, repos = repos,  で: 
   パッケージ ‘rJava’ のインストールは、ゼロでない終了値をもちました 
```

エラー文にパッケージのパスが出ないときは、`find.package()`で探しておきます。

```R
> find.package("rJava")
[1] "C:/Users/user/Documents/R/win-library/3.6/rJava"
```

## 2.2. Rからパッケージを削除
```R
remove.packages(c("glue", "Rcpp", "rJava"))
```

## 2.3. パッケージの残骸を削除
`remove.packages()`を走らせても残骸が残っていることがあります。
なので、ユーザーディレクトリを直接参照してフォルダが残っていれば消します。
この時、RやRStudioを閉じていないと消せないことがあるので、予め閉じておきましょう。

## 2.4. デフォルトのインストール先を設定

`C:/Program Files/R/R-x.x.x/etc`の`Rprofile.site`を編集（ない場合は新規作成）し、以下の記述を加えておきます。

```
# PACKAGE DIRECTORY OPTION
.libPaths(c(.Library, .libPaths()))
```
こうすることで、パッケージのインストール先としてProgram Files以下が優先されます。

## 2.5. 改めてパッケージを導入
RまたはRStudioを`管理人権限`で開き、いつも通りパッケージを導入します。

```R
install.packages(c("glue", "Rcpp", "rJava"))
```

インストール先が無事にProgram Files以下になっていることを確認してください。

```R
> find.package(c("glue", "Rcpp", "rJava"))
[1] "C:/Program Files/R/R-3.6.2/library/glue"  "C:/Program Files/R/R-3.6.2/library/Rcpp" 
[3] "C:/Program Files/R/R-3.6.2/library/rJava"
```

万が一Program Files以下になっていない場合は、強制的にProgram Files以下になるように指定して再インストールです。

```R
# 2.2.～2.3.までやり直してパッケージを再度削除してから、以下を実行します。
install.packages(c("glue","Rcpp"), lib = "C:/Program Files/R/R-x.x.x/library")
```

# 3. 対策

- **ユーザーディレクトリへのインストールを回避するためには、`パッケージ導入時・アップデート実行時は管理人権限で開く`または`予めユーザーにフルコントロール権限を与えておく`ことが必須となります。**<BR>その上で、2.4.の設定を行っておけば、パッケージのインストール時にProgram Files以下が優先されるようになります。

- たまに、`「パッケージのソースからインストールを行いますか？ (コンパイルが必要です)」`と聞かれますが、これは`ソースインストール`と呼ばれるものらしいです。個人的にはまずは`いいえ`を選択することを推奨します。そのほうが安定的にパッケージを導入できるからです。<BR>その上で、より最新バージョンが必要であれば、`update.packages()`を個別に走らせて`はい`を選択して様子を見ます。環境とか相性とかの問題もあるので、上手くいけば最新版を使えますし、仮に上手くいかなくてエラーが出ても安定版を使うことになるだけで実用性の観点では安定版でも問題ないはずです。

- R自体のバージョンが遠因となる場合もあります。基本的にR本体は新しいに越したことはないので、サボらず定期的にアップデートしてください。割とコレで解決する場合もあります。 ~~ちなみに私は4.x.xへのアップデートが怖くてしばらく放置してました。~~

# 4. 注意

2.4.のように`.libPaths()`を変更しても、ユーザーディレクトリ内に導入したパッケージは使用することができます。

```R
> find.package("backports")
[1] "C:/Users/user/Documents/R/win-library/3.6/backports"
> library(backports)
 警告メッセージ: 
 パッケージ ‘backports’ はバージョン 3.6.3 の R の下で造られました 
```

しかし、`.libPaths()`を変更した場合、ユーザーディレクトリ内のパッケージを削除する際は一工夫必要です。

```R:Example
# こうではなく
> remove.packages("backports")
Removing package from ‘C:/Program Files/R/R-3.6.2/library’
(as ‘lib’ is unspecified)
Error in remove.packages : there is no package called ‘backports’

# このように、libにユーザーディレクトリを指定する
> remove.packages("backports", lib = Sys.getenv("R_LIBS_USER"))
```

# 6. まとめ

というわけで、エラーが発生するパッケージを全てProgram Files以下に再インストールしたらエラーが出なくなりました。

よくソースインストールする時にこのようなエラーがありましたが、再インストール後はソースインストールしても警告文が出なくなりました。

根本的解決かは不明ですが、一応今のところ問題ないです。

おしまい。

# 7. 参考文献

- [install.packagesでインストールするpathを変更する - Qiita](https://qiita.com/ysk24ok/items/66a4c4ca637952f3f540)
- [パッケージインストールとソースインストールの違い - 雲のメモ帳](https://www.cloudnotes.tech/entry/2016/09/22/135048)