GitHub - JuliaInterop/JuliaCall: Embed Julia in R (original) (raw)
JuliaCall for Seamless Integration of R and Julia
[Table of Contents]
Package JuliaCall
is an R interface to Julia
, which is a high-level, high-performance dynamic programming language for numerical computing, see https://julialang.org/ for more information. Below is an image forMandelbrot set. JuliaCall brings more than 100 times speedup of the calculation! Seehttps://github.com/JuliaInterop/JuliaCall/tree/master/example/mandelbrotfor more information.
Installation
You can install JuliaCall
just like any other R packages by
install.packages("JuliaCall")
To use JuliaCall
you must have a working installation of Julia. This can be easily done via:
library(JuliaCall) install_julia()
which will automatically install and setup a version of Julia specifically for use with JuliaCall. Or you can do
library(JuliaCall) julia_setup(installJulia = TRUE)
which will invoke install_julia
automatically if Julia is not found and also do initialization of JuliaCall
.
You can also setup Julia manually by downloading a generic binary fromhttps://julialang.org/downloads/ and add it to your path. CurrentlyJulia v0.6.x
and the Julia v1.x
releases are all supported byJuliaCall
.
You can get the development version of JuliaCall
by
devtools::install_github("JuliaInterop/JuliaCall")
Basic Usage
Before using JuliaCall
, you need to do initial setup by functionjulia_setup()
for automatic type conversion, Julia display systems, etc. It is necessary for every new R session to use the package. If not carried out manually, it will be invoked automatically before otherjulia_xxx
functions. Solutions to some common error in julia_setup()
are documented in the troubleshooting section.
library(JuliaCall) julia <- julia_setup() #> Julia version 1.11.1 at location C:\Users\lichangcheng.julia\juliaup\julia-1.11.1+0.x64.w64.mingw32\bin will be used. #> Loading setup script for JuliaCall... #> Finish loading setup script for JuliaCall.
If you want to use Julia
at a specific location, you could do the following:
julia_setup(JULIA_HOME = "the folder that contains Julia binary").
You can also set JULIA_HOME in command line environment or use options(...)
.
Different ways of using Julia to calculate sqrt(2)
julia$command("a = sqrt(2);"); julia$eval("a")
julia_command("a = sqrt(2);"); julia_eval("a") #> [1] 1.414214 julia_eval("sqrt(2)") #> [1] 1.414214 julia_call("sqrt", 2) #> [1] 1.414214 julia_eval("sqrt")(2) #> [1] 1.414214 julia_assign("x", sqrt(2)); julia_eval("x") #> [1] 1.414214 julia_assign("rsqrt", sqrt); julia_call("rsqrt", 2) #> [1] 1.414214 2 %>J% sqrt #> [1] 1.414214
You can use julia$exists
as exists
in R to test
whether a function or name exists in Julia or not
julia_exists("sqrt") #> [1] TRUE julia_exists("c") #> [1] FALSE
Functions related to installing and using Julia packages
julia_install_package_if_needed("Optim") julia_installed_package("Optim") #> [1] "1.9.4" julia_library("Optim")
Troubleshooting and Ways to Get Help
Julia is not found
Make sure the Julia
installation is correct. JuliaCall
can findJulia
on PATH, and there are three ways for JuliaCall
to findJulia
not on PATH.
- Use
julia_setup(JULIA_HOME = "the folder that contains julia binary")
- Use
options(JULIA_HOME = "the folder that contains julia binary")
- Set
JULIA_HOME
in command line environment.
libstdc++.so.6: version `GLIBCXX_3.4.xx’ not found
Such problems are usually on Linux machines. The cause for the problem is that R cannot find the libstdc++ version needed by Julia
. To deal with the problem, users can export “TheFolderContainsJulia/lib/julia” to R_LD_LIBRARY_PATH.
RCall not properly installed
The issue is usually caused by updates in R, and it can be typically solved by setting rebuild
argument to TRUE
in julia_setup()
as follows.
JuliaCall::julia_setup(rebuild = TRUE)
ERROR: could not load library "/usr/lib/x86_64-linux-gnu/../bin/../lib/x86_64-linux-gnu/julia/sys.so"
This error happens when Julia is built/installed withMULTIARCH_INSTALL=1
, as it is on e.g. Debian. It is caused by the bindir-locating code in jl_init not being multiarch-aware. To work around it, try setting JULIA_BINDIR=/usr/bin
in.Renviron.
How to Get Help
- One way to get help for Julia functions is just using
julia$help
as the following example:
#> ```
#> sqrt(x)
#> ```
#>
#> Return <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msqrt><mi>x</mi></msqrt></mrow><annotation encoding="application/x-tex">\sqrt{x}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.2397em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8003em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal">x</span></span></span><span style="top:-2.7603em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.2397em;"><span></span></span></span></span></span></span></span></span>.
#>
#> Throws [`DomainError`](@ref) for negative [`Real`](@ref) arguments. Use complex negative arguments instead. Note that `sqrt` has a branch cut along the negative real axis.
#>
#> The prefix operator `√` is equivalent to `sqrt`.
#>
#> See also: [`hypot`](@ref).
#>
#> # Examples
#>
#> ```jldoctest; filter = r"Stacktrace:(\n \[[0-9]+\].*)*"
#> julia> sqrt(big(81))
#> 9.0
#>
#> julia> sqrt(big(-81))
#> ERROR: DomainError with -81.0:
#> NaN result for non-NaN input.
#> Stacktrace:
#> [1] sqrt(::BigFloat) at ./mpfr.jl:501
#> [...]
#>
#> julia> sqrt(big(complex(-81)))
#> 0.0 + 9.0im
#>
#> julia> sqrt(-81 - 0.0im) # -0.0im is below the branch cut
#> 0.0 - 9.0im
#>
#> julia> .√(1:4)
#> 4-element Vector{Float64}:
#> 1.0
#> 1.4142135623730951
#> 1.7320508075688772
#> 2.0
#> ```
#>
#> ```
#> sqrt(A::AbstractMatrix)
#> ```
#>
#> If `A` has no negative real eigenvalues, compute the principal matrix square root of `A`, that is the unique matrix <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>X</mi></mrow><annotation encoding="application/x-tex">X</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span></span></span></span> with eigenvalues having positive real part such that <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>X</mi><mn>2</mn></msup><mo>=</mo><mi>A</mi></mrow><annotation encoding="application/x-tex">X^2 = A</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal">A</span></span></span></span>. Otherwise, a nonprincipal square root is returned.
#>
#> If `A` is real-symmetric or Hermitian, its eigendecomposition ([`eigen`](@ref)) is used to compute the square root. For such matrices, eigenvalues λ that appear to be slightly negative due to roundoff errors are treated as if they were zero. More precisely, matrices with all eigenvalues `≥ -rtol*(max |λ|)` are treated as semidefinite (yielding a Hermitian square root), with negative eigenvalues taken to be zero. `rtol` is a keyword argument to `sqrt` (in the Hermitian/real-symmetric case only) that defaults to machine precision scaled by `size(A,1)`.
#>
#> Otherwise, the square root is determined by means of the Björck-Hammarling method [^BH83], which computes the complex Schur form ([`schur`](@ref)) and then the complex square root of the triangular factor. If a real square root exists, then an extension of this method [^H87] that computes the real Schur form and then the real square root of the quasi-triangular factor is instead used.
#>
#> [^BH83]: Åke Björck and Sven Hammarling, "A Schur method for the square root of a matrix", Linear Algebra and its Applications, 52-53, 1983, 127-140. [doi:10.1016/0024-3795(83)80010-X](https://doi.org/10.1016/0024-3795(83)80010-X)
#>
#> [^H87]: Nicholas J. Higham, "Computing real square roots of a real matrix", Linear Algebra and its Applications, 88-89, 1987, 405-430. [doi:10.1016/0024-3795(87)90118-2](https://doi.org/10.1016/0024-3795(87)90118-2)
#>
#> # Examples
#>
#> ```jldoctest
#> julia> A = [4 0; 0 4]
#> 2×2 Matrix{Int64}:
#> 4 0
#> 0 4
#>
#> julia> sqrt(A)
#> 2×2 Matrix{Float64}:
#> 2.0 0.0
#> 0.0 2.0
#> ```
- The GitHub Pages for this repository host the documentation for the development version of
JuliaCall
:https://JuliaInterop.github.io/JuliaCall/. - Also, you are more than welcome to contact me about
JuliaCall
atlch34677@gmail.com or cxl508@psu.edu.
JuliaCall for R Package Developers
If you are interested in developing an R
package which is an interface for a Julia
package, JuliaCall
is an ideal choice. You only need to find the Julia
function or Julia
module you want to have in R
,using
the module, and julia_call
the function. There are some examples:
- diffeqr is a package for solving differential equations in
R
. It utilizesDifferentialEquations.jl for its core routines to give high performance solving of ordinary differential equations (ODEs), stochastic differential equations (SDEs), delay differential equations (DDEs), and differential-algebraic equations (DAEs) directly inR
. - convexjlr is an
R
package for Disciplined Convex Programming (DCP) by providing a high level wrapper forJulia
packageConvex.jl.convexjlr
can solve linear programs, second order cone programs, semidefinite programs, exponential cone programs, mixed-integer linear programs, and some other DCP-compliant convex programs throughConvex.jl
. - ipoptjlr provides an
R
interface to theIpopt
nonlinear optimization solver. It provides a simple high-level wrapper forJulia
package [Ipopt.jl
] (https://github.com/jump-dev/Ipopt.jl). - FixedEffectjlruses the
Julia
packageFixedEffectModels.jlto estimate large fixed effects models inR
. - Julia MixedModels from Rillustrates how to use
JuliaCall
andJulia
packageMixedModels.jl to build mixed models inR
. - autodiffr provides automatic differentiation to native
R
functions by wrappingJulia
packagesForwardDiff.jl andReverseDiff.jlthroughJuliaCall
, which is a work in progress.
If you have any issues in developing an R
package using JuliaCall
, you may report it using the link:https://github.com/JuliaInterop/JuliaCall/issues/new, or email me atlch34677@gmail.com or cxl508@psu.edu.
Suggestion, Issue Reporting, and Contributing
JuliaCall
is under active development now. Any suggestion or issue reporting is welcome! You may report it using the link:https://github.com/JuliaInterop/JuliaCall/issues/new, or email me atlch34677@gmail.com or cxl508@psu.edu. You are welcome to use theissue templateand the pull request template. The contributing guideprovides some guidance for making contributions.
Checking JuliaCall
Package
To check and test the JuliaCall
package, you need to have the source package. You can
- download the source of
JuliaCall
from Github, - open
JuliaCall.Rproj
in your RStudio or openR
from the downloaded directory, - run
devtools::test()
to see the result of the test suite. - run
devtools::check()
or click theCheck
button in the RStudio Build panel in the upper right to see the result ofR CMD check
.
Other Interfaces Between R and Julia
- RCall.jl is a
Julia
package which embedsR
inJulia
.JuliaCall
is inspired byRCall.jl
and depends onRCall.jl
for many functionalities like type conversion betweenR
andJulia
. - XRJulia is an
R
package based on John Chambers’XR
package and allows for structured integration ofR
withJulia
. It connects toJulia
and uses JSON to transfer data betweenJulia
andR
. A simple performance comparison betweenXRJulia
andJulia
can be found in JuliaCallJOSS paper. - RJulia is an
R
package which embedsJulia
inR
as well asJuliaCall
. It is not on CRAN yet, and I haven’t tested it.
License
JuliaCall
is licensed underMIT.
Code of Conduct
Please note that the JuliaCall
project is released with a Contributor Code of Conduct. By contributing to this project, you agree to abide by its terms.
Citing
If you use JuliaCall
in research that resulted in publications, then please cite the JuliaCall
paper using the following BibTeX entry:
@Article{JuliaCall,
author = {Changcheng Li},
title = {{JuliaCall}: an {R} package for seamless integration between {R} and {Julia}},
journal = {The Journal of Open Source Software},
publisher = {The Open Journal},
year = {2019},
volume = {4},
number = {35},
pages = {1284},
doi = {10.21105/joss.01284},
}