最近こんな感じの記事ばかり見かけます。RとPythonどっちが良いの?ってやつ。
どの言語いいかなんて一長一短だし,ほんと不毛だとおもいます。この不毛な争いを解決すべく,Juliaを使う人も多いはず(?)
Juliaから他の言語を呼び出せることは前から知っていたのですが,ちゃんといじったことがなかったので,今回はトライしてみます。ちなみにRからもJuliaは動かせますし,Pythonからも動かせるらしいです。
# set up
using Pkg
Pkg.add("RCall")
using RCall
R version 3.6.0 (2019-04-26) -- "Planting of a Tree" Copyright (C) 2019 The R Foundation for Statistical Computing Platform: x86_64-w64-mingw32/x64 (64-bit) R is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under certain conditions. Type 'license()' or 'licence()' for distribution details. R is a collaborative project with many contributors. Type 'contributors()' for more information and 'citation()' on how to cite R or R packages in publications. Type 'demo()' for some demos, 'help()' for on-line help, or 'help.start()' for an HTML browser interface to help. Type 'q()' to quit R.
基本的にはこれでOKですが,時々precompileでエラーを吐きます。エラーではPkg.buildしろって言われるのですが,Pkg.Build
してもこんなエラーがでてくるときがあります。
{Julia}
> LoadError: R cannot be found. Set the "R_HOME" environment variable to re-run Pkg.build("RCall").
JuliaのENVにRのパスが通っていなかったりしますので,こんな設定が必要になるかもしれません。JuliaのENVにRのパスであるR_HOME
がないことを確認し,新しくRのパスを通してあげます。binまではいらないので,Rの各バージョンがあるディレクトリまでで十分です。
{Julia}
ENV["R_HOME"] # missing R ENV
show(ENV)
ENV["R_HOME"]="C:\\hoge\\huga\\Documents\\R\\R-3.6.0" # binまでは通さない。
Pkg.build("RCall") # rebuild
ちなみにENVにパスを通すのは毎回起動するたびにやらなきゃいけないみたいです。~/.julia/congig/startup.jlにパスを通すコードを書いておけば毎回起動時に通しておいてくれるので便利です。
そんなに難しくなく,基本は(1)juliaからRに変数を渡す,(2)Rで変数を操作する,(3)R変数をJuliaに渡す,というステップです。その逆も可能です。つまりR to JuliaもJulia to Rもできます。
書き方は,@bicycle1885さんがすでにまとめてくれています。
rcopy(R"1:5") # get R eval
5-element Array{Int64,1}: 1 2 3 4 5
x = 3.0
R"1 + $x" # An inline R expression
RObject{RealSxp} [1] 4
x = 10
@rput x
R"r = rnorm(x)"
@rget r
r'
1×10 LinearAlgebra.Adjoint{Float64,Array{Float64,1}}: 0.383796 0.868393 0.231633 0.298366 … -1.35082 0.12759 -0.887251
rcopy(R"1 + $x")
# multiple lines
R"""
n = 100 + 1
r = rnorm(n)
plot(c(1:n), r, type = "l")
"""
RObject{NilSxp} NULL
Juliaのloopの中にRを忍ばせることもできるので,モンテカルロシミュレーションなどをやるときに,「Rのパッケージを使って分析したいけど,重たい処理はJuliaでやりたい」ってときに便利かもしれません。
for i in 1:10
@rput i
R"""
cat("The iteration time is",i,"in R")
t = i
"""
@rget t
println(", and $t in Julia.")
end
The iteration time is 1 in R, and 1 in Julia. The iteration time is 2 in R, and 2 in Julia. The iteration time is 3 in R, and 3 in Julia. The iteration time is 4 in R, and 4 in Julia. The iteration time is 5 in R, and 5 in Julia. The iteration time is 6 in R, and 6 in Julia. The iteration time is 7 in R, and 7 in Julia. The iteration time is 8 in R, and 8 in Julia. The iteration time is 9 in R, and 9 in Julia. The iteration time is 10 in R, and 10 in Julia.
reval
およびrcall
関数を使えば,Julia上でRのデータや関数を扱うことができます。
たとえばデータフレームやtibbleも使えます。
iris = reval("iris")
RObject{VecSxp} Sepal.Length Sepal.Width Petal.Length Petal.Width Species 1 5.1 3.5 1.4 0.2 setosa 2 4.9 3.0 1.4 0.2 setosa 3 4.7 3.2 1.3 0.2 setosa 4 4.6 3.1 1.5 0.2 setosa 5 5.0 3.6 1.4 0.2 setosa 6 5.4 3.9 1.7 0.4 setosa 7 4.6 3.4 1.4 0.3 setosa 8 5.0 3.4 1.5 0.2 setosa 9 4.4 2.9 1.4 0.2 setosa 10 4.9 3.1 1.5 0.1 setosa 11 5.4 3.7 1.5 0.2 setosa 12 4.8 3.4 1.6 0.2 setosa 13 4.8 3.0 1.4 0.1 setosa 14 4.3 3.0 1.1 0.1 setosa 15 5.8 4.0 1.2 0.2 setosa 16 5.7 4.4 1.5 0.4 setosa 17 5.4 3.9 1.3 0.4 setosa 18 5.1 3.5 1.4 0.3 setosa 19 5.7 3.8 1.7 0.3 setosa 20 5.1 3.8 1.5 0.3 setosa 21 5.4 3.4 1.7 0.2 setosa 22 5.1 3.7 1.5 0.4 setosa 23 4.6 3.6 1.0 0.2 setosa 24 5.1 3.3 1.7 0.5 setosa 25 4.8 3.4 1.9 0.2 setosa 26 5.0 3.0 1.6 0.2 setosa 27 5.0 3.4 1.6 0.4 setosa 28 5.2 3.5 1.5 0.2 setosa 29 5.2 3.4 1.4 0.2 setosa 30 4.7 3.2 1.6 0.2 setosa 31 4.8 3.1 1.6 0.2 setosa 32 5.4 3.4 1.5 0.4 setosa 33 5.2 4.1 1.5 0.1 setosa 34 5.5 4.2 1.4 0.2 setosa 35 4.9 3.1 1.5 0.2 setosa 36 5.0 3.2 1.2 0.2 setosa 37 5.5 3.5 1.3 0.2 setosa 38 4.9 3.6 1.4 0.1 setosa 39 4.4 3.0 1.3 0.2 setosa 40 5.1 3.4 1.5 0.2 setosa 41 5.0 3.5 1.3 0.3 setosa 42 4.5 2.3 1.3 0.3 setosa 43 4.4 3.2 1.3 0.2 setosa 44 5.0 3.5 1.6 0.6 setosa 45 5.1 3.8 1.9 0.4 setosa 46 4.8 3.0 1.4 0.3 setosa 47 5.1 3.8 1.6 0.2 setosa 48 4.6 3.2 1.4 0.2 setosa 49 5.3 3.7 1.5 0.2 setosa 50 5.0 3.3 1.4 0.2 setosa 51 7.0 3.2 4.7 1.4 versicolor 52 6.4 3.2 4.5 1.5 versicolor 53 6.9 3.1 4.9 1.5 versicolor 54 5.5 2.3 4.0 1.3 versicolor 55 6.5 2.8 4.6 1.5 versicolor 56 5.7 2.8 4.5 1.3 versicolor 57 6.3 3.3 4.7 1.6 versicolor 58 4.9 2.4 3.3 1.0 versicolor 59 6.6 2.9 4.6 1.3 versicolor 60 5.2 2.7 3.9 1.4 versicolor 61 5.0 2.0 3.5 1.0 versicolor 62 5.9 3.0 4.2 1.5 versicolor 63 6.0 2.2 4.0 1.0 versicolor 64 6.1 2.9 4.7 1.4 versicolor 65 5.6 2.9 3.6 1.3 versicolor 66 6.7 3.1 4.4 1.4 versicolor 67 5.6 3.0 4.5 1.5 versicolor 68 5.8 2.7 4.1 1.0 versicolor 69 6.2 2.2 4.5 1.5 versicolor 70 5.6 2.5 3.9 1.1 versicolor 71 5.9 3.2 4.8 1.8 versicolor 72 6.1 2.8 4.0 1.3 versicolor 73 6.3 2.5 4.9 1.5 versicolor 74 6.1 2.8 4.7 1.2 versicolor 75 6.4 2.9 4.3 1.3 versicolor 76 6.6 3.0 4.4 1.4 versicolor 77 6.8 2.8 4.8 1.4 versicolor 78 6.7 3.0 5.0 1.7 versicolor 79 6.0 2.9 4.5 1.5 versicolor 80 5.7 2.6 3.5 1.0 versicolor 81 5.5 2.4 3.8 1.1 versicolor 82 5.5 2.4 3.7 1.0 versicolor 83 5.8 2.7 3.9 1.2 versicolor 84 6.0 2.7 5.1 1.6 versicolor 85 5.4 3.0 4.5 1.5 versicolor 86 6.0 3.4 4.5 1.6 versicolor 87 6.7 3.1 4.7 1.5 versicolor 88 6.3 2.3 4.4 1.3 versicolor 89 5.6 3.0 4.1 1.3 versicolor 90 5.5 2.5 4.0 1.3 versicolor 91 5.5 2.6 4.4 1.2 versicolor 92 6.1 3.0 4.6 1.4 versicolor 93 5.8 2.6 4.0 1.2 versicolor 94 5.0 2.3 3.3 1.0 versicolor 95 5.6 2.7 4.2 1.3 versicolor 96 5.7 3.0 4.2 1.2 versicolor 97 5.7 2.9 4.2 1.3 versicolor 98 6.2 2.9 4.3 1.3 versicolor 99 5.1 2.5 3.0 1.1 versicolor 100 5.7 2.8 4.1 1.3 versicolor 101 6.3 3.3 6.0 2.5 virginica 102 5.8 2.7 5.1 1.9 virginica 103 7.1 3.0 5.9 2.1 virginica 104 6.3 2.9 5.6 1.8 virginica 105 6.5 3.0 5.8 2.2 virginica 106 7.6 3.0 6.6 2.1 virginica 107 4.9 2.5 4.5 1.7 virginica 108 7.3 2.9 6.3 1.8 virginica 109 6.7 2.5 5.8 1.8 virginica 110 7.2 3.6 6.1 2.5 virginica 111 6.5 3.2 5.1 2.0 virginica 112 6.4 2.7 5.3 1.9 virginica 113 6.8 3.0 5.5 2.1 virginica 114 5.7 2.5 5.0 2.0 virginica 115 5.8 2.8 5.1 2.4 virginica 116 6.4 3.2 5.3 2.3 virginica 117 6.5 3.0 5.5 1.8 virginica 118 7.7 3.8 6.7 2.2 virginica 119 7.7 2.6 6.9 2.3 virginica 120 6.0 2.2 5.0 1.5 virginica 121 6.9 3.2 5.7 2.3 virginica 122 5.6 2.8 4.9 2.0 virginica 123 7.7 2.8 6.7 2.0 virginica 124 6.3 2.7 4.9 1.8 virginica 125 6.7 3.3 5.7 2.1 virginica 126 7.2 3.2 6.0 1.8 virginica 127 6.2 2.8 4.8 1.8 virginica 128 6.1 3.0 4.9 1.8 virginica 129 6.4 2.8 5.6 2.1 virginica 130 7.2 3.0 5.8 1.6 virginica 131 7.4 2.8 6.1 1.9 virginica 132 7.9 3.8 6.4 2.0 virginica 133 6.4 2.8 5.6 2.2 virginica 134 6.3 2.8 5.1 1.5 virginica 135 6.1 2.6 5.6 1.4 virginica 136 7.7 3.0 6.1 2.3 virginica 137 6.3 3.4 5.6 2.4 virginica 138 6.4 3.1 5.5 1.8 virginica 139 6.0 3.0 4.8 1.8 virginica 140 6.9 3.1 5.4 2.1 virginica 141 6.7 3.1 5.6 2.4 virginica 142 6.9 3.1 5.1 2.3 virginica 143 5.8 2.7 5.1 1.9 virginica 144 6.8 3.2 5.9 2.3 virginica 145 6.7 3.3 5.7 2.5 virginica 146 6.7 3.0 5.2 2.3 virginica 147 6.3 2.5 5.0 1.9 virginica 148 6.5 3.0 5.2 2.0 virginica 149 6.2 3.4 5.4 2.3 virginica 150 5.9 3.0 5.1 1.8 virginica
starwars = reval("starwars")
RObject{VecSxp} # A tibble: 87 x 13 name height mass hair_color skin_color eye_color birth_year gender <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> 1 Luke~ 172 77 blond fair blue 19 male 2 C-3PO 167 75 <NA> gold yellow 112 <NA> 3 R2-D2 96 32 <NA> white, bl~ red 33 <NA> 4 Dart~ 202 136 none white yellow 41.9 male 5 Leia~ 150 49 brown light brown 19 female 6 Owen~ 178 120 brown, gr~ light blue 52 male 7 Beru~ 165 75 brown light blue 47 female 8 R5-D4 97 32 <NA> white, red red NA <NA> 9 Bigg~ 183 84 black light brown 24 male 10 Obi-~ 182 77 auburn, w~ fair blue-gray 57 male # ... with 77 more rows, and 5 more variables: homeworld <chr>, species <chr>, # films <list>, vehicles <list>, starships <list>
もちろん変数にもアクセスできる。
starwars["name"][1]
RObject{CharSxp} <CHARSXP: "Luke Skywalker">
# using R function
rcall(:plot, [1:100;], rand(100), type = "l", ylab = "rand")
rcall(:sum, [1:10;])
RObject{IntSxp} [1] 55
パッケージを使いたいときは,一応@rlibrary
や@rimport
といったマクロを使えますが,公式的にはトリプルクオーテーションで囲むのが良いとのこと。
http://juliainterop.github.io/RCall.jl/stable/gettingstarted#@rlibrary-and-@rimport-macros-1
# using R package
R"""
library(tidyverse)
ggplot(tibble(x = seq(-4, 4, len = 101), prob = dnorm(seq(-4, 4, len = 101))), aes(x = x, y = prob)) +
geom_line()
"""
RObject{VecSxp}
いままではR一択で分析していたのですが,ここまで簡単にJuliaからRが使えると,もはや言語の壁はありませんね。