# R/SWISH demos
R for SWISH provides an interface to [Rserve](https://rforge.net/Rserve/) where the access predicates are inspired by [Real](http://stoics.org.uk/~nicos/sware/real/) by [Nicos Angelopoulos](http://stoics.org.uk/~nicos/). The interface defines two predicates and a [quasi quotation](http://www.swi-prolog.org/pldoc/man?section=quasiquotations):
$ Var <- Expression :
Evaluate _Expression_ and bind the result to _Var_. _Var_ can both be a Prolog
variable, which causes the R expression to be converted into Prolog or an
R variable (atom), which causes the result to be bound to an R variable.
$ <- Expression :
Evaluate _Expression_ and display the resulting R console output.
$ {|r(Arg ...)||R-code|} :
In this quasi quotation, `r` specifies the syntax. `Arg ...` is a list of
Prolog terms that are translated to R and bound to an R variable with the
same name. `R-code` is arbitrary R code. This may contain any characters
except for the `|}` termination sequence.
Above, *Expression* is either a Prolog term or a quasi quotation. If it is a
Prolog term, it is translated into R using these rules:
- An identifier (atom with chars valid for R identifiers) are emitted verbatim.
- The Prolog atoms `true` and `false` are translated into the R expressions
=TRUE= and =FALSE=.
- A Prolog string is translated into an R string. Note that R strings may be
written as `"string"` or `'string'`, while in Prolog `'string'` is an atom,
which is treated as an identifier. Thus, use double quoted Prolog strings
to create a string in R.
- Numbers are translated into R numbers.
- A term =|functor(Arg ...)|= is translated into an R-function call.
- The R operators are supported: =|+, -, *, /, mod, '%%', ^,
>=, >, ==, <, <=, =<, \=, '!=', :, <-|=
- =|A$B|= and =|A[I]|= are supported
- Goal expansion is provided to turn =|a.b|= and =|a.b()|= into valid syntax.
## Exchange data between Prolog and R
Data may be transferred using the assignment operator `Target <- Source`, where `Source` is the Prolog representation of an R expression. `Target` is either a Prolog variable, transferring the value of an R expression to Prolog, or an R variable or expression, transferring a Prolog expression to R.
First we illustrate exchanging R data to Prolog. Note that the expression can both be the Prolog representation of an R expression or R source represented as a quasi quotation.
A <- 1:10.
A <- {|r||1:10|}.
Next, we transfer data from Prolog to R. We compute the mean and return it to show that `a <- List` actuall binds the R variable `a`.
numlist(0, 10, List),
a <- List,
Mean <- mean(a).
The left side of the assignment can be any valid R term as illustrated below, where we assign the column names of a data frame. See [Data frame](example/Rdataframe.swinb) for more high level operations on data frames.
df <- data.frame([100,200,300]),
colnames(df) <- ["hundreds"],
<- df.
## Simple plot examples
First, we make some trivial plots using an R vector, Prolog list and a _quasi quotation_.
<- plot(c(1,2,3)).
<- plot([1,2,3,4]).
{|r||plot(c(1,2,3))|}.
numlist(1, 25, Data),
{|r(Data)||plot(Data)|}.
## Performance tests for transferring data
Below we compare computing the mean from a list of 1M integers through R as well as natively in Prolog. It turns out R does the job faster on a large number of integers than Prolog. Why? Once in R, the array is a simple C array of integers, causing a blindly fast addition. The Prolog counterpart adds the numbers one-by-one and does rigid overflow checking and handling.
numlist(1, 1 000 000, _L),
time(A <- mean(_L)).
numlist(1, 1 000 000, _L),
time(sum_list(_L, Sum)).
## Show error handling
A <- {|r||a b|}.
## Using ggplot2 to render plots
The library("ggplot2") can be used for rendering plots. Unlike native plot() however, the call should be made with <-/1 because ggplot relies on console output. We first give the example using an R quasi quotation, followed by using a Prolog term. Note that
- Quasi quotations can be used to copy/paste R code into your Prolog
program without changing it (except when it contains =||}|=).
- Prolog code may need minor modifications. In the example, =|I(.5)|=
must be changed to `'I'(0.5)` because Prolog floats cannot start with
a =|.|= and functors (used as function symbols) cannot start with a
capital. The Prolog approach however
- Is better portable.
- Profits from Prolog syntax checking.
- Makes it easier to compose R expressions from smaller elements.
:- <- library("ggplot2").
<- {|r||qplot(mpg, data=mtcars, geom="density", fill=gear, alpha=I(.5), main="Distribution of Gas Milage", xlab="Miles Per Gallon", ylab="Density")|}.
<- qplot(mpg, data=mtcars, geom="density", fill=gear, alpha='I'(0.5), main="Distribution of Gas Milage", xlab="Miles Per Gallon", ylab="Density").
## Query and handle data frames
This shows how to print a data frame and how to get R data into Prolog. Note that the interface merely fetches the matrix as a nested list of columns. The library(r/r_data) provides utilites for creating and fetching R data frames from Prolog. This [notebook](example/Rdataframe.swinb) illustrates the library.
:- use_rendering(table).
<- mtcars.
MtCars <- mtcars,
Cols <- colnames(mtcars),
Rows <- rownames(mtcars).