Homebrewをインストールしている前提で。mac環境構築参照。
brew cask install r-app rstudio
で終了。
macOSでHomebrewを用いてインストールできるのは
brew install rでインストールされるRbrew cask install r-appでインストールされるR for Mac OS Xと基本的に同じものの2種類になる。1. のbrew install r版はopenblasなどでカスタムができること、brew doctorでWarningが出ないメリットがあるが、CRAN的には非公式ビルド扱いのためにパッケージのインストールの際に毎回ソースからビルドすることになる。という大きなデメリットがある。またtcl/tkサポートがない?ためEZRがうまく動かなかったような記憶がある。EZRに関してはplotの出力の問題もあり、仮想マシンを使うなどしてWindows版を利用するのがスムーズではある。
一方2. のbrew cask install r-appでインストールされる方は基本的には公式ビルドのためパッケージのインストールなどで問題は生じない。代わりに一緒にインストールされるtcl/tkなどがあまりお行儀が良くないらしく、以下のようなbrew doctorでのWarningがでるようになってしまう。Warningを消すにはこれらのファイルを削除するしかないが、消さなくてもとりあえず気づけるような問題は生じていないのでそのままにしている。
$ brew doctor
Please note that these warnings are just used to help the Homebrew maintainers
with debugging if you file an issue. If everything you use Homebrew for is
working fine: please don't worry or file an issue; just ignore this. Thanks!
Warning: Unbrewed dylibs were found in /usr/local/lib.
If you didn't put them there on purpose they could cause problems when
building Homebrew formulae, and may need to be deleted.
Unexpected dylibs:
/usr/local/lib/libtcl8.6.dylib
/usr/local/lib/libtk8.6.dylib
Warning: Unbrewed header files were found in /usr/local/include.
If you didn't put them there on purpose they could cause problems when
building Homebrew formulae, and may need to be deleted.
Unexpected header files:
/usr/local/include/fakemysql.h
/usr/local/include/fakepq.h
/usr/local/include/fakesql.h
/usr/local/include/itcl.h
/usr/local/include/itcl2TclOO.h
/usr/local/include/itclDecls.h
/usr/local/include/itclInt.h
/usr/local/include/itclIntDecls.h
/usr/local/include/itclMigrate2TclCore.h
/usr/local/include/itclTclIntStubsFcn.h
/usr/local/include/mysqlStubs.h
/usr/local/include/odbcStubs.h
/usr/local/include/pqStubs.h
/usr/local/include/tcl.h
/usr/local/include/tclDecls.h
/usr/local/include/tclOO.h
/usr/local/include/tclOODecls.h
/usr/local/include/tclPlatDecls.h
/usr/local/include/tclThread.h
/usr/local/include/tclTomMath.h
/usr/local/include/tclTomMathDecls.h
/usr/local/include/tdbc.h
/usr/local/include/tdbcDecls.h
/usr/local/include/tdbcInt.h
/usr/local/include/tk.h
/usr/local/include/tkDecls.h
/usr/local/include/tkPlatDecls.h
Warning: Unbrewed .pc files were found in /usr/local/lib/pkgconfig.
If you didn't put them there on purpose they could cause problems when
building Homebrew formulae, and may need to be deleted.
Unexpected .pc files:
/usr/local/lib/pkgconfig/tcl.pc
/usr/local/lib/pkgconfig/tk.pc
Warning: Unbrewed static libraries were found in /usr/local/lib.
If you didn't put them there on purpose they could cause problems when
building Homebrew formulae, and may need to be deleted.
Unexpected static libraries:
/usr/local/lib/libtclstub8.6.a
/usr/local/lib/libtkstub8.6.a
help("Startup")
.Renviron(--no-environでスキップ)
$R_ENVIRON$R_HOME/etc/Renviron.site$R_ENVIRON_USER./.Renviron~/.Renviron ←これを用意しているRprofile.site(あれば。--no-site-fileでスキップ)
$R_PROFILE$R_HOME/etc/Rprofile.site.Rprofile(--no-init-fileでスキップ)
$R_PROFILE_USER ←.Renvironで設定しているとこれが優先される./.Rprofile ←するとプロジェクト毎のこれが読み込まれていなかった
.Rprofile中でsource("packrat/init.R")によりpackratが起動~/.Rprofile./*.RDataの読み込み(あれば。--no-restore-dataでスキップ).First関数が定義されていれば実行される.First.sys()関数が実行される
options("defaultPackages")のパッケージ群をrequireするmethodsパッケージが含まれていると先に.OptRequireMethods()で読み込まれてnamespaceの初期化が正しく行われる、らしいなおR --vanillaとすると--no-site-file, --no-init-file, --no-environ and (except for R CMD) --no-restoreの扱いになるので問題の切り分けをしたいときに。
R起動時に読み込まれ、環境変数を設定するファイル。
読み込まれる順番は上記のようになっており、プロジェクト(カレントディレクトリ)では通常は作られないので最後の~/.Renvironが読み込まれることになる模様。この後に.Rprofileの読み込みになり、その際にはこのファイル内でR_PROFILE_USERを設定していると優先される。
や各所を参考に作っている。
.Rprofileの読み込み確認最初と最後にメッセージを表示させることで、こっそりエラーになって止まっていても気づけるようにしておく。
message("\n*** Loading user .Rprofile (~/.Rprofile) ***\n")
...
message("*** Successfully loaded user .Rprofile ***\n")
.RenvironのR_LIBS_USERとともに.libPathsを設定する。「パッケージのインストール先」と「インストールされたパッケージの読込先」を両方とも設定しておく必要がある模様。R_LIBS_USERは読込先、.libPathsはインストール先の指定になる?。これらの設定はpackrat管理の初期化処理で上書きされるため、プロジェクトの.Rprofileとの読み込み順に注意が必要になる。.Renvironの設定にも依存するが、自分の設定ではR_PROFILE_USERが設定されているため、その中でこのインストールパス処理してから下記のプロジェクトの.Rprofile読み込みが行われるようにしている。
install.packagesでインストールするpathを変更する - Qiita
なんか設定してもうまくいかないと思ったらあらかじめディレクトリは作っておく必要がある(存在しないディレクトリは読み込まない)のが原因だった。エラーは出してくれない。.Renvironで$R_LIBS_USERを、.Rprofileで.libPaths()を設定。
# set .libPaths to "~/.R_LIBS"
if (dir.exists(file.path("~", ".R_LIBS")) || dir.create(file.path("~", ".R_LIBS"))) {
.libPaths(file.path("~", ".R_LIBS"))
} else {
warning("\n******* .libPaths was undefined !!! *******\n")
}
なおこっそり.bashrcにも入れている。ついでにaliasもここに記載。
# create directory for installed packages
if [ ! -d ~/.R_LIBS ]; then
mkdir ~/.R_LIBS
echo "Created '~/.R_LIBS' for R_LIBS_USER."
fi
alias R='R --no-save --no-restore-data'
brew cask install r-appの方を使っている分には基本的には問題なくCRANのバイナリが利用できるはずだが、それだけでは足りないものもあるようで、bookdownパッケージほか多くのパッケージ作者でもあるYihui Xie氏の用意してくているCRANextra用のサーバーがあるようなのでそちらも設定。
# CRAN repos from rstudio and extra from macos.rbind.org by Yihui Xie
options(repos = c(
CRAN = 'https://cran.rstudio.com',
CRANextra = 'https://macos.rbind.org'
))
.Rprofile読み込み設定~/.Renvironで$R_PROFILE_USERを~/.Rprofileに設定し、カレントディレクトリの./.Rprofileよりも優先して読み込むようにしているため、プロジェクトの.Rprofileが存在しても~/.Rprofileが常に読み込まれることになる。特にPackratで管理しているプロジェクトでは(プロジェクトのルート)/.Rprofileに
#### -- Packrat Autoloader (version 0.4.9-8) -- ####
source("packrat/init.R")
#### -- End Packrat Autoloader -- ####
のような初期化処理が追記されているため、気づかずにいるとPackrat管理しているつもりで何もしていなかったということになりかねない(なった)。そのため以下のコードを$R_PROFILE_USER(実質~/.Rprofile)のインストールパスの設定よりあとかつ起動時のパッケージ追加処理より前に入れてプロジェクトの.Rprofileを読み込むようにしている。またR --vanilla環境ではSys.getenv("R_USER")は""を返すため、無限ループにハマらないようにunset = getwd()を入れている。
# source projectdir/.Rprofile
# R --vanilla returns "" to Sys.getenv("R_USER")
if ((Sys.getenv("R_USER", unset = getwd()) != getwd()) && (file.exists(file.path(getwd(), ".Rprofile")))) {
message("* Project .Rprofile is detected. *\nLoading Project .Rprofile...")
source(file.path(getwd(), ".Rprofile"))
message("Successfully loaded Project .Rprofile\n")
}
.Rprofileにlibrary(tidyverse)とすると、
.First.sys()でoptions("defaultPackages")のパッケージをロードするの順になるためbase::search()でのパスの順番が変わり、dplyr::filter()ではなくstats::filter()が優先されてしまったりする。そのため、“defaultPakcages”に追記する形をとる必要がある。
options(defaultPackages = c(getOption("defaultPackages"), "tidyverse"))
ただしこれだとPackratを利用するプロジェクトなど、指定したパッケージがインストールされていない場合にはエラーが出てしまう。これを抑制するためにrequireNamespace(x, quietly = TRUE)を用いてインストールされているか判定し、存在するものだけを加えるようにしていたが、requireNamespaceではPackrat管理下のプロジェクトにパッケージがインストールされていなくてもTRUEが返ってしまう。 require()はsuppressWarnings()とsuppressMessages()を使えば余分な表示は消せるが、結局.First.sys()で外部パッケージを読み込ませていると、そのあとに立ち上がるpackrat環境ではインストールされていないのでafterPackratModeOn -> cleanSearchPath -> forceUnload -> unloadNamespaceのようなエラーが出る……。しかも先にrequireを呼び出してしまうせいか結局元々の"defaultPackages"よりも先に追加パッケージがsearch()のパスに入ってしまう。
requreNamespaceだとpackrat環境でのみ問題が生じる
.Rprofileを実行している時点ではインストールされていると判断されるpackratが読み込まれた環境ではインストールされていないのでエラー.Rprofileを読み込んでpackratの読み込み処理をさせるとうまくいく?解決方法として
requireNamespaceを利用して(も問題ないので)requireの順番を崩さずにインストールされているかだけチェックして追加の処理にすることで解決できる。
Packrat環境かどうかを確認するには!is.na(Sys.getenv("R_PACKRAT_MODE", unset = NA))が使えるはずなのだが、これはpackratが開始してからしかわからない。packratの読み込みはプロジェクトの.Rprofile中のsource("packrat/init.R")で行われるので、先にプロジェクトの.Rprofile読み込みを行っておけば正しく判定可能になる。読み込み前だと常にFALSEになってしまう。代替手段としてはgetwd()/packrat/init.Rかpackrat.lockが存在するかどうかで判定する。Packrat環境の場合はdefaultPakagesはいじらずに、プロジェクトの中でインストールおよび読みこむパッケージを管理するようにする。Packratの使用目的からもこの方が道理にかなっているだろう。大人しくセットアップファイルでも作って管理することにする。先にプロジェクトの.Rprofileを読み込んでいる前提なので、そちらか.RenvironでSys.setenv("NO_ADDITIONAL_PACKAGES" = TRUE)(NA以外なら何でも)を設定しておけば追加処理をスキップできるようにしてある。
if (!is.na(Sys.getenv("R_PACKRAT_MODE", unset = NA))) {
message("* This project is under control of packrat. No additional packages will be loaded in global .Rprofile. *\n")
} else if (!is.na(Sys.getenv("NO_ADDITIONAL_PACKAGES", unset = NA))) {
message("* This project is set to use 'defaultPackages'. No additional packages will be loaded in global .Rprofile. *\n")
} else {
local({
original_default <- getOption("defaultPackages")
pkgs <- c("tidyverse", "magrittr", "skimr")
pkgs <- pkgs[sapply(pkgs, function(x) {return(ifelse((requireNamespace(x, quietly = TRUE)), TRUE, FALSE))})]
options(defaultPackages = c(original_default, pkgs))
message(paste0("* These additional packages will be loaded. *\n", paste(pkgs, collapse = ", "), "\n"))
})
}
一応require版もメモとして取っておく。こちらだとgetOption("defaultPackages")で得られるリストは全く同じものになるが、先にrequire()してしまうせいかnamespace initializationがうまく行かず、filter()でdplyr::filter()ではなくstats::filter()が呼び出される状態になってしまう。
pkgs[sapply(pkgs, function(x) {return((suppressMessages(suppressWarnings(require(x, character.only = TRUE)))))})]
Packratを使用しているかの判定がSys.getenv("R_PACKRAT_MODE")ではsource("packrat/init.R")処理前の時点ではうまくいかないことを確認するためのコード。
# .Rprofileに書いてもpackrat起動前なので常に"Not Packrat!"になってしまう
if (!is.na(Sys.getenv("R_PACKRAT_MODE", unset = NA))) {
message("Packrat!")
} else {
message("Not Packrat!")
}
R for Enterprise: Understanding R’s Startup · R Views
の下の方の「Record sessionInfo automatically」を元にrstudioapiを使わなくてもいいように改造。ただし.Last起動時(RStudio終了時)にgetwd()がプロジェクトルートから変わっていないことを前提にしている。
.Last <- function(){
if (interactive() && !is.na(Sys.getenv("RSTUDIO", unset = NA)) && as.logical(sum(grepl(".Rproj", list.files())))) {
## append date + sessionInfo to a file called sessionInfoLog
cat("Recording session info into the project's sesionInfoLog file...")
info <- capture.output(sessionInfo())
info <- paste("\n----------------------------------------------",
paste0('Session Info for ', Sys.time()),
paste(info, collapse = "\n"),
sep = "\n")
f <- file.path(getwd(), "sessionInfoLog")
cat(info, file = f, append = TRUE)
}
}
option()Speeding up package installation | R-bloggers Use parallel option of boot function in R - Stack Overflow
parallelパッケージとかもあるが、ここではinstall.packages()とboot用のオプションのみ。CPUコア数は以下のコードで。
parallel::detectCores()
## [1] 8
install.packagesのNcpus Argumentの説明より
the number of parallel processes to use for a parallel install of more than one source package. Values greater than one are supported if the make command specified by Sys.getenv(“MAKE”, “make”) accepts argument -k -j Ncpus.
boot::bootのncpus Argumentの説明より
integer: number of processes to be used in parallel operation: typically one would chose this to the number of available CPUs.
# set CPU cores to use in install.packages and boot::boot
# to know the number of cores in your PC, use parallel::detectCores()
options(Ncpus=4,
boot.ncpus=4)
# set boot parallel method
# options(boot.parallel="multicore")
一覧を見るには
Sys.getenv()