klonowsk

klonowsk

Rx - run your R code in a persistent external Rscript process (Elixir ↔ R bridge)

Rx provides an Elixir ↔ R bridge heavily inspired by Pythonx. It includes support for LiveBook, the capture of static and interactive plots - the latter via plotly_ex, and Explorer. It extends and simplifies on the existing Rservex library, which I found somewhat limiting.

Alongside the default external process backend, Rx ships an experimental, optional, opt-in embedded native backend that loads R directly into the BEAM through a NIF. It exists for high-throughput workflows where the cost of crossing the process boundary dominates. The native backend is not built or loaded by default.

Set the environmental variable RX_BUILD_NIF=1 to build the C NIF, or RX_BUILD_RUST_NIF=1 to build the Rust NIF (needs Rust/Cargo from rustup). You’ll also need R’s headers and the embedded R shared library (libR.so on Linux, libR.dylib on macOS), plus make and a C compiler for the C path. Then init, as follows:

r_home = System.cmd("R", ["RHOME"], stderr_to_stdout: true) |> elem(0) |> String.trim()

lib_r_path =
  [Path.join([r_home, "lib", "libR.so"]), Path.join([r_home, "lib", "libR.dylib"])]
  |> Enum.find(&File.exists?/1)

Rx.system_init(backend: :native, r_home: r_home, lib_r_path: lib_r_path)

So, to run LiveBook with native C NIF:

RX_BUILD_NIF=1 livebook server

Tested on mac OS and Ubuntu Linux via WSL 2.

Released on github:

A few example notebooks are present under the notebooks directory on GitHub (notebooks/) for usage examples.

Any and all suggestions welcome.


Example code:

Mix.install([
  {:rx, "~> 0.1.0"},
  {:kino, "~> 0.19.0"},
  {:explorer, "~> 0.11"},
  {:kino_explorer, "~> 0.1.25"},
  {:plotly_ex, "~> 0.1"}
])


{obj, _} = Rx.eval("data.frame(x = 1:3, y = c('a','b','c'))", %{})
{:ok, df} = Rx.Explorer.from_r(obj)
df


df = Explorer.DataFrame.new(%{"x" => [1, 2, 3]})
{:ok, r_obj} = Rx.Explorer.to_r(df)
{result, _} = Rx.eval("sum(df$x)", %{"df" => r_obj})
Rx.decode(result)


[plot] = Rx.plot("plot(1:5)", %{})
Rx.Kino.image(plot)


[ggplot] =
  Rx.plot(
    """
    library(ggplot2)
    ggplot(mtcars, aes(wt, mpg)) + geom_point()
    """,
    %{}
  )
Rx.Kino.image(ggplot)


{r_plot, _} =
  Rx.eval(
    """
    plotly::plot_ly(mtcars, x=~wt, y=~mpg, color=~cyl, type = "scatter")
    """,
    %{}
  )

{:ok, fig} = Rx.Plotly.from_r(r_plot)
Plotly.show(fig)


{model, _} =
  Rx.eval(
    """
    lm(mpg ~ wt, mtcars)
    """,
    %{}
  )
Rx.print(model) |> IO.puts()

Where Next?

Popular in Announcing Top

wmnnd
Hi there, for my project DBLSQD, I needed a file storage solution that is a bit more flexible than Arc. Because I thought others might f...
New
mindok
What is ContEx? A pure Elixir server-side data plotting/charting library outputting SVG. It has nice barcharts in particular and works g...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
kevinlang
Hey all, We have made an Ecto3 Adapter for SQLite3, ecto_sqlite3! We have successfully on-boarded the full suite of integration tests (...
New
kip
Image is an image processing library for Elixir. It is based upon the fabulous vix library that provides a libvips wrapper for Elixir. I...
622 19610 194
New
wojtekmach
Hey everyone! Req is an HTTP client for Elixir that I’ve been working on for quite some time. There is already a lot of HTTP clients out...
New
restlessronin
The repo is at GitHub - cyberchitta/openai_ex: Community maintained Elixir library for OpenAI API · GitHub. Docs are at OpenaiEx User Gu...
152 10796 134
New

Other popular topics Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 44778 311
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New

We're in Beta

About us Mission Statement