Table of Contents

Calculate R Expression

Description

This is a container functor that calls R externally with the user-defined expression. Like the other calculator functors, data is connected through hook functors placed inside its {{ … }} block.

Inputs

Name Type Description
Expression Code The expression that will run on R. Code values cannot be written as plain text constants in EGO Script — see Writing the expression in EGO Script below.
Treat Warning As Errors Boolean Value Type Warnings raised by the R script will be treated as errors.

Optional Inputs

None.

Outputs

Name Type Description
result Struct A struct containing the output values generated by the expression.

Notes

Expression inputs

Data is passed into the expression through hook functors placed inside the container's {{ … }} block — the same verbose form hook mechanism used by the calculator functors. Hooks can be added using the Create a hook button on the functor bar, or by dragging them in individually.

Maps cannot be connected — this functor has no cell context. There is no shorthand notation; see Calculate Functors — Complete Operator Documentation for the general hook mechanism and syntax.

Tables and lookup tables

Lookup tables and tables require extra care, since each is transferred to R using a different representation.

A lookup table is transferred as a list with two columns, Key and Value. Each column is accessed with the $ operator:

# Access the third key and its corresponding value in lookup table t1
patchId <- t1$Key[3];
patchArea <- t1$Value[3];

A table is transferred as a DataFrame, with each column likewise accessed using $. Two conventions apply to tables in either direction:

For further detail on the underlying table representation, see External Communication.

Expression outputs

Values are returned to Dinamica by calling one of the following functions from the R script. Every call requires an identifier as its first parameter — the name Dinamica uses to place the value into the output struct — and the value itself, which can be constructed inline, as in the examples below, or supplied as a variable:

Function Output type Notes Example
outputDouble() Real Accepts any numeric value. outputDouble(“myDouble”, 3.14)
outputNumberVector() Tuple Accepts any collection of numbers. outputNumberVector(“myTuple”, c(1:10))
outputString() String Accepts any string value. outputString(“myString”, “This is a string”)
outputLookupTable() Lookup Table Requires two number vectors of equal length — one for the keys, one for the values. Lookup tables are always Real-typed on both sides; there is no String option. outputLookupTable(“myLUT”, c(1:10), c(1:10) * 10)
outputTable() Table Requires a table built with the data.frame function, using stringsAsFactors = FALSE as described above. Its optional second parameter (default 1) sets how many leading columns, from the left, are key columns. outputTable(“myTable”, data.frame(State = c(“Massachusetts”, “Massachusetts”), City = c(“Boston”, “Chelsea”), Population = c(667137, 39398), stringsAsFactors = FALSE), 2)

Retrieving outputs

CalculateRExpression returns a single Struct value (via its result output port) containing every value passed to an output*() function. To retrieve individual values from that struct, use the corresponding functor from the Integration group:

Functor Retrieves
Extract Struct Number A value passed to outputDouble()
Extract Struct Tuple A value passed to outputNumberVector()
Extract Struct String A value passed to outputString()
Extract Struct Lookup Table A value passed to outputLookupTable()
Extract Struct Table A value passed to outputTable()

Each functor takes two inputs: the Struct returned by CalculateRExpression, and the name of the entry to extract as a string constant.

Installing packages

Packages are installed by calling dinamicaPackage(“packageName”) from within the expression — one call per package. Unlike Calculate Python Expression, there is no separate input port for listing packages; dinamicaPackage() is the only mechanism available.

dinamicaPackage(“packageName”) also acts as R's library() call: when the package name matches the name of the module to load, calling it both installs the package (if not already present) and loads it, in a single call.

dinamicaPackage("moments");

Setup

There are two ways to run R scripts from CalculateRExpression — though only the local installation is available on Linux.

Dinamica EGO Enhancement Plugin

Windows only. Download and install the Dinamica EGO Enhancement Plugin. It contains everything needed to run R scripts inside Dinamica EGO, with no further configuration.

Local R installation

On Linux, this is the only option — Dinamica EGO always uses the R installation already present on the system. On Windows, it can be used as an alternative to the plugin. Either way, it requires:

On Windows, this alternative installation is selected in the Dinamica EGO GUI by going to ToolsOptionsIntegration tab and enabling Use alternative R installation for Calculate R Expression.

Examples

The following examples use a consistent set of inputs:

Compute the mean and total area across all patches, and report progress to the Message Log:

patchMean <- mean(t1$Value);
patchTotal <- sum(t1$Value);
print(paste("Processed", length(t1$Value), "patches"));
 
outputDouble("meanArea", patchMean);
outputDouble("totalArea", patchTotal);
Note: The print() call is visible in Dinamica EGO's Message Log, shown as a Result-level message. Log levels are ordered Unconditional, Error, Warning, Result, Info, Info2, Debug, Debug2 — messages printed from R are only shown when the Message Log level is set to Result or a more verbose level; at Unconditional, Error, or Warning they are suppressed.

Filter the lookup table down to patches whose area meets the threshold, and return the filtered lookup table:

aboveThreshold <- t1$Value >= v1;
filteredKeys <- t1$Key[aboveThreshold];
filteredValues <- t1$Value[aboveThreshold];
 
outputLookupTable("filteredPatches", filteredKeys, filteredValues);

Build and return a table with one row per patch, including a column that flags whether each patch meets the threshold. The column's name is taken from the passed string s1 rather than being hard-coded:

patchFlags <- data.frame(
    PatchId = t1$Key,
    Area = t1$Value,
    MeetsThreshold = t1$Value >= v1,
    stringsAsFactors = FALSE
);
names(patchFlags)[3] <- s1;
 
outputTable("patchSummary", patchFlags, 1);

Install the moments package and use it to compute the skewness of the patch area distribution — a statistic not available in base R — then flag patches whose area is a statistical outlier:

dinamicaPackage("moments");
 
patchMean <- mean(t1$Value);
patchStdDev <- sd(t1$Value);
patchSkewness <- skewness(t1$Value);
 
isOutlier <- abs(t1$Value - patchMean) > 2 * patchStdDev;
outlierPatches <- data.frame(
    PatchId = t1$Key[isOutlier],
    Area = t1$Value[isOutlier],
    stringsAsFactors = FALSE
);
 
outputDouble("meanArea", patchMean);
outputDouble("stdDevArea", patchStdDev);
outputDouble("skewnessArea", patchSkewness);
outputTable("outlierPatches", outlierPatches, 1);

Writing the expression in EGO Script

Like Calculate Python Expression, the Expression input is type Code, which is represented in the underlying script using base64 encoding — impractical to write or edit directly as a text constant. Instead, connect a String carrier functor containing the R expression text to the Expression port; its output is accepted wherever a Code value is expected. Since only this one output is needed, the carrier can be inlined directly into the call.

This limitation is specific to hand-written EGO Script. In the Dinamica EGO GUI, the Expression port has a dedicated code editor that edits the Code value directly — the String carrier workaround is only necessary when writing or editing the .ego file as text.

result := CalculateRExpression (String $"(
aboveThreshold <- t1$Value >= v1;
outputLookupTable("filteredPatches", t1$Key[aboveThreshold], t1$Value[aboveThreshold]);
)") .no {{
    NumberTable landCoverAreas 1;
    NumberValue minimumArea    1;
}};
filteredPatches := ExtractStructLookupTable result "filteredPatches";

Group

Integration

Internal Name

CalculateRExpression