What is the same, what is different, and why


All the things that are great about R stay the same when using R in Exaptive, including access to the vast ecosystem of CRAN packages, vectorized data processing, and a highly flexible application of nearly any statistical technique you can think of. R functionality is a first class citizen of the Exaptive platform, and using R in your application is just as easy.

The main difference is how data gets to your R code, and how results come back out of it. Since the Exaptive platform is technology agnostic, this interface will let your R components automatically and seamlessly work with components written in Python, JavaScript, or anything else.

This guide has everything you need to get started writing R components for your Xap. You'll want to keep the R Component API reference handy when you start to code. 

The Interface: how components talk to each other


Whenever you create a new R component, you will define inputs and outputs that let your component talk with others. In the example here, there are 2 input ports named data and config_options and one output port named data


The State Object


 

data <- function(state) {
    # Do something
}

config_options <- function(state) {
    # Do something
}


Each function takes a single parameter, called state in this example, but it can be called anything you like that is not a reserved keyword. The state object in this example is the gateway in and out of our component. All of the data handed to the input port is accessible through this object. Additionally, we will bind our output to this object. Lastly, there are a number of utility functions already loaded into the namespace of our component that will help work with this gateway.


Getting Data In 

Data coming in is embedded in this object, and is easily extracted.

  

config_options <- function(state) {
    input_port_data <- v_export(state$api$inputstate)
    my_data <- input_port_data$config_options
}


The v_export utility function converts all of the input data from all of the ports into a list with a property for each port's data. We can further bind the specific data we received from a port by accessing it's property (which is named the same thing as the port name).


Getting Results Back Out

In the same way we accessed our input data from the state object, we will bind our output data to this same state object.

 

config_options <- function(state) {
    input_port_data <- v_export(state$api$inputstate)
    my_data <- input_port_data$config_options

    result <- from_my_model(
        period = config_options$period,
        sensitivity = config_options$sens
    )

    state$api$output(name = "data", value = v_import(result))
}


Outputs are bound back to the state options to be sent to the outputs ports of your application. The utility function v_import() will automatically convert your data from R to Exaptive data types (see table below). Since Exaptive datatypes are analogous to JSON, the data you export will need to be JSON serializable types.


NOTE: Only data bound to the state object will be sent to any output ports, there is no need to return data from your main function.


For additional information, see detailed documentation on the R Component API.

Additional Functions

Your code is by no means limited to only the functions that respond to your input ports. Your component can define as many other functions as you like to use as helper functions.

 

helper_function <- function(period, sensitivity) {
    # Do something
    return(period + sensitivity)
}

config_options <- function(state) {
    input_port_data <- v_export(state$api$inputstate)
    my_data <- input_port_data$config_options

    result <- helper_function(
        period = config_options$period,
        sensitivity = config_options$sens
    )

    state$api$output(name = "data", value = v_import(result))
}

 

Using Packages


Your R component is able to connect directly to CRAN, and get access to any of its packages. To register a CRAN library, you will need to make a small addition to the Spec file of your component. The Spec file is just a JSON file where all the component's settings are kept--including what libraries your component depends on. In that file is a property called "dependencies". You will need to add each dependency as a key:value pair to the "cran" properly like so:

 

...
"dependencies": {
"file": [],
"cran": [
{"path": "dplyr"},
{"path": "stringr"}
]
},
...

 

Then, inside your code, load the library namespace as normal.

 

library(dplyr)
library(stringr)



Reference: Exaptive and R data types


 Exaptive Type
Exaptive Example 
R Type 
R Example 
boolean
 
true, false


 
logical
 
TRUE, FALSE, T, F
 
integer
 
10
 
integer
 
[10]
 
float
 
10.1
 
numeric
 
[10.1]
 
string
 
"hello world"
 
character
 
["hello world"]
 
list, set, multiset
 
[1, 2, 3]
  
vector or list
 
[1  2  3]
 
entity
 
{
name: "Ringo", 
bands: [ "Beatles", "All-Star Band"],
}
 
list
 
list
[["name"]] ["Ringo"]
[["bands"]]: ["Beatles"  "All-Star Band"]