This is a container functor that calls R externally with a user-defined expression. Like the other calculator functors, data is connected through hook functors placed inside its block.
| Name | Type | Description |
|---|---|---|
| Expression | Code Type | The expression to run on R. Written directly as a Code constant using its own raw string syntax — see Writing the expression in EGO Script below. |
| Treat Warning As Errors | Boolean Value Type | If true, warnings raised by the R script are treated as errors. |
None.
| Name | Type | Description |
|---|---|---|
| Result | Struct Type | Struct containing the output values generated by the expression, one entry per call to an output function in the R script. |
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.
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:
stringsAsFactors = FALSE to prevent this conversion.For further detail on the underlying table representation, see External Communication.
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) |
Calculate R Expression returns a single Struct Type 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 Calculate R Expression, and the name of the entry to extract as a string constant.
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");
There are two ways to run R scripts from Calculate R Expression — though only the local installation is available on Linux.
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.
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 Tools → Options → Integration tab and enabling “Use alternative R installation for Calculate R Expression”.
Reports an error if this functor is used without either the Enhancement Plugin or a working local R installation configured.
Raises an error if the number of Number Table hooks nested inside this container exceeds the capacity of the external communication message queue.
The following examples use a consistent set of inputs: t1 is a lookup table of land cover patches mapping Key (patch identifier) to Value (patch area); v1 is a scalar minimum area threshold; and s1 is a string giving the name to use for a 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);
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);
Like Calculate Python Expression, the Expression input is type Code Type. It can be filled in directly as a text constant, using Code Type's own raw string syntax – the same $“<delimiter>( raw_characters )<delimiter>” form used by String constants. This is also the form the Dinamica EGO GUI's dedicated code editor generates when it writes the Expression port's value, so a hand-written script and one produced by the GUI take the same shape. See Code Type for the full grammar, including the base64 alternative form.
result := CalculateRExpression $"(
aboveThreshold <- t1$Value >= v1;
outputLookupTable("filteredPatches", t1$Key[aboveThreshold], t1$Value[aboveThreshold]);
)" .no {{
NumberTable landCoverAreas 1;
NumberValue minimumArea 1;
}};
filteredPatches := ExtractStructLookupTable result "filteredPatches";
Here .no is the value of Treat Warning As Errors.
CalculateRExpression