55 R
08/06
2 # # #
Rcppとは
R の関数を C++ で実装することを
可能にするパッケージ
Rcppを利用している
パッケージ数
パーセンテージ
700
600
500
400
300
200
100
0
8
6
4
2
0
2016201420122010
700以上のパッケージで利用されている
パッケージ数
%
1 RcppArmadillo 353992 0.0235
2 Rcpp 254575 0.0169
3 ggplot2 219765 0.0146
4 digest 179117 0.0119
5 stringr 171733 0.0114
6 plyr 170953 0.0113
7 stringi 170182 0.0113
8 scales 167722 0.0111
9 magrittr 159638 0.0106
10 gtable 150171 0.0099
最も多くダウンロードされている
パッケージのひとつ
DL数 割合
http://cran-logs.rstudio.com/ から
2016年4月にダウンロードされたパッケージのランキング
Hadleyverse
ggplot2 reshape2 plyr dplyr tidyr
stringr lubridate readr readxl haven
httr rvest xml2
T
Hadleyverse
ggplot2 reshape2 plyr dplyr tidyr
stringr lubridate readr readxl haven
httr rvest xml2
Rcpp に依存
T
Rcpp
Law of Hadleyverse
Dirk EddelbuettelRomain François Hadley Wickham
黒魔術言語C++
→まずは便利なところだけ勉強すればいい
→RStudio が(多少)わかりやすく表示してくれる
→ まぁ、否めないですね…
言語仕様が巨大になため習得に時間が掛かる
コンパイルエラーがわかりにくい
変数の型が複雑
C++のエラーの多くは
【変数の型】と【代入する値の型】の不一致による
E 55
Rcppのインストール
自作のRcpp関数を作成するためには
C++のコンパイラをインストールする必要がある
Windows
R のバージョンに合った Rtools をインストールする
Mac
ターミナルで次のコマンドを打つ
https://cran.r-project.org/bin/windows/Rtools/index.html
iUaVW)dW WUe ))[ deS
Win、Mac 共に R で
[ deS *bSU]S Wd “IUbb”
Rtoolsのインストール
基本的には対応する一番新しい Frozen バージョンを
インストールすれば良い
Rtoolsのインストール
インストール時に PATH の設定にチェックする
(コンパイラがインストールされた場所を R に教えるため)
ここ!
Rtoolsのインストール
: jd* WeW g #H; B#
P- !=6ooHca cS_ [ WdooIooI)/*/*-ooT[ ooi207 U6ooIeaa dooT[ 7 U6ooIeaa do
o_[ hR20ooT[ 7v wu
: djdeW_ # '' )g#
Ld[ Tf[ e)[ dbWUd*
=GDD = RA==9U6oIeaa do_[ hR20oT[ oARRn-* O
=GDD = RD GRNI;HH I9U6+Ieaa d+_[ hR20+T[ +**+ [TWiWU+ UU+i42R20)h20)
_[ h/.+0*5*/+ ea)hcSbbWc*WiW
v w
cWSV _aVW 6 bad[i
UU gWcd[a 0*5*/ i42R20)bad[i)dW ( <f[ e Tj E[ AN)N20 bca WUe
確認のため R で次のコマンドを入力し
下のような出力が得られたらOK
E 55
Rcpp のコードを書く場合には
の利用を強く推奨します
コード補完やエラー表示が親切なので
E 55
ファイル > New File > C++ File
適当な名前でファイルに保存して Source を押す!
E 55
: IUbb66dafcUW=bb # a]jaI*Ubb#
: e[_Wd ha 0.
P- 40
: e[_Wd ha U -(.(/
P- . 0 2
ファイル > New File > C++ File
適当な名前でファイルに保存して Source を押す!
Rcppで作成した関数は通常のR関数と同様に使用できる
E 55
// Rcpp を利用するために必要なヘッダファイル
#include <Rcpp.h>
// これを記述しない場合は Rcpp::NumericVector
// と書かないといけない
using namespace Rcpp;
// この記述の直下の関数がRから利用可能になる
// [[Rcpp::export]]
// 関数の定義
NumericVector timesTwo(NumericVector x) {
return x * 2;
}
/* C++ コード中にRのコードを埋め込める
コンパイル直後に自動で実行される
*/
/*** R
timesTwo(42)
*/
R と C++ の書き方の違い
ベクトルなどの要素番号は 0 から
変数や関数(の返値)のデータ型を指定する必要がある
文の最後に ; 必須
変数名や関数名に . ピリオドは使えない
値の代入は = のみ
関数の返値に return 必須
df_I 8) Xf Ue[a i l
df_ 8) ,
Xac ii [ i l
df_ 8) df_ ' ii
m
cWefc df_
m
ベンチマーク
実数ベクトルの合計値を求める
ベンチマーク
++ PPIUbb66Wibace
VafT W df_IUbb Ff_Wc[UMWUeac i l
[ e 9 i* W e 7
VafT W df_ 9 ,*,7
Xac [ e [9,7 [ 8 7 ''[ l
df_ 9 df_ ' iP[ 7
m
cWefc df_7
m
実数ベクトルの合計値を求める
ベンチマーク
実数ベクトルの合計値を求める
++ PPIUbb66b f [ d Ubb--
++ PPIUbb66Wibace
VafT W df_IUbb=bb-- Ff_Wc[UMWUeac i l
VafT W df_ 9 ,*,7
Xac VafT W ii 6 i l
df_ 9 df_ ' ii7
m
cWefc df_7
m
ベンチマーク
実数ベクトルの合計値を求める
++ PPIUbb66Wibace
VafT W df_IUbb f_ Ff_Wc[UMWUeac i l
cWefc df_ i 7
m
ベンチマーク
: cTW U _Sc]66TW U _Sc]
' df_I i (
' df_ i (
' df_IUbb i (
' df_IUbb=bb-- i (
' df_IUbb f Sc i (
' Ua f_ d9U !eWde!( !cWb [USe[a d!( !W SbdWV!( !cW Se[gW! (
' acVWc 9 FLDD(
' cWb [USe[a d9-,,
eWde cWb [USe[a d W SbdWV cW Se[gW
- df_I i -,, 1,*045 .30*/53
. df_ i -,, ,*.0/ -*/.-
/ df_IUbb i -,, ,*-5. -*,0/
0 df_IUbb=bb-- i -,, ,*.,. -*,54
1 df_IUbb f_ i -,, ,*-40 -*,,,
RcppはC言語で実装されたRの関数より速い場合がある
Rcppのデータ構造
Dataframe List S4
Vector Matrix
単に同じようなデータ構造が定義されているのではなく
Rのメモリにあるオブジェクトを直接操作できる
Rcppのデータ型
⃝⃝Matrix
値型
R
ベクトル
Rcpp
ベクトル
Rcpp
行列
Rcpp
スカラー
C++
スカラー
論理 logial LogicalVector LogicalMatrix - bool
整数 integer IntegerVector IntegerMatrix - int
実数 numeric NumericVector NumericMatrix - double
複素数 complex ComplexVector ComplexMatrix Rcomplex complex
文字列 character CharacterVector CharacterMatrix String string
日付 Date DateVector - Date -
日時 POSIXct DatetimeVector - Datetime time_t
@
Rcppでは
苦いC++を甘くするために
Rと同様に使える
関数や演算子が定義されている
Sugar 関数
ベクター関係
head, tail, rep_each, rep_len, rep, rev, seq_along, seq_len, cumsum, diff, pmin, pmax
確率分布
d/q/p/r 全てのRの提供する確率分布
数学関数
abs, acos, asin, atan, beta, ceil, ceiling, choose,cos, cosh, exp, expm1, factorial, floor, gamma,
lbeta, lchoose, lfactorial, lgamma, log, log10, log1p, pentagamma, psigamma, round, signif, sin,
sinh, sqrt, tan, tanh, tetragamma, trigamma, trunc
要約統計量
mean, min, max, sum, sd, var
値の検索
match, self_match, which_max, which_min
重複の値
duplicated, unique
apply 関数
lapply, sapply, mapply
論理値
ifelse, all, any
Sugar 演算子
ベクトル : ベクトル
i'jpi)jpi jpi+j
ベクトル : スカラー
.'ip.)ip. ipi+.
四則演算
ベクトル : ベクトル
i99jpi

9jpi:jpi:9j
ベクトル : スカラー
.99ip.

9ip.:ipi:9.
Sugar 演算子
比較演算
ベクトルの作成
++ g 8) cWb ,( -,
Ff_Wc[UMWUeac g -, 7
++ g 8) U -(.(/
++ PPIUbb66b f [ d Ubb--
Ff_Wc[UMWUeac g 9 l-(.(/m7
++ g 8) U i9-( j9.( k9/
Ff_Wc[UMWUeac g 9
Ff_Wc[UMWUeac66UcWSeW FS_WV "i", - (
FS_WV "j" 9. (
RP"k" 9/ 7
ベクトル要素へのアクセス
実数・整数・文字列・論理ベクトルでアクセス
Ff_Wc[UMWUeac [ 9 l,(.(0m7
C eW WcMWUeac [ 9 l,(.(0m7
= ScSUeWcMWUeac [ 9 l!i!(!j!(!k!m7
Da [US MWUeac [ 9 g:,7
Ff_Wc[UMWUeac c 9 gP[ 7
gP[ 9 gS 7
行列の作成
++ _ 8) _Sec[i ,( cah 9 .( Ua 9 /
Ff_Wc[UESec[i _ .( / 7
++ _ 8) _Sec[i g( cah 9 .( Ua 9 /
Ff_Wc[UESec[i _ .( / ( g*TW [ 7
行列の要素へのアクセス
++ , .
_ , ( . 7
++ ,
_ , ( R 7
++ .
_ R ( . 7
++ ,s- .s/
_ IS W ,(- ( IS W .(/ 7
データフレームの作成
>SeS cS_W VX 9
>SeS cS_W66UcWSeW g-(g.(g/ 7
++ {
>SeS cS_W66UcWSeW FS_WV ! -!( g- (
FS_WV ! .! 9g. (
RP! /! 9g/ 7
データフレームの要素へのアクセス
実数・整数・文字列・論理ベクトルでアクセス
>SeS cS_W VX- 9 VXPg 7
VXPg 9 VX.7
Ff_Wc[UMWUeac g- 9 VXP, 7
VXP!i! 9 g.7
実数・整数・文字列スカラーでアクセス
カラムの値には g- を介してアクセスする
VXP(- や VXP- P- などは駄目
D[de D 9
D[de66UcWSeW g-(g.(g/ 7
++ {
D[de66UcWSeW FS_WV ! -!( g- (
FS_WV ! .! 9g. (
RP! /! 9g/ 7
※ v1, v2, v3 の型やサイズは何でも良い
リストの作成
リストの要素へのアクセス
実数・整数・文字列・論理ベクトルでアクセス
D[de D- 9 DPg 7
DPg 9 D.7
Ff_Wc[UMWUeac g- 9 DP, 7
DP!i! 9 g.7
実数・整数・文字列スカラーでアクセス
リスト要素の要素には g- を介してアクセスする
MWUeac M
M* W e ++
M* S_Wd ++
ESec[i E
E* cah ++
E* Ua ++
cah S_Wd E ++
Ua S_Wd E ++
>SeS cS_W >
> * W e ++
> * S_Wd ++
> *Seec !cah* S_Wd! ++
D[de D
D* W e ++
D* S_Wd ++
ベクトルの長さや要素名など
属性値
MWUeac M
M*Seec ! S_Wd! ++
ESec[i E7
E*Seec !V[_! 9 C eW WcMWUeac66UcWSeW ( 7
E*Seec !V[_ S_Wd! 9 D[de66UcWSeW ( 7
>SeS cS_W > 7
> *Seec ! S_Wd! ++
> *Seec !cah* S_Wd! ++
D[de D7
D*Seec ! S_Wd! ++
Rの関数を呼び出す
f Ue[a X !c ac_! 7
Ff_Wc[UMWUeac cWd 9
X 1( FS_WV !_WS !(- ( FS_WV !dV!(. 7
g[ca _W e W g 9
g[ca _W e66 S_WdbSUWRW g ! r ! 7
f Ue[a X 9 W gP! ! 7
この方法でパッケージ関数を呼び出す場合は
library(パッケージ名) する必要がある
こちらは library(パッケージ名) する必要がない
55 R
Rcpp を使えば
R のコードを C++ に置き換えることも可能
ただ実装が面倒なのは事実なので
処理のボトルネックになっている部分に
適用するのが効果的
Rcpp学習のために
Rcpp Gallery
http://gallery.rcpp.org/
Rcpp Note
http://statr.me/rcpp-note/
Introduction to Rcpp(日本語)
https://www.gitbook.com/book/teuder/introduction-to-rcpp/details/ja
R言語徹底解説
(共立出版)
C++学習のために
Programming Place Plus
http://ppp-lab.sakura.ne.jp/ProgrammingPlacePlus/cpp/index.html
沢山ありすぎるので1つだけ
+ 1
Rcppの注意点
コンパイルした Rcpp 関数は RData に保存できない
新しいRのセッションの度に再コンパイルする
コンパイル済み関数を保存したい場合には
自作パッケージにする必要がある
Rcppの注意点
++ g- ~
Ff_Wc[UMWUeac g- 9 l-(.(/m7
++ g- g. ~
Ff_Wc[UMWUeac g. 9 g-7
++ g. ~
g.P, 9 57
++ g- ~
IUafe 88 g- 88 !o !7
++ g- z }  x t
++ 5 . /
Rcppの注意点
++ g- ~
Ff_Wc[UMWUeac g- 9 l-(.(/m7
++ g- g. U a W ~
Ff_Wc[UMWUeac g. 9 U a W g- 7
++ g. ~
g.P, 9 57
++ g- ~
IUafe 88 g- 88 !o !7
++ g- x
++ 5 . /
Rcppの注意点
メモリー
++ g- ~
Ff_Wc[UMWUeac g- 9 l-(.(/m7
g-
-(.(/
単純な代入のメカニズム
++ g- g. ~
Ff_Wc[UMWUeac g. 9 g-7
Rcppの注意点
メモリー
g-
-(.(/
g.
単純な代入のメカニズム
++ g. ~
g.P, 9 57
Rcppの注意点
メモリー
g-
5(.(/
g.
単純な代入のメカニズム
Rcppの注意点
メモリー
++ g- ~
Ff_Wc[UMWUeac g- 9 l-(.(/m7
g-
-(.(/
clone()を使った代入のメカニズム
++ g- g. U a W ~
Ff_Wc[UMWUeac g. 9 U a W g- 7o
Rcppの注意点
メモリー
g-
-(.(/
g.
-(.(/
clone()を使った代入のメカニズム
++ g. ~
g.P, 9 57
Rcppの注意点
メモリー
g-
-(.(/
g.
5(.(/
clone()を使った代入のメカニズム
Rcppの注意点
メモリー
++ g- ~
Ff_Wc[UMWUeac g- 9 l-(.(/m7
g-
-(.(/
関数の引数の一部の要素を変更するケース
++ g- IUbb X } y
++ ga[V X Ff_Wc[UMWUeac g. l tttt m
: X g-
Rcppの注意点
メモリー
g-
-(.(/
g.
関数の引数の一部の要素を変更するケース
++ X g. ~
++ ga[V X Ff_Wc[UMWUeac g. l g.P, 957 m
: X g-
: bc[ e g-
P- 5 . /
Rcppの注意点
メモリー
g-
5(.(/
g.
関数の引数の一部の要素を変更するケース
R の copy on modify
メモリー
" g- ~
g- 8) U -(.(/
g-
-(.(/
メモリー
g-
-(.(/
g.
R の copy on modify
" g- g. ~
g. 8) g-
メモリー
g-
-(.(/
g.
5(.(/
" g. ~
g.P- 8) 5
R の copy on modify
NAの扱い
Sugar関数・演算子は便利なだけではなく安全である
標準 C++ には NA は定義されていないので
R の NA 値をうまく扱えない
Sugar関数・演算子は R と同様の結果を返す
標準 C++ の int 同士の演算子
++ PPIUbb66Wibace
C eW WcMWUeac SVVR[ eW Wc C eW WcMWUeac i(
C eW WcMWUeac j
l
[ e 9 i* W e 7
C eW WcMWUeac k 7
Xac [ e [9,7 [8 7 ''[ l
kP[ 9 iP[ ' jP[ 7 ++ [ e ' [ e
m
cWefc k7
m
: i'j
P- F; .
: SVVR[ eW Wc i(j
P- ).-0304/203 .
: i 8) U - ( -
: j 8) U F;( -

あまぁいRcpp生活