コードのベクトル化の重要性

効率的なRコードの書き方

Colin Gillespie

Jumping Rivers & Newcastle University

一般的なルール

  • R関数の呼び出しは最終的にCまたはFORTRANコードに到達する
    • そのコードは非常に高度に最適化されている

目標

  • 基礎となるCまたはFORTRANコードにできるだけ速くアクセスする。関数呼び出しは少ないほど良い。
効率的なRコードの書き方

ベクトル化関数

  • 多くのR関数はベクトル化されている
    • 単一の数値を受け取りベクトルを返す
rnorm(4)
-0.7247  0.2502  0.3510  0.6919
  • ベクトルを入力として受け取る
mean(c(36, 48))
42
効率的なRコードの書き方

乱数の生成

library(microbenchmark)
n <- 1e6
x <- vector("numeric", n)
microbenchmark(
    x <- rnorm(n),
    {
        for(i in seq_along(x))
            x[i] <- rnorm(1)
        },
    times = 10
)
# Unit: milliseconds
# expr        lq mean    uq  cld
# rnorm(n)    60   70    80  a
# Looping   2600 2700  2800   b

## Output trimmed for presentation

比較

x <- vector("numeric", n)
for(i in seq_along(x))
    x[i] <- rnorm(1)

x <- rnorm(n)
効率的なRコードの書き方

なぜループは遅いのか?

ループ処理
x <- vector("numeric", n)
for(i in seq_along(x))
    x[i] <- rnorm(1)
メモリ確保
x <- vector("numeric", n)
  • ループ:一度限りのコスト
  • ベクトル化:同程度
生成
  • ループrnorm()を百万回呼び出す
  • ベクトル化rnorm()を1回呼び出す
代入
  • ループ:代入メソッドを百万回呼び出す
  • ベクトル化:1回の代入
効率的なRコードの書き方

Rクラブ

Rクラブの第二のルール:可能な限りベクトル化ソリューションを使用すること。

効率的なRコードの書き方

練習しましょう!

効率的なRコードの書き方

Preparing Video For Download...