== RCall.jl
参照 URL https://juliainterop.github.io/RCall.jl/stable/
RCall は,Julia から R 環境(R パッケージ)を利用したり,R 環境での作業結果を Julia へ取り込んだりすることができる。
== インストール
まだ RCall をインストールしていない場合は,以下の 2 行を実行。
julia> using Pkg
julia> Pkg.add("RCall")
== さあ始めよう
まず,最初に RCall パッケージをロードしよう。
他のパッケージと同じで,あるパッケージを使いたいときにはそのセッションの最初に「using パッケージ名」と指定する。
julia> using RCall
== RCall の使い方
Julia と R の相互作用のために,RCall は複数の方法を提供する。
- R の REPL モード
- @rput と @get マクロ
- R"文字列" マクロ
- RCall API: reval, rcall, rcopy, robject など
- @rlibrary と @rimport マクロ
== R の REPL モード
Julia のプロンプトが出ているときに $ を押すと,R の REPL モードに移行する(プロンプトが julia> から R> に変わる)。
R から Julia に戻るときは delete キー(Windows の場合は backspaceキー)を」押す(プロンプトがR> から julia> に戻る)。
R の REPL モードで Julia の変数(オブジエクト)を引用するときには「$変数名」,「$]式」のようにする。
julia の println() で,文字列中に $変数名 と書けばその値で置き換えられるのと同じような使い方である。
julia> foo = 1
1
$ キーを押す
R> x <- $foo
R> x
[1] 1
R> y = $(rand(10))
R> sum(y)
[1] 5.234343
delete キーを押す
julia>
== @rput マクロと @rget マクロ
これらのマクロは,Julia と R の間で変数を転送する。
コピーされた変数は元の変数と同じ名前になる。
julia> z = 1
1
julia> @rput z
1
R> z
[1] 1
R> r = 2
julia> @rget r
2.0
julia> r 2.0
一行で複数の変数をやり取りすることもできる。
julia> foo = 2
2
julia> bar = 4
4
julia> @rput foo bar
4
R> foo + bar
[1] 6
== @R_str 文字列マクロ
RCall の別の使い方は R"文字列" マクロである。
これは特にスクリプトファイルで有用である。
julia> R"rnorm(10)" # プロンプトは julia> の状態で使う
RObject{RealSxp}
[1] 2.12249461 0.09807257 -2.28437327 ...
[7] -0.49853088 1.16451855 -0.41658982 ...
このような使い方をすると,文字列を R の式とみなし,R での評価結果を Julia のラッパーでくるんだ RObject として返す。
R"文字列" マクロは変数代入(\latexmath:[$変数名)をサポートする。
aa\\$]bb のような R の式としては不適切な場合にさえも使うことができる。
julia> x = randn(10)
10-element Array{Float64,1}:
-2.8182219563281503
0.8334083608216333
-1.2866572484420662
-0.719998093988448
1.3888582310416397
0.45538366532280794
0.26108314692800977
-0.2748229904314617
-0.9151614036341179
1.1915882754899525
julia> R"t.test($x)"
RObject{VecSxp}
One Sample t-test
data: `#JL`$x
t = -0.46172, df = 9, p-value = 0.6552
alternative hypothesis: true mean is not equal to 0
95 percent confidence interval:
-1.1117626 0.7348546
sample estimates:
mean of x
-0.188454
Julia で評価される前の式を R に渡すこともできる。
このような場合には ( ) でくくる必要がある。
なお,以下の例では文字列をくくるのに二重引用符 " をつかっているが,その中の文字列中に出てくる文字列は一重引用符 ’を使う例を示している。
一重引用符の代わりに「エスケープ付の二重引用符 \"」を使ってもよい。
外側の引用符は二重引用符でなければならない(一重引用符を使うとエラーになる)。
julia> R"optim(0, $(x -> x-cos(x)), method='BFGS')"
RObject{VecSxp}
$par
[1] -1.56343
$value
[1] -1.570796
$counts
function gradient
14 13
$convergence
[1] 0
$message
NULL
複数行にわたるような文字列スクリプトは,(Python と同じ)三重引用符(二重引用符を3個連続)を使う。
julia> y = 1
1
julia> R"""
f <- function(x, y) x + y
ret <- f(1, $y)
"""
RObject{RealSxp}
[1] 2
== RCall API
reval 関数は,入力された文字列を R コードとして評価する。
評価結果は RObject として返される。
julia> jmtcars = reval("mtcars");
julia> typeof(jmtcars)
RObject{VecSxp}
julia> names(jmtcars)
11-element Array{Symbol,1}:
:mpg
:cyl
:disp
:hp
:drat
:wt
:qsec
:vs
:am
:gear
:carb
julia> jmtcars[:mpg]
RObject{RealSxp}
[1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 ...
[16] 10.4 14.7 32.4 30.4 33.9 21.5 15.5 15.2 ...
[31] 15.0 21.4
julia> df = rcopy(jmtcars); # データフレームに変換
julia> first(df, 5)
5×11 DataFrame
Row │ mpg cyl disp hp drat ...
│ Float64 Float64 Float64 Float64 Float64 ...
─────┼──────────────────────────────────────────────────
1 │ 21.0 6.0 160.0 110.0 3.9 ...
2 │ 21.0 6.0 160.0 110.0 3.9 ...
3 │ 22.8 4.0 108.0 93.0 3.85 ...
4 │ 21.4 6.0 258.0 110.0 3.08 ...
5 │ 18.7 8.0 360.0 175.0 3.15 ...
rcall 関数は関数呼び出しのために使用される。
jmtcars の次元サイズを求め RObject に変換する
julia> rcall(:dim, jmtcars)
RObject{IntSxp}
[1] 32 11
引数は暗黙的に評価され RObject に変換される。
ベクトルの和を求め RObject に変換する
julia> rcall(:sum, Float64[1.0, 4.0, 6.0])
RObject{RealSxp}
[1] 11
rcopy 関数はRObject を Julia のオブジェクトに変換する。
豊富な発見的手法に基づいて,もっとも適切な Julia の型に変換する。
julia> rcopy(R"c(1)")
1.0
julia> rcopy(R"c(1, 2)")
2-element Array{Float64,1}:
1.0
2.0
julia> rcopy(R"list(1, 'zz')")
2-element Array{Any,1}:
1.0
"zz"
julia> rcopy(R"list(a = 1, b= 'zz')")
OrderedCollections.OrderedDict{Symbol,Any} with 2 entries:
:a => 1.0
:b => "zz"
特定の型変換をするために,第 1 引数として型を指定することができる。
julia> rcopy(Array{Int}, R"c(1, 2)")
2-element Array{Int64,1}:
1
2
robject 関数はあらゆる Julia オブジェクトを RObject に変換する。
julia> robject(1)
RObject{IntSxp}
[1] 1
julia> robject(Dict(:a => 1, :b => 2))
RObject{VecSxp}
$a
[1] 1
$b
[1] 2
== @rlibrary マクロと @import マクロ
このマクロは,全てのエクスポートされた R パッケージ中の関数およびオブジェクトを現在のモジュールにロードする。
julia> @rlibrary boot
julia> city = rcopy(R"boot::city") # get some data
10×2 DataFrame
│ Row │ u │ x │
│ │ Float64│ Float64│
├──────┼────────┼────────┤
│ 1 │ 138.0 │ 143.0 │
│ 2 │ 93.0 │ 104.0 │
│ 3 │ 61.0 │ 69.0 │
│ 4 │ 179.0 │ 260.0 │
│ 5 │ 48.0 │ 75.0 │
│ 6 │ 37.0 │ 63.0 │
│ 7 │ 29.0 │ 50.0 │
│ 8 │ 23.0 │ 48.0 │
│ 9 │ 30.0 │ 111.0 │
│ 10 │ 2.0 │ 50.0 │
julia> ratio(d, w) = sum(d[!, :x] .* w)/sum(d[!, :u] .* w)
ratio (generic function with 1 method)
julia> b = boot(city, ratio, R = 100, stype = "w");
julia> rcall(:summary, b[:t])
RObject{StrSxp}
V1
Min. :1.274
1st Qu.:1.449
Median :1.543
Mean :1.572
3rd Qu.:1.638
Max. :2.178
当然ではあるが,データは R と Julia の間で何回もコピーされるので,余りにも非効率である。
効率性の面からは,R"文字列" マクロを使うことをお勧めする。
いくつかの R 関数はドットを含むキーワード引数を持っている。
RCall はこれらのキーワードをエスケープするために,文字列マクロ「var"ドットを含む引き数名"」を提供する。
julia> @rimport base as rbase
julia> rbase.sum([1, 2, 3], var"rm.na" = true)
RObject{IntSxp}
[1] 7
※コメント投稿者のブログIDはブログ作成者のみに通知されます