RLink`
RLink`

REvaluate

REvaluate[code]

evaluates a string of R code, and returns the result as a Wolfram Language expression.

Details

  • The code code must be a string of valid R code, which, after execution, produces the result of one of the types that can be handled by REvaluate.
  • These are the R types explicitly supported by RLink, elements of which can be returned by REvaluate, along with the internal RLink heads of expressions representing such elements:
  • "integer"RVector
    "double"RVector
    "complex"RVector
    "logical"RVector
    "character"RVector
    "list"RList
    "NULL"RNull
    "closure"RFunction
    "builtin"RFunction
    "environment"REnvironment
  • Apart from explicitly supported types, most other types can be imported from R into the Wolfram Language by converting them into a string (deparsed R code). Such elements are wrapped into an RCode wrapper.
  • The type "environment" is only partially supported at present. Namely, it will consider all environment objects explicitly exported from R into the Wolfram Language to represent global environments.
  • When the code passed to REvaluate evaluates to a type not handled by REvaluate, REvaluate returns $Failed.

Examples

open allclose all

Basic Examples  (12)

This constructs a list (R vector) of 10 consecutive integers:

This uses a general vector constructor in R to construct a vector of numbers:

To suppress the output, or when no output is needed, put a semicolon at the end of the R code, in which case REvaluate returns Null:

When scalars are entered, they are automatically considered vectors of length 1 by R. This is reflected in RLink:

By default, real numeric quantities are interpreted as doubles:

One way to have R interpret them as integers is to use R's as.integer function:

This returns a more general sequence:

The Wolfram Language's equivalent follows:

This computes the sine function on the sequence from the previous example (most functions in R are vectorized, just as in the Wolfram Language):

This is the same, but using explicit function mapping (sapply in R corresponds to Map in the Wolfram Language):

The second method is slower, however, just as it would be in the Wolfram Language:

This is a slightly more complex example. Here, a function is mapped that takes a value of the independent variable and returns it back together with the value of the function (here, sine) wrapped in a vector:

Here is the Wolfram Language's equivalent for the rhs of the assignment from the previous example:

You can use larger pieces of R code inside REvaluate. In such a case, however, you should wrap your statements in a block (curly braces):

This splits a string, and actually returns a list rather than a vector, which is reflected in extra curly braces:

Note that you have to escape the quotation marks.

This generates a random 5×5 matrix:

This computes eigenvalues and eigenvectors:

You can see that the result is an R list and has a non-empty attribute set (attribute names); therefore, it is represented as a general R object with a head RObject. This topic is covered in more details in "R Data Types in RLink" and the RObject reference page.

This extracts only eigenvectors:

Or eigenvalues:

This is the same in the Wolfram Language (eigenvectors do not necessarily have to be the same in this case):

This creates a random matrix in the Wolfram Language:

Send it to R:

The result of this element-wise logical comparison is a logical vector (matrix):

Test that the result is of a logical type:

This lists the current objects present in your R workspace:

Scope  (8)

Assignments  (3)

You can also use REvaluate to make assignments. So you can, for example, do the following assignment to a global variable myint in the R workspace:

REvaluate can now be used to check the content of the newly created global variable myint:

The following assignment will return a function reference:

It may be used either on the R side (since this function was given a name in R):

Or on the Wolfram Language side:

To make assignments but suppress returning the result back to the Wolfram Language, you can suppress the output by adding a semicolon at the end:

Multidimensional Arrays  (3)

While you can handle multidimensional arrays with REvaluate just as easily as one-dimensional arrays, there are a few subtleties.

This will create a random one-dimensional array in R:

Since R stores arrays in column-major order, the previous result is not what you might have expected. But this is needed for consistency regarding array indexing:

To convert the array to row-major order (which is the order used by the Wolfram Language), you can use Transpose:

For example:

The dimensions get reversed:

And the same for indexing for the converted array:

The above issues only show up for arrays created in R and then sent to the Wolfram Language. If you create an array in the Wolfram Language and then send it to R, it is automatically transformed to column-major order, and back to row-major order when you get it back from R. Therefore, in such cases, you get back the original array.

This creates an array in the Wolfram Language:

Send it to R:

And get it from R:

As before, the indexing is consistent with that in the Wolfram Language:

This means that you can send Wolfram Language arrays to R and continue working with them in R, just like you would in the Wolfram Language.

As another example, consider matrix multiplication. First, construct a matrix in the Wolfram Language:

Now send it to R, assigning it to a variable mmat in the R workspace:

This will perform the matrix multiplication:

It yields the same result as it would in the Wolfram Language:

Special Quantities: NaNs and Infinities  (1)

There is currently a one-directional support for special quantities such as NaNs and infinities of various kinds.

The following R input demonstrates how various quantities are translated into the Wolfram Language. This is what you would get directly in the R console:

And in the Wolfram Language:

In order to get a complex result when taking a square root of a negative number, that number must be entered manifestly as a complex number:

While getting such quantities from R to the Wolfram Language is supported, the reverse is currently not:

Missing Points  (1)

Vectors and lists in R support missing points. In the Wolfram Language, such points are represented by Missing[].

Here is a typical example for a vector:

And a list:

The action of most functions on missing elements is to produce another missing element. For example:

Missing points have a bidirectional support in RLink. For example, the following performs the same computation as the previous example, but with the data sent to R from the Wolfram Language:

For a number of reasons described in the tutorial "Functions" on R functions, the following syntax is much preferred:

Generalizations & Extensions  (2)

Defining Your Own Functions  (1)

Here is an example of one possible implementation of the Wolfram Language Tuples function in R, returning tuples as data frames:

Here is how it can be used:

Manipulating R Objects' Attributes on the R Side, and General R Objects   (1)

All objects in R can have one or several attributes. In RLink, R objects with generic attributes are represented on the Wolfram side by Wolfram Language expressions with the head RObject. Some aspects of this also affect REvaluate.

The following will construct a matrix in the Wolfram Language, send it to R, and assign it to a variable myInt in the R workspace:

You can inspect the class of the resulting R object stored in a variable:

Attributes of any R object are stored in an R list. Objects of the class matrix have at least one attribute, "dim", which stores the information about dimensions (dimensions themselves are represented as an integer vector):

You can see that this list itself has attributes, in particular the attribute "names", and therefore it cannot be represented as just a Wolfram Language list, but has a head RObject. One shortcut to retrieve the value of a given attribute is to use the R attr function:

You can use REvaluate to perform non-trivial reshaping of your matrix on the R side by modifying its dim attribute. For example, you may convert the matrix into a three-dimensional array with dimensions {2,5,2}:

Which results in the following:

At some point, you may wish to add some new attributes to myInt, for example:

And now:

The dim attribute is implicit. You can always use RObject-based general representation, even for objects with no attributes: