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:
- Key columns are marked by an asterisk (
*) appended to their column name — this is the same convention used throughout Dinamica EGO's table representation (see Connecting Data Inputs). - R automatically converts string columns to Factors inside a
data.frame, but Dinamica requires plain Character Vectors. Always build tables withstringsAsFactors = FALSEto prevent this conversion.
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. | 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:
- R installed on the machine, with the
Rscriptexecutable (Rscript.exeon Windows) present in itsbinsub-folder. - The Dinamica package for R installed and at its latest version.
On Windows, this alternative installation is selected in the Dinamica EGO GUI by going to Tools → Options → Integration tab and enabling Use alternative R installation for Calculate R Expression.
Examples
The following examples use a consistent set of inputs:
t1— a lookup table of land cover patches, mappingKey(patch identifier) toValue(patch area)v1— a scalar minimum area thresholds1— a string giving the name to use for the threshold flag column
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: Theprint()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
Internal Name
CalculateRExpression