A library that allows to execute arbitrary R programs within LuaJIT. Being the most widely used language for statistical computing, R features a huge number of scientific libraries. Of particular relevance is the possibility to leverage on the plotting capabilities of ggplot2 and similar libraries:
local R = require "rclient"
local r = R.connect()
-- Lua --> R:
r.myvec = { 1,2,3 } -- Array.
r.mymat = R.asmatrix({ {1,2,3},{4,5,6} })
r.mylist = R.aslist({ 7,8,9 }, { "a","b","c" })
r.mydf = R.asdataframe({ 7,8,9 }, { "a","b","c" }, { "row1" })
-- Execute R commands and evaluate expression as in R interpreter:
r "myvec <- myvec^2"
r "myvec" --> [1] 1 4 9
-- R --> Lua:
local vec = r.myvec
local mat = r.mymat
local list = r.mylist
local df = r.mydf
print(unpack(vec)) --> 1 4 9
print(unpack(mat[1])) --> 1 2 3
print(unpack(mat[2])) --> 4 5 6
print(unpack(list[0][1])) --> a b c
print(list[1][1], list[2][1], list[3][1]) --> 7 8 9
print(list.a[1], list.b[1], list.c[1] ) --> 7 8 9
print(unpack(df[0][1])) --> a b c
print(unpack(df[0][2])) --> row1
print(df[1][1], df[2][1], df[3][1]) --> 7 8 9
print(df.a[1], df.b[1], df.c[1] ) --> 7 8 9
RCLIENT implements a client for Rserve which is used to host a (local or remote) R session toward which a connection is established. The following R code, to be executed in a R session, installs Rserve and starts a local R session:
install.packages("Rserve")
library("Rserve")
Rserve(args="--no-save")
In R almost every data structure is based on a R vector (also called generic vector). Conceptually a R vector is a sequence of elements of arbitrary type (including other R vectors). We say that a R object is atomic if it cannot be further decomposed into finer data structures. The following table lists the correspondences between R atomic type names and Lua type names:
R Atomic Type | Lua Type |
---|---|
null | nil |
numeric | number |
integer | number |
complex | cdata<complex> |
logical | boolean |
character | string |
We say that a R object is a R array if it is a R vector and and all its elements are atomics of the same type. A R scalar is a R array of length 1. R objects can have associated attributes which store metadata information. A R matrix is a R array with an attribute identifying the dimensions. A R list is a R vector of R vectors with an attribute identifying the column names. A R data.frame is a R vector of R vectors sharing the same length with attributes identifying the column names and the row names. This library allows the exchange between Lua and R of the following R aggregate types:
R Aggregate Type |
---|
array |
matrix |
list |
data.frame |
NOTE: no nesting is allowed for any of the R aggregate types (for instance a list of lists is not supported).
NOTE: in the following we refer to "Lua table" for a generic Lua table, to "Lua table array" for a Lua table whose only keys are
1, ..., N
and to "Lua array" for a Lua table array whose elements are of the same type and correspond to a R atomic. This last data structure is the one
that corresponds to a R array. Whenever a Lua array is expected a Lua scalar corresponding to a R atomic can be passed instead and this is equivalent to passing a Lua
array of length 1.
Objects are transfered from Lua to R via set-variable statements. The Lua object on the right hand side must be either nil
, or a
Lua array, or the object returned by one of the following functions: asmatrix()
, aslist()
, asdataframe()
.
Objects are transfered from R to Lua via get-variable statements. The R object being indexed on the left hand side must be either a R atomic or a
not nested R aggregate. A Lua table is always returned (unless the R object is null
, in which case nil
is returned) whose structure depends on
the R type. The cases of R arrays and R matrices behave as expected: a Lua array or a Lua table array of Lua arrays is returned. Remember that R scalars really are R
arrays of length 1. Otherwise:
local y = r.x -- r is a connection obtained via rclient.connect().
-- If x is a list with N columns:
y = { [0] = { [1] = column_names },
[1] = column_1_elements,
...
[N] = column_N_elements,
}
y[column_name_1] = y[1]
...
y[column_name_N] = y[N]
-- If x is a data.frame with N columns:
y = { [0] = { [1] = column_names, [2] = row_names },
[1] = column_1_elements,
...
[N] = column_N_elements,
}
y[column_name_1] = y[1]
...
y[column_name_N] = y[N]
-- Please notice that here strings are automatically interpreted as factors, in
-- which case what is passed back to Lua are the numeric encodings (1, ..., N)
-- associated with such factors. If this behavior is undesired please use the
-- "stringsAsFactors=FALSE" option when constructing data.frames on R side.
In the following r
is a connection to a R instance started by Rserve.
Returns the loaded module (no global variable is set).
Opens a connection to an instance of R started by Rserve and returns a connection object. The defaults result in a connection to a local instance of R started by Rserve
in its default configuration. If the environment variable LUA_EXEC
is set (as it is the case if using ULua), the Rserve
instance's working directory is set equal to it.
Executes the string rcode
and and passes the last result (if present) in string form to out
. As out
defaults to
print
this function mimics the R interpreter by default.
Sets the R variable named as variable
(a string) to x
.
Returns an object which is interpreted on R side as a R matrix. The input x
must be a Lua table array of Lua arrays sharing the same length and element
type.
Returns an object which is interpreted on R side as a R list. The input x
must be a Lua table array of Lua arrays. The input colnames
, if
present, must be a Lua table array of strings and have the same length of x
.
Returns an object which is interpreted on R side as a data.frame. The input x
must be a Lua table array of Lua arrays sharing the same length. The inputs
colnames
and rownames
, if present, must be Lua table arrays of strings and have respectively the same length of x
and of
x[1]
.
Returns an object which corresponds to the R variable named as variable
(a string).