Rの細かいTipsまとめ(小さいTipsの寄せ集め)

独立した記事にはならないが、それぞれ便利かつ重要な小さなRのTipsを紹介。

目次

チートシート

ggplot2

qplot()

基本

qplot(x=Sepal.Width, y=Sepal.Length, data=iris, geom="point", color=Species) # 散布図
qplot(x=date, y=unemploy, data=economics, geom="line") # 折れ線グラフ
qplot(x=feed, data=chickwts, geom="bar") # 棒グラフ
qplot(x=Sepal.Width, data=iris, binwidth=0.3, geom="histogram") # ヒストグラム
qplot(x=Sepal.Width, data=iris, geom="density") # 密度プロット
qplot(y=Sepal.Length, data=iris, geom="boxplot") # 箱ひげ図
qplot(x=Species, y=Sepal.Length, data=iris, geom="boxplot") # 箱ひげ図xy
qplot(x=Species, y=Sepal.Length, data=iris, geom="violin") # バイオリンプロット

高度なチャート

qplot(x=Sepal.Width, y=Sepal.Length, data=iris, geom=c("point", "smooth"), facets = round(Petal.Width) ~ Species) # 共変量プロット
qplot(x=Species, y=Sepal.Length, data=iris, geom='boxplot', facets = round(Sepal.Width) ~ round(Petal.Width))

見た目をカスタマイズ

qplot(x=Sepal.Width, y=Sepal.Length, data=iris, color=Species, geom="point", xlim=c(0,NA), ylim=c(0,NA), main="散布図の例", xlab="がくの幅", ylab="がくの長さ")

ggplot()

基本

p1 <- ggplot(iris, aes(x=Sepal.Width, y=Sepal.Length, color=Species)) + geom_point() # 散布図
p2 <- ggplot(economics, aes(x=date, y=unemploy)) + geom_line() # 折れ線グラフ
p3 <- ggplot(chickwts, aes(x=feed)) + geom_bar() # 棒グラフ
p4 <- ggplot(iris, aes(x=Sepal.Width)) + geom_histogram(binwidth=0.3) # ヒストグラム
p5 <- ggplot(iris, aes(x=Sepal.Width)) + geom_density() # 密度プロット
p6 <- ggplot(iris, aes(y=Sepal.Length)) + geom_boxplot() # 箱ひげ図
p7 <- ggplot(iris, aes(x=Species, y=Sepal.Length)) + geom_boxplot() # 箱ひげ図xy
p8 <- ggplot(iris, aes(x=Species, y=Sepal.Length)) + geom_violin() + geom_boxplot(width=.1, fill="black", outlier.colour=NA) + stat_summary(fun=median, geom="point", fill="white", shape=21, size=2.5) # バイオリンプロット

高度なチャート

ggplot(iris, aes(y=Sepal.Length, x=Sepal.Width)) + geom_point() + geom_smooth() + facet_grid(round(Petal.Width) ~ Species) # 共変量プロット
ggplot(iris, aes(y=Sepal.Length, x=Sepal.Width)) + geom_point() + geom_smooth() + facet_wrap( ~ Species) # 並べるだけ

追加要素

ggplot(iris, aes(x=Sepal.Width, y=Sepal.Length, color=Species)) + geom_point() +
  ggtitle("散布図の例") + xlab("がくの幅") + ylab("がくの長さ") +
  geom_vline(xintercept = 3, color = "red") +
  geom_hline(yintercept = 7, color = "blue") +
  geom_abline(slope = .5, intercept = 4)

複数のチャートをレイアウト

require(patchwork)
(p1+p3)/p2/(p4+p5+p6)/(p7+p8)

並列処理

doParallel/foreachを使った並列処理

最初におまじない

require(doParallel)
require(foreach)
cores <- makeCluster(detectCores(), type='PSOCK')
system <- Sys.info()['sysname']
cl <- NULL
if (system == 'Windows') {
    cl <- makeCluster(getOption('cl.cores', cores))
    registerDoParallel(cl)
    registerDoSEQ()
    on.exit(stopCluster(cl))
} else {
    options('mc.cores' = cores)
    registerDoParallel(cores)
}

ループ処理

coefs <- foreach(i = 1:47, # ループのインデクス
                 .packages=.packages(),
                 .export=ls(envir=parent.frame()),
                 .combine=rbind # デフォルトで結果はリストに追加していくが、結果が行単位になっている場合で行追加する場合はこのようにする
                 ) %dopar% {
  bsts_model = bsts_models[[i]]
     :
  coef <- data.frame(coef, row.names=NULL)
  coef$varname <- varnames
  coef[coef$varname!='(Intercept)',c(6,7,1:5,8)] # 最後の戻り値が結果のオブジェクトに追記されていく
}

変数を含むコマンドを実行する

1行

.file <- "result"
.path <- "//tsclient/c/home/downloads/"
.str_cmd <- paste0("x <- fread('", .path, .file, ".csv')")
eval(parse(text=.str_cmd))

複数行

.file <- "result"
.path <- "//tsclient/c/home/downloads/"
.str_cmd <- paste0(".tmp <- fread('", .path, .file, ".csv')"); eval(parse(text=.str_cmd)) # 一時変数に代入
.tmp %>% ... -> .tmp # 具体的な処理
.str_cmd <- paste0(".tmp -> t_", .f); eval(parse(text=.str_cmd)) # 一時変数から戻す

ベクトル

ベクトルのノルム

m <- matrix(rnorm(20), nc=4) # 例で使う行列を生成
norm1 <- drop(crossprod(abs(m), rep(1, nrow(m)))) # マンハッタンノルム
norm2 <- drop(crossprod(m^2, rep(1, nrow(m)))) # ユークリッドノルム

集合

ids1_or_ids2 <- union(ids1, ids2) # 和集合
ids1_and_ids2 <- intersect(ids1, ids2) # 積集合
ids1_minus_ids2 <- setdiff(ids1, ids2) # 差集合(ids1 - ids2)
setequal(ids1, ids2) # 集合として等しいかどうか
id %in% ids # 集合に含まれるかどうか

特定の条件に当てはまるインデックスを抽出

vec2[which(vec1<10)] # vec1<10になるvec2の値
params[which.min(result$loss_mse),] # loss_mseが最小になる行
params[which.max(result$gain_auc),] # gain_aucが最大になる行

オブジェクトが同一かどうかを検証

identical(x1, x2) # 全く同じ
all.equal(x1, x2) # ほぼ同じ

サンプリング

ランダムダンプリング

stratified sampling(層化抽出法)

require(sampling)
strata(data, stratanames=c('層化に使うカラム1', '層化に使うカラム2'), size=c(カラム1の抽出率, カラム2の抽出率), method=抽出方法)

抽出方法は

  • 'srswor': 非復元ランダムサンプリング(デフォルト)
  • 'srswr': 復元ランダムサンプリング
  • 'poisson': ポアソンサンプリング
  • 'systematic': 系統抽出

Rで文字列をコマンドとして実行する(eval)

Rの繰り返し処理などでコマンドの一部のみを書き換えて同様の処理を行いたい、たとえば対象のデータフレームのみ変えて同じ処理を実行したい場合がある。

そういう場合には動的な部分(データフレームオブジェクト名)を変数として含むコマンドの文字列を生成し、その文字列をコマンドとして実行することになる。

言葉にするとややこしいが、他の言語でもあるeval処理である。

コマンドが1行の場合

最も単純なケースである。

基本形

ファイル名に動的部分を含むテキストファイル(activity_type1.txt)を読み込み、名前に動的部分を含むテーブル(t_activity_type1)に格納する例

.f <- 'activity_type1'
eval(parse(text=paste0("t_", .f, " <- fread('/path/to/datadir/", .f, ".txt', encoding='UTF-8', sep='\t', na.strings='')")))

.fが動的部分で、ファイル名である。

そして動的部分を

.f <- 'activity_type2'

などと変えても同様に実行できる。

eval(parse(text=paste0("固定文字列", 動的部分, "固定文字列")))

が基本になる。paste0()関数がパーツを結合して文字列を生成する関数で、それ以外はおまじないだと思っておけばいい。コマンドの固定文字列部分にクォーテーションマーク'を含む場合、文字列全体はダブルクォーテーションマーク"で囲む。

コマンド部分のみ文字列変数として切り出してソースを見やすくする

この記法だとソースコードの中で動的部分が見えにくく、コマンドの一部を書き換えたり繰り返し利用したりするのに向かない(特にカッコの数がわからなくなる)ので、コマンド部分を変数として取り出したのが以下になる。

.f <- 'activity_type1'
.str_cmd <- paste0("t_", .f, " <- fread('/path/to/datadir/", .f, ".csv', encoding='UTF-8', sep='\t', na.strings='')")
eval(parse(text=.str_cmd))

.str_cmdがコマンドの文字列になる。こうすると

.f <- 'activity_type1'
.str_cmd <- paste0("t_", .f, " <- fread('/path/to/datadir/", .f, ".csv', encoding='UTF-8', sep='\t', na.strings='')")
eval(parse(text=.str_cmd))
.str_cmd <- paste0("t_", .f, " %>% mutate_at(ends_with('_date'), as.Date)")
eval(parse(text=.str_cmd))

のように動的コマンドを複数生成して実行しやすくなる。

複数行のコマンドを実行する場合

上記の方法だと繰り返しeval(parse(text=.str_cmd))が必要になってしまう。動的に実行するコマンドが複数行の場合でも毎回必要になり、あまりイケてない。

そこで一時ファイルを生成して、一時ファイルに対して処理を行う。

.f <- 'activity_type1'
.str_cmd <- paste0(".tmp <- fread('/path/to/datadir/", .f, ".csv', encoding='UTF-8', sep='\t', na.strings='')")
eval(parse(text=.str_cmd)) # .tmpという一時ファイルに代入
# .tmpに対する処理
.tmp %>% 
  mutate_at(vars(ends_with('_date')), as.Date) %>% 
  mutate_at(vars(ends_with('_type')), as.factor) %>% 
  mutate_if(is.logical, as.integer) -> .tmp
# .tmpの内容を個別の永続テーブルに入れる
.str_cmd <- paste0(".tmp -> t_", .f); eval(parse(text=.str_cmd))

.tmpに対する処理の部分が動的ではない普通のコマンドとなり、ソースコードの可読性も上がり、再利用やメンテナンスもしやすくなった。

シンプルなコマンド1行であれば動的にする必要もあまりないが、複数行のコマンドを繰り返し実行したい場合にはこの方法が力を発揮する。

forループの中で実行する

以上の例を複数のファイルに対して繰り返し実行する。
動的な部分をベクトルに代入し、forループの中に先の処理を入れる。

# 動的な部分の定義
filenames <- c('activity_type1', 'activity_type7', 'activity_click', 'event_unsubscribe', 'event_old')
# 繰り返し
for (.f in filenames) {
  # いったんdata.tableオブジェクトとして取り込む
  .str_cmd <- paste0("t_", .f, " <- fread('/path/to/datadir/", .f, ".csv', encoding='UTF-8', sep='\t', na.strings='')")
  eval(parse(text=.str_cmd))
  # 作業用オブジェクトを生成
  eval(parse(text=paste(".tmp <- t_", .f, sep="")))
  .tmp %>% 
    mutate_at(vars(ends_with('_date')), as.Date) %>% 
    mutate_at(vars(ends_with('_type')), as.factor) %>% 
    mutate_if(is.logical, as.integer) -> .tmp
  .tmp[mail_type %like% '購入お礼', c('mail_type', 'mail_type2', 'mail_type3', 'channel'):=data.table('SAF', '購入お礼', NA, NA)]
  # 作業用オブジェクトから元のオブジェクトに戻す
  eval(parse(text=paste0(".tmp -> t_", .f)))
}

ソースコードがかなり洗練される。

# 条件に合致したオブジェクトに対して一括処理
for (.i in ls(pattern='t1_.*_r_')) {
  .str_cmd <- paste('class(', .i, ') <- "matrix"', sep='')
  eval(parse(text=.str_cmd))
}

エラーが発生しても停止しない(try-catch)

try(for (i in unique(creatives.sampled$campaignId)) {
  for (j in adsize.sampled) {
    assign(paste0("result", i, "_", j, "_20161010"), myFunc(i, j, "2016-10-10"))
  }
})

オブジェクトの削除、ロード

rm(list=ls(pattern="^result.*")) # 正規表現にマッチしたオブジェクトのみ一括で削除
rm(list=ls(all=T)) # ドットで始まる隠しオブジェクトを含むすべてのオブジェクトを削除
for(f in system("ls prcomp*.RData", TRUE)) load(f) # ローカルの特定の形式に当てはまるファイル名のイメージを一括ロード

RのデータフレームとPandasのデータフレームの間でデータをやり取りする

RとPythonの間でのデータをやり取りするとき、CSVファイルではなく変数の型などを内包したデータフレームで直接やりとりできると便利。
これを実現するのがFeatherというライブラリ。

インストール

Rで

install.packages('feather')

Pythonで

pip install feather

使う

Rで

require(feather)
write_feather(iris, 'iris.feather') # 書き出し
iris2 <- read_feather('iris.feather') # 読み込み

Pythonで

import feather
iris.df = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv') # irisのデータセットを準備
feather.write_dataframe(iris.df, 'iris.feather') # 書き出し
iris.df = feather.read_dataframe('iris.feather') # 読み込み

Rで郵便番号マスタを作成する(データフレーム、data.table両対応)

分析用のデータの中には地域名がほしい形(都道府県名、市区町村名で区切られた形)で含まれておらず、一方で郵便番号が含まれていることもある。

その場合郵便番号から地域名を取得することになるが、その都度そのコードを書くのは面倒。
しかも郵便番号が更新されることもあるので、常に最新版を持ってくるようにしたい。

そこでコピペでそのまま郵便番号マスタを生成できるコードを用意した。
日本郵便の郵便番号データから最新版のCSVを取得してきて、郵便番号マスタを生成するものである。
これがあればRの中で常に最新版の郵便番号マスタを生成できる。
分析用データと結合して地域名を付けることも簡単である。

日本郵便の郵便番号データから最新版のCSVを取得する。
CSVファイルに含まれるカラムと形式の詳細は以下参照。

http://www.post.japanpost.jp/zipcode/dl/readme.html

必要なカラムのみ取得すればいい。
ここでは郵便番号(2列目)と市区町村コード(1列目)、都道府県名(7列目)、市区町村名(8列目)を取得する。なお郵便番号の形式はハイフンを含まない7ケタの数字列。

データフレームで読み込む場合

require(curl)
temp <- tempfile()
download.file("http://www.post.japanpost.jp/zipcode/dl/kogaki/zip/ken_all.zip", temp)
files <- unzip(temp)
df.zipcode <- read.csv(files[1], na.strings="", stringsAsFactors = FALSE, header=F, skip=0, fileEncoding = "shift-jis", colClasses = c("character", "NULL", "character", "NULL", "NULL", "NULL", "character", "character", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL"))
unlink(files)
unlink(temp)
rm(files, temp)
colnames(df.zipcode) <- c("citycode","zipcode","prefecture","city")

ちなみにdata.tableを使う場合はこんな感じ。
CSVファイルのエンコーディングがShift-JISでfread()が対応していないため、
一度read.csv()でデータフレームとして読み込んでからdata.tableに変換する。

data.tableで読み込む場合

require(curl)
require(data.table)
require(dplyr)
temp <- tempfile()
download.file("http://www.post.japanpost.jp/zipcode/dl/kogaki/zip/ken_all.zip", temp)
files <- unzip(temp)
read.csv(files[1], na.strings="", stringsAsFactors = FALSE, header=F, skip=0, fileEncoding = "shift-jis", colClasses = c("character", "NULL", "character", "NULL", "NULL", "NULL", "character", "character", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL")) %>% as.data.table -> dt.zipcode
unlink(files)
unlink(temp)
rm(files, temp)
setnames(dt.zipcode, "V1", "citycode")
setnames(dt.zipcode, "V3", "zipcode")
setnames(dt.zipcode, "V7", "prefecture")
setnames(dt.zipcode, "V8", "city")

こんなふうにすれば郵便番号を含むデータから都道府県、市区町村名も紐付けできる。
ちなみに元データの郵便番号の形式がハイフンを含む999-9999形式の場合

require(stringr)
dt.data<- dt.data %>% 
mutate(zipcode = str_replace(zipcode, "([0-9]{3})-([0-9]{4})", "\\1\\2")) %>% 
left_join(dt.zipcode)

モデルの選択

anova(単純なモデル, 複雑なモデル)

p-valueを見る

圧縮ファイルの読み込み

fread("gzip -dc df.txt")

多変量の可視化

表形式で―ftable()

度数で

ftable(Species ~ round(Sepal.Width) + round(Sepal.Length), data = iris)

                                       Species setosa versicolor virginica
round(Sepal.Width) round(Sepal.Length)                                    
2                  4                                1          0         0
                   5                                0          4         1
                   6                                0          9         3
                   7                                0          0         1
                   8                                0          0         0
3                  4                                4          0         0
                   5                               23          2         0
                   6                                0         27        24
                   7                                0          8        14
                   8                                0          0         4
4                  4                                0          0         0
                   5                               17          0         0
                   6                                5          0         0
                   7                                0          0         1
                   8                                0          0         2

比率で

round(prop.table(ftable(Species ~ round(Sepal.Width) + round(Sepal.Length), data = iris), margin=1) *100, 2)
  • margin=1で横方向の合計=1、margin=1で縦方向の合計=1とする。
  • useNA="no"でNAは集計対象から除外、useNA="always"でNAも集計対象に含める。

チャートで条件付散布図と箱ひげ図

条件付散布図

coplot(Sepal.Length ~ Sepal.Width | Species * Petal.Width, data=iris, panel = panel.smooth)

箱ひげ図

boxplot(Sepal.Length ~ Species + round(Petal.Width), data=iris, outline = FALSE)

高速化

  • apply()は内部でforの処理が入っている→
  • forが遅いのは、都度オブジェクトを拡張するから。for+rbind()などは最悪。
  • 最初にサイズを決めておくと速くなる。apply()を使うよりも速くなることもある。
  • ベクトル処理は高速
library(Rmpi)
library(snow)

# 1. apply (faster)
mat.matched <- mat.data==apply(mat.data, 1, max)

# 2. for (slower)
mat.matched <- matrix(nrow=nrow(mat.data), ncol=ncol(mat.data))
for(i in 1:nrow(mat.data)){ mat.matched[i,] <- mat.data[i,] == max(mat.data[i,]) }

# 3. parApply
cl <- makeCluster(4, type="SOCK")
clusterExport(cl, "mat.data")
mat.matched <- parApply(cl, mat.data, 1, max)
stopCluster(cl)

http://d.hatena.ne.jp/a_bicky/20120425/1335312593

blasの変更

yum install openblas
alternatives --install /usr/lib64/libblas.so.3 libblas.so.3 /usr/lib64/libopenblas.so.0 30
alternatives --install /usr/lib64/libblas.so.3 libblas.so.3 /usr/lib64/libblas.3.2.1 10
update-alternatives --config libblas.so.3

MPIのインストール

yum install -y openmpi-devel

事前にコマンドラインで環境変数をしてから

export LD_LIBRARY_PATH=/usr/lib64/openmpi/lib:$LD_LIBRARY_PATH
R

コンパイル時に3個の引数を渡す

install.packages("Rmpi", configure.args=c("--with-Rmpi-libpath=/usr/lib64/openmpi/lib", "--with-Rmpi-include=/usr/include/openmpi-x86_64", "--with-Rmpi-type=OPENMPI"))
library("Rmpi")
install.packages("snow")
library("snow")

参考
http://www.cybaea.net/Blogs/R-tips-Installing-Rmpi-on-Fedora-Linux.html

使い方
http://www.sfu.ca/~sblay/R/snow.html

Revolution R

  • Windowsではかなり速くなるがCentOSでは微妙
  • RevoMathはBLASにIntelのMKLを使って高速化(RROのインストール後にRevoMathをインストール)
  • 自動でマルチスレッド対応(HTは無視、純粋にコア数を見る)する。
  • 手動でやる場合は
library(RevoUtilsMath)
setMKLthreads(3)
  • getMKLthreads()でコア数を取得

RROではレポジトリが結構前の日付で固定されている。
最新版のパッケージをインストールしたい場合は

options(repos = c(CRAN = "https://mran.revolutionanalytics.com/snapshot/YYYY-MM-DD"))

を実行してからinstall.packages()を実行する。

caretが使っている

  • doMC (mac / unix)
  • doParallel (windows)

メモリ節約

sparse matix

要素のほとんどがゼロの行列→sparse matrix
普通のmatrixやデータフレーム形式で扱うとすべてのセルに対してメモリが割り当てられる
つまり行数×列数だけのメモリが消費される

ログデータを集計したもの(1000万UID×10万アイテム)などではメモリが足りないことに
行数と列数は膨大な割りに、実は値(の入るところ)が少ない→sparse matrix(疎行列)

もっと効率的にメモリを扱えないものか…値の入るセルだけメモリを使えないものか…
→これを実現したのが{Matrix}パッケージのsparse matrix形式(dgCMatrixクラスなど)

.Optionsでいろいろ

デフォルトでstringsAsFactors=FALSEにする。options()で設定しておくほうがいい

NAに対する処理

na.rm

  • NAを除外
  • 集計関数(max(), min(), range(), mean(), median(), quantile(), var())で使用。NAが入っているとデフォルトではNAを返すが、na.rm=TNAを除外してカウントする
  • cov(), cor()ではna.rmを指定できないので
cov(x[!is.na(x)], y[!is.na(y)])

とする。

na.omit

  • NAを含む行を除外
  • データフレームで使う
x <- data.frame(a=1:3, b=c(2,NA,4), c=rep(3,3))
na.omit(x)

tapply()よりaggregate()が使いやすい

aggregate(nExpected ~ category + type + audience + period, data = data1, FUN = sum)

aggregate(
    cbind(imp, click, cv) ~ segmentId + creativeId, 
    data = creatives.sampled, 
    FUN = sum
)

このようにformulaを使った集計ができるし、アウトプットもデータフレームになる。tapply()だと多次元配列になり扱いにくい。

tapply()の戻り値はarray

save()write.table()の引数の与え方の違い

似た処理なのに同じ引数の与え方で異なる挙動

Rのサンプルデータのわかりやすい解説

WindowsでR

RとRtoolsはスペースを含まないパスに設置する。
\Program Filesなどはダメ。コンパイルエラーになることがある

Macなどとの互換性のためにWindowsでは必須

options(encoding='UTF-8')

Rstanのインストール

Windows

Rtoolsが必要。

Rtoolsのインストール

Rtoolsのインストール後、システムのPATHに

C:\rtools40\usr\bin

を追加しないとmakeがないエラーになる。以下を実行すると起動時に読み込む.Renvironを生成してくれる

writeLines('PATH="${RTOOLS40_HOME}\\usr\\bin;${PATH}"', con = "~/.Renviron")

確認

Sys.which("make")

Rstanのインストール

install.packages("rstan", repos = "https://cloud.r-project.org/", type="win.binary")

R-4.0.2でRstanの2.21.xのバイナリは使えない。Stanのモデル構築時にundefined reference torstan::stan_fit::stan_fit(SEXPREC*, int)’`のエラーが発生する。
ソースからコンパイルする

remove.packages(c("StanHeaders", "rstan"))
dotR <- file.path(Sys.getenv("HOME"), ".R")
if (!file.exists(dotR)) dir.create(dotR)
M <- file.path(dotR, "Makevars.win")
if (!file.exists(M)) file.create(M)
cat("\n CXX14FLAGS += -mtune=native -O3 -mmmx -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2",
    file = M, sep = "\n", append = FALSE)
Sys.setenv(MAKEFLAGS = paste0("-j", parallel::detectCores()))
install.packages(c("StanHeaders", "rstan"), repos = "https://cloud.r-project.org/", type="source")

MROだと途中で使うRscript.exeが初期メッセージを表示するためエラーになる。
対応しても違うエラーが発生中

パッケージ管理

# そのセッション内では永続的に
options(Ncpus=4) # 4コアを使って同時に複数パッケージをコンパイル
options(repos = c(CRAN = "https://mran.revolutionanalytics.com/snapshot/YYYY-MM-DD")) # 特定の日付を指定
options(repos = c("https://mc-stan.org/r-packages/", getOption("repos"))) # レポジトリの追加

# そのパッケージ限りで
## レポジトリを指定してインストール
install.packages("xml2", repos("https://mran.revolutionanalytics.com/snapshot/YYYY-MM-DD")) # 特定の日付を指定
install.packages("cmdstanr", repos = c("https://mc-stan.org/r-packages/", getOption("repos"))) # レポジトリの追加

## ソースかバイナリか
install.packages("xml2", repos("https://mc-stan.org/r-packages/"), type='source') # ソースからコンパイル
install.packages("xml2", repos("https://mc-stan.org/r-packages/"), type='win.binary') # バイナリ

## コンパイル時のオプションの指定
install.packages("xml2", configure.vars = "INCLUDE_DIR=/usr/include/libxml2/libxml LIB_DIR=/usr/lib/x86_64-linux-gnu")
install.packages("xml2", configure.args = '--enable-aaa --bbb=bb')

バージョン指定

devtools::install_version("rstan", version = "2.18.1", repos = "http://cran.us.r-project.org")

パッケージを保持してRをアップグレード

R自体をアップグレードすると、古いバージョンで使っていたパッケージが削除されてしまう。
それを防ぐ方法。

  1. Rをアップグレードする前に現在のパッケージの一覧を一時ファイルに保存しておく
tmp <- installed.packages()
installedpkgs <- as.vector(tmp[is.na(tmp[,"Priority"]), 1])
save(installedpkgs, file="installed_old.rda")
  1. Rの新しいバージョンをインストールする

  2. 新しいバージョンのRを起動し、先に保存した古いパッケージ一覧を読み込んでCRANから再インストール

tmp <- installed.packages()
installedpkgs.new <- as.vector(tmp[is.na(tmp[,"Priority"]), 1])
missing <- setdiff(installedpkgs, installedpkgs.new)
install.packages(missing)
update.packages()
  1. BioConductorのパッケージを使っている場合、追加で以下を実行
chooseBioCmirror()
biocLite() 
load("installed_old.rda")
tmp <- installed.packages()
installedpkgs.new <- as.vector(tmp[is.na(tmp[,"Priority"]), 1])
missing <- setdiff(installedpkgs, installedpkgs.new)
for (i in 1:length(missing)) biocLite(missing[i])

https://www.r-bloggers.com/how-to-upgrade-r-without-losing-your-packages/

データの加工や分析で使うRの使い方 の記事一覧