裏 RjpWiki

Julia ときどき R, Python によるコンピュータプログラム,コンピュータ・サイエンス,統計学

Julia で R を使う(その1)

2021年01月29日 | ブログラミング

== 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

コメント    この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« MATLAB プログラムを Julia ... | トップ | Julia で R を使う(その2) »
最新の画像もっと見る

コメントを投稿

ブログラミング」カテゴリの最新記事