Table of Contents
- Getting Started
- Manual
- Additional Features
GAMS Transfer is a package to maintain GAMS data outside a GAMS script in a programming language like Python, Matlab, or R. It allows the user to add GAMS symbols (Sets, Aliases, Parameters, Variables and Equations), to manipulate GAMS symbols, as well as read/write symbols to different data endpoints. GAMS Transfer's main focus is the highly efficient transfer of data between GAMS and the target programming language, while keeping those operations as simple as possible for the user. In order to achieve this, symbol records - the actual and potentially large-scale data sets - are stored in native data structures of the corresponding programming languages. The benefits of this approach are threefold: (1) The user is usually very familiar with these data structures, (2) these data structures come with a large tool box for various data operations, and (3) optimized methods for reading from and writing to GAMS can transfer the data as a bulk - resulting in the high performance of this package.
Getting Started
Install
GAMS Transfer R is available on CRAN and can be installed as follows from the R console.
GAMS Transfer R depends on packages R6
, R.utils
, and Rcpp
, collections
.
When building from source, GAMS Transfer R also requires the library zlib
. The user can point to zlib
by adding the directory containing zlib
to the environment variable PATH
or by using configure.vars
argument of install.packages()
.
Examples
GDX Read
Reading in all symbols can be accomplished with one line of code (we reference data from the trnsport.gms example).
All symbols are internally stored in the Container data field (dictionary). The users should never have to access or modify the data
field. The symbols can be accessed via m[<symbol_name>]
and the records can be accessed via m[<symbol_name>]$records
. Symbol records are stored in the data frame format.
GDX Write
There are five symbol classes within GAMS Transfer R: Sets, Parameters, Variables, Equations, and Aliases. For purposes of this quick start, we show how to recreate the distance
data structure from the trnsport.gms model (the parameter d
). This brief example shows how users can achieve "GAMS-like" functionality, but within an R environment. GAMS Transfer R leverages the object oriented programming to simplify the syntax.
This example shows a few fundamental features of GAMS Transfer R:
- A Container is analogous to a GDX file
- Symbols will always be linked to a Container (notice that we always pass the Container reference
m
to the symbol constructor) - Records can be added to a symbol with the
setRecords()
method, through therecords
constructor argument (internally callssetRecords()
), or through directly setting therecords
field. GAMS Transfer R will convert many common R data structures into a standard format. - Domain linking is possible by passing domain set objects to other symbols.
- Writing a GDX file can be accomplished in one line with the write() method.
Full Example
It is possible to use GAMS Transfer R to recreate the trnsport.gms results in GDX form. As part of this example, we also introduce the write() method (and generate new.gdx
). We will discuss it in more detail in the following section: Data Exchange with GDX.
It can be observed from the above example that a typical work flow for writing using GAMS Transfer R is creating a container, filling it with symbols (Sets, Parameters, Variables, Equations, and Aliases), and write it to a GDX file. To read a GDX file, a Container can simply be initialized with the GDX file name as an argument.
These examples introduced the reader to the GAMS Transfer R syntax. In the remaining sections, we will present details about the core functionality and dig further into the syntax.
Manual
Container
Storing, manipulating, and transforming sparse data requires that it lives within an environment. This data can then be linked together to enable various operations. In GAMS Transfer R, we refer to this "environment" as the Container
, it is the main repository for storing and linking our data. Linking data enables data operations such as implicit set growth, domain checking, and data format transformations (to dense/sparse matrix formats). A Container also enables different read/write operations.
Creating a Container
is a simple matter of initializing an object. For example:
This new Container
object, here called m
, contains a number of convenient fields and methods that allow the user to interact with the symbols that are in the Container
. Some of these methods are simply used to filter out different types of symbols, other methods are used to numerically characterize the data within each symbol.
The Container
constructor arguments are:
Argument | Type | Description | Required | Default |
---|---|---|---|---|
loadFrom | string , Container | Name of the GDX file being read into the Container | No | NULL |
- Container fields
Field | Description | Type |
---|---|---|
data | main dict that is used to store all symbol data | dict (collections package) |
summary | output a list containing the container information | list |
Symbols are organized in the Container
under the data
field. The users should never have to access the data
field. Symbols in the container can be accessed via m[<symbol_name>]
.
- Container methods
Method | Description | Arguments/Defaults | Returns |
---|---|---|---|
addAlias | add an Alias | name (string ) aliasWith (Set ,Alias ) | Alias object |
addUniverseAlias | add a UniverseAlias | name (string ) | UniverseAlias object |
addEquation | add an Equation | name (string ) type (string ) domain=NULL (string ,list ) records=NULL (data frame ,vector ,NULL ) domainForwarding=FALSE (logical ) description="" (string ) | Equation object |
addParameter | add a Parameter | name (string ) domain=NULL (string ,list ) records=NULL (data frame ,array , matrix ) domainForwarding=FALSE (logical ) description="" (string ) | Parameter object |
addSet | add a Set | name (string ) domain="*" (string ,list ) isSingleton=FALSE (logical ) records=NULL (data frame ,array ,matrix ) domainForwarding=FALSE (logical ) description="" (string ) | Set object |
addVariable | add a Variable | name (string ) type="free" (string ) domain=NULL (string ,list ) records=NULL (data frame ,array ,matrix ) domainForwarding=FALSE (logical ) description="" (string ) | Variable object |
copy | copies symbols to the destination container. overwrite=TRUE overwrites the symbols with the same name in destination . Symbol domains are relaxed if destination Container does not contain equivalent domain sets | destination (Container), symbols=NULL (character), overwrite=FALSE (logical) | NULL |
countDomainViolations | returns a named list containing number of domain violations symbols with non-zero domain violations | symbols=NULL (character ) - if NULL , assumes all symbols | list |
countDuplicateRecords | returns a named list containing number of duplicate records for symbols with non-zero duplicate records | symbols=NULL (character ) - if NULL , assumes all symbols | list |
describeAliases | create a summary table with descriptive statistics for Aliases | symbols=NULL (string ) - if NULL , assumes all Aliases | data frame |
describeEquations | create a summary table with descriptive statistics for Equations | symbols=NULL (string ) - if NULL , assumes all equations | data frame |
describeParameters | create a summary table with descriptive statistics for Parameters | symbols=NULL (string ) - if NULL , assumes all parameters | data frame |
describeSets | create a summary table with descriptive statistics for Sets | symbols=NULL (string ) - if NULL , assumes all sets | data frame |
describeVariables | create a summary table with descriptive statistics for Variables | symbols=NULL (string ) - if NULL , assumes all variables | data frame |
dropDomainViolations | drops domain violations for symbols in the Container | symbols=NULL (character ) - if NULL , assumes all symbols | - |
dropDuplicateRecords | drops duplicate records for symbols in the Container | symbols=NULL (character ) - if NULL , assumes all symbols, keep = first/last | - |
equals | Check if two Container objects are equal | other (Container ), verbose=FALSE | logical |
getAliases | returns a list of object references for Aliases that are isValid | isValid=NULL (logical ) | list |
getDomainViolations | gets domain violations for symbols in the Container | symbols=NULL (character ) - if NULL , assumes all symbols | list of DomainViolation |
getEquations | returns a list of object references for Equations that are isValid | isValid=NULL (logical ) | list |
getParameters | returns a list of object references for Parameters that are isValid | isValid=NULL (logical ) | list |
getSets | returns a list of object references for Sets that are isValid | isValid=NULL (logical ) | list |
getSymbolNames | returns the original symbol names for a vector names of any case | names (character ) | character |
getSymbols | returns a list of object references for symbols | symbols (character ) - if NULL assumes all symbols | list |
getVariables | returns a list of object references for Variables that are isValid | isValid=NULL (logical ) | list |
getUELs | returns the UELs used in the Container | symbols=NULL (character), ignoreUnused = FALSE | character vector |
hasDomainViolations | returns TRUE if any symbol in the container has domain violations, FALSE otherwise | symbols=NULL (character ) - if NULL , assumes all symbols | logical |
hasDuplicateRecords | returns TRUE if any symbol in the container has duplicate records, FALSE otherwise | symbols=NULL (character ) - if NULL , assumes all symbols | logical |
hasSymbols | checks if symbol names for a vector names exists in the container | names (character ) | logical |
isValid | TRUE if all symbols in the Container are valid | symbols=NULL (character ) - if NULL , assumes all symbols, verbose=FALSE (logical ) force=FALSE (logical ) | logical |
listAliases | list all aliases (isValid=NULL ), list all valid aliases (isValid=TRUE ), list all invalid aliases (isValid=FALSE ) in the container | isValid=NULL (logical ) | vector |
listEquations | list all equations (isValid=NULL ), list all valid equations (isValid=TRUE ), list all invalid equations (isValid=FALSE ) in the container | isValid=NULL (logical ) types=NULL (character of eqaution types) - if NULL , assumes all types | vector |
listParameters | list all parameters (isValid=NULL ), list all valid parameters (isValid=TRUE ), list all invalid parameters (isValid=FALSE ) in the container | isValid=NULL (logical ) | vector |
listSets | list all sets (isValid=NULL ), list all valid sets (isValid=TRUE ), list all invalid sets (isValid=FALSE ) in the container | isValid=NULL (logical ) | vector |
listSymbols | list all symbols (isValid=NULL ), list all valid symbols (isValid=TRUE ), list all invalid symbols (isValid=FALSE ) in the container | isValid=NULL (logical ) | vector |
listVariables | list all variables (isValid=NULL ), list all valid variables (isValid=TRUE ), list all invalid variables (isValid=FALSE ) in the container | isValid=NULL (logical ) types=NULL (character of variable types) - if NULL , assumes all types | vector |
read | main method to read loadFrom , can be provided with a list of symbols to read in subsets, records controls if symbol records are loaded or just metadata | loadFrom (string , Container ) symbols=NULL (string ) records=TRUE (logical ) | NULL |
removeSymbols | symbols to remove from the Container, also sets the symbols' container to NULL; removes symbol links from the Container; Aliases are also removed if the parent set is removed | symbols (string ) - if NULL assumes all symbols | NULL |
removeUELs | removes uels from all symbols the Container | uels=NULL (character), symbols=NULL (character). If Symbols is NULL UELs are removed for all symbols. | NULL |
renameSymbol | rename a symbol oldName in the Container | oldName (string ), newName (string ) | NULL |
renameUELs | renames uels in the Container | uels (named character), symbols=NULL (character), allowMerge=FALSE (logical). If allowMerge = TRUE , the underlying integer mapping of a factor is allowed to change to offer additional data flexibility. If Symbols is NULL UELs are renamed for all symbols. | NULL |
reorderSymbols | reorder symbols in order to avoid domain violations | - | NULL |
write | main bulk write method to a writeTo target | writeTo (string ) symbols=NULL (character ) - if NULL , assumes all symbols compress=FALSE (logical ) uelPriority=NULL (string ) mode="mapped" (character "string" or "mapped") | NULL |
Symbols
In GAMS Transfer R, a symbol is either a GAMS Set, Parameter, Variable, Equation, Alias. In GAMS Transfer R, a symbol cannot live on its own, but is always part of a Container.
- Create a symbol
There are two different ways to create a GAMS set and add it to a Container.
- Use symbol constructor for Set, Parameter, Variable, Equation, Alias library(gamstransfer)m = Container$new()p = Parameter$new(m, "p")
- Use the Container methods addSet, addParameter, addVariable, addEquation, addAlias (which internally calls the symbol constructor) library(gamstransfer)m = Container$new()p = m$addParameter("p")
- Add Symbol Records
Three possibilities exist to assign symbol records:
- Setting the argument
records
in the symbol constructor/Container method (internally callssetRecords
) - Using the symbol method
setRecords
- Setting the field
records
directly
If the data is in a convenient format, a user may want to pass the records directly within the set constructor. This is an optional keyword argument and internally the symbol constructor will simply call the setRecords
method. The symbol method setRecords
is a convenience method that transforms the given data into an approved data frame format (see Standard Data Formats). Many native R data types can be easily transformed into data frames, so the setRecords
method will accept a number of different types for input. The setRecords
method is called internally on any data structure that is passed through the records
argument.
The examples of setting records using the above-mentioned methods can be found in the respective documentation for each symbol ( Set, Parameter, Variable, Equation, and Alias ).
Set
- Set Constructor
Argument | Type | Description | Required | Default |
---|---|---|---|---|
container | Container | A reference to the Container object that the symbol is being added to | Yes | - |
name | string | Name of symbol | Yes | - |
domain | list | String, List of domains given either as a string ("*" for universe set) or as a reference to a Set object | No | "*" |
isSingleton | logical | Indicates if set is a singleton set (TRUE ) or not (FALSE ) | No | FALSE |
records | string vector, data frame | Symbol records | No | NULL |
domainForwarding | logical | Flag or a vector of flags that forces set elements to be recursively included in corresponding parent sets (i.e., implicit set definition) | No | FALSE |
description | string | Description of symbol | No | "" |
- Set Fields
Field | Description | Type |
---|---|---|
description | description of symbol | string |
dimension | dimension of symbol, setting dimension is a shorthand notation to set domain to a list of size n containing "*" | integer |
domain | list of domains given either as string (* for universe set) or as reference to the Set/Alias object | list |
domainForwarding | flag or a vector of flags that forces set elements to be recursively included in corresponding parent sets (i.e., implicit set definition) | logical |
domainLabels | column headings for the records data frame | list of string |
domainNames | string version of domain names | list of string |
domainType | none , relaxed or regular depending on state of domain links | string |
isSingleton | logical if symbol is a singleton set | logical |
name | name of symbol | string |
numberRecords | number of symbol records (i.e., returns nrow(self$records) if not NULL ) | integer |
records | the main symbol records | data frame |
container | reference to the Container that the symbol belongs to | Container |
summary | output a list of only the metadata | list |
- Set Methods
Method | Description | Arguments/Defaults | Returns |
---|---|---|---|
addUELs | adds UELs to the symbol | uels (character), dimension=NULL | NULL |
copy | copies the symbol to the destination container. overwrite=TRUE overwrites the symbol with the same name in destination . Symbol domains are relaxed if destination Container does not contain equivalent domain sets | destination (Container), overwrite=FALSE | NULL |
countDomainViolations | returns the number of domain violations for the symbol | - | numeric |
countDuplicateRecords | returns the number of duplicate records for the symbol | - | numeric |
findDomainViolations | get a view of records data frame that contain any domain violations | - | data.frame |
findDuplicateRecords | get a view of records data frame that contain duplicate records. keep = "first" (finds all duplicates while keeping the first instance as unique), keep="last" (finds all duplicates while keeping the last instance as unique), or keep=FALSE (finds all duplicates) | keep = first | data.frame |
dropDomainViolations | drops domain violations for the symbol | - | - |
dropDuplicateRecords | drops duplicate records for the Symbol | keep = first/last | - |
equals | Check if two Symbol objects are equal | other (Symbol ), checkUELs=TRUE , checkElementText=TRUE , checkMetaData=TRUE , verbose=FALSE | logical |
generateRecords | convenience method to set standard data.frame formatted records. Will generate records with the Cartesian product of all domain sets. The density argument can take any value on the interval [0,1] . If density is < 1, then randomly selected records will be removed. density will accept a numeric of length 1 or dimension . This allows users to specify a density per symbol dimension (when vector) or density of the records dataframe. Random number state can be set with seed argument. | density=1.0 (numeric ) seed=NULL (integer ) | NULL |
getDomainViolations | gets domain violations for the symbol | - | list of DomainViolation |
getSparsity | get the sparsity of the symbol w.r.t the size of full cartesian product of the domain sets | - | numeric |
getUELs | returns the UELs used in the Symbol | dimension = NULL , codes = NULL , ignoreUnused=FALSE | character vector |
hasDomainViolations | returns TRUE if the symbol contains domain violations, FALSE otherwise | - | logical |
hasDuplicateRecords | returns TRUE if the symbol contains duplicate records, FALSE otherwise | - | logical |
isValid | checks if the symbol is in a valid format, throw exceptions if verbose=TRUE , recheck a symbol if force=TRUE | verbose=FALSE force=FALSE | logical |
removeUELs | removes UELs from the symbol | uels=NULL (character), dimension=NULL | NULL |
renameUELs | renames UELs in the symbol | uels (character of same length as current UELs or named character vector), dimension=NULL , allowMerge=FALSE (logical). If allowMerge = TRUE , the underlying integer mapping of a factor is allowed to change to offer additional data flexibility | NULL |
reorderUELs | reorders UELs in the symbol that appear in the symbol dimensions . If uels is NULL , the UELs are reordered based on symbol records, unused UELs are moved to the end. If dimensions is NULL then reorder UELs in all dimensions of the symbol | uels=NULL (NULL or character of same length as current UELs or named character vector), dimension=NULL (numeric) | NULL |
setRecords | main convenience method to set standard data frame formatted records | records (string vector, list, data frame) | NULL |
setUELs | sets UELs for the Symbol | uels (character), dimension , rename=FALSE | NULL |
- Adding Set Records
Three possibilities exist to assign symbol records to a set: We show a few examples of ways to create differently structured sets.
- Example #1 - Create a 1D set from a vector
- library(gamstransfer)m = Container$new()i = Set$new(m, "i", records = c("seattle", "san-diego"))# NOTE: the above syntax is equivalent to -# i = Set$new(m, "i")# i$setRecords(c("seattle", "san-diego"))# NOTE: the above syntax is also equivalent to -# m$addSet("i", records= c("seattle", "san-diego"))# NOTE: the above syntax is also equivalent to -# i = m$addSet("i")# i$setRecords(c("seattle", "san-diego"))# NOTE: the above syntax is also equivalent to -# m$addSet("i")# m["i"]$setRecords(c("seattle", "san-diego"))> i$recordsuni1 seattle2 san-diego
- Example #2 - Create a 2D set from a list
- library(gamstransfer)m = Container$new()k = Set$new(m, "k", c("*", "*"), records=list("seattle", "san-diego"))# NOTE: the above syntax is equivalent to -# k = Set$new(m, "k", c("*", "*"))# k$setRecords(list("seattle", "san-diego"))# NOTE: the above syntax is also equivalent to -# m$addSet("k", c("*","*"), records=list("seattle", "san-diego"))# NOTE: the above syntax is also equivalent to -# k = m$addSet("k", c("*","*"))# k$setRecords(list("seattle", "san-diego"))# NOTE: the above syntax is also equivalent to -# m$addSet("k", c("*", "*"))# m["k"]$setRecords(list("seattle", "san-diego"))> k$recordsuni_1 uni_21 seattle san-diego
- Example #3 - Create a 1D set from a data frame slice
- library(gamstransfer)m = Container$new()dist = data.frame(from = c("seattle", "seattle", "seattle","san-diego", "san-diego", "san-diego"),to = c("new-york", "chicago", "topeka","new-york", "chicago", "topeka"),thousand_miles = c(2.5, 1.7, 1.8, 2.5, 1.8, 1.4))l = Set$new(m, "l", records = unique(dist[["from"]]))# NOTE: the above syntax is equivalent to -# l = Set$new(m, "l")# l$setRecords(unique(dist[["from"]]))# NOTE: the above syntax is also equivalent to -# m$addSet("l", records=unique(dist[["from"]]))# NOTE: the above syntax is also equivalent to -# l = m$addSet("l")# l$setRecords(unique(dist[["from"]]))# NOTE: the above syntax is also equivalent to -# m$addSet("l")# m["l"]$setRecords(unique(dist[["from"]]))> l$recordsuni1 seattle2 san-diego
Set element text is very handy when labeling specific set elements within a set. A user can add a set element text directly with a set element. Note that it is not required to label all set elements, as can be seen in the following example.
- Example #4 - Add set element text
The primary advantage of the setRecords
method is that GAMS Transfer R will convert many different (and convenient) data types into the standard data format (a data frame). Users that require higher performance will want to directly pass the Container a reference to a valid data frame, thereby skipping some of these computational steps. This places more burden on the user to pass the data in a valid standard form, but it speeds the records setting process.
In this section, we walk the user through an example of how to set records directly.
- Example #5 - Directly set records (1D set)
Stepping through this example we take the following steps:
- Create an empty Container
- Create a GAMS set
i
in the Container, but do not set therecords
- Create a data frame (manually, in this example) taking care to follow the standard format
- The data frame has the right shape and column labels so we can proceed to set the records.
- We need to cast the
uni_1
column as afactor
, so we create a custom ordered category type usingfactor
- Finally, we set the records directly by passing a reference to
df_i
into the symbol records attribute. The setter function ofrecords
checks that a data frame is being set, but does not check validity. Thus, as a final step, we call the$isValid()
method to verify that the symbol is valid.
- Note
- Users can debug their data frames by running
<symbol_name>$isValid(verbose=TRUE)
to get feedback about their data.
- Example #6 - Directly set records (1D subset)
This example is more subtle in that we want to create a set j
that is a subset of i
. We create the set i
using the setRecords
method but then set the records directly for j
. There are two important details to note: 1) the column labels in df_j
now reflect the standard format for a symbol with a domain set (as opposed to the universe) and 2) we create the factors by referencing the parent set (i
) for the levels
(instead of referencing itself).
- Note
- One can also use the genereateRecords() method to automatically populate randomly generated symbol records in the standard format.
Parameter
- Parameter Constructor
Argument | Type | Description | Required | Default |
---|---|---|---|---|
container | Container | A reference to the Container object that the symbol is being added to | Yes | - |
name | string | Name of symbol | Yes | - |
domain | list | List of domains given either as a string ("*" for universe set) or as a reference to a Set object, an empty domain list will create a scalar parameter | No | NULL |
records | many | Symbol records | No | NULL |
domainForwarding | logical | Flag or a vector of flags that forces parameter elements to be recursively included in corresponding parent sets (i.e.,implicit set definition) | No | FALSE |
description | string | Description of symbol | No | "" |
- Parameter Fields
Field | Description | Type |
---|---|---|
container | reference to the Container that the symbol belongs to | Container |
defaultValues | default values for the symbol | numeric |
description | description of symbol | character |
dimension | dimension of symbol, setting dimension is a shorthand notation to set domain to a list of size n containing "*" | numeric ,integer |
domain | list of domains given either as a string ("*" for universe set) or as a reference to the Set/Alias object | list |
domainForwarding | Flag or a vector of flags that forces parameter elements to be recursively included in corresponding parent sets (i.e.,implicit set definition) | logical |
domainLabels | column headings for the records data frame | list of string |
domainNames | string version of domain names | list of string |
domainType | none , relaxed or regular depending on state of domain links | string |
isScalar | TRUE if self$dimension = 0 | logical |
name | name of symbol | string |
numberRecords | number of symbol records (i.e., returns nrow(self$records) if not NULL ) | integer |
records | the main symbol records | data frame |
shape | a vector describing the array dimensions if records were converted with $toDense() | vector |
summary | output a list of only the metadata | list |
- Parameter Methods
Method | Description | Arguments/Defaults | Returns |
---|---|---|---|
addUELs | adds UELs to the symbol | uels (character), dimension=NULL | NULL |
copy | copies the symbol to the destination container. overwrite=TRUE overwrites the symbol with the same name in destination . Symbol domains are relaxed if destination Container does not contain equivalent domain sets | destination (Container), overwrite=FALSE | NULL |
countDomainViolations | returns the number of domain violations for the symbol | - | numeric |
countDuplicateRecords | returns the number of duplicate records for the symbol | - | numeric |
countEps | total number of SpecialValues$EPS in value column | - | integer |
countNA | total number of SpecialValues[["NA"]] in value column | - | integer |
countNegInf | total number of SpecialValues$NEGINF in value column | - | integer |
countPosInf | total number of SpecialValues$POSINF in value column | - | integer |
countUndef | total number of SpecialValues$UNDEF in value column | - | integer |
dropDomainViolations | drops domain violations for the symbol | - | - |
dropDuplicateRecords | drops duplicate records for the Symbol. keep = "first" (drops all duplicates while keeping the first instance as unique), keep="last" (drops all duplicates while keeping the last instance as unique), or keep=FALSE (drops all duplicates) | keep = "first" | - |
equals | Check if two Symbol objects are equal | other (Symbol ), checkUELs=TRUE , checkMetaData=TRUE , rtol=0 (relative tolernace), atol=0 (absolute tolerance), verbose=FALSE | logical |
findDomainViolations | get a view of records data frame that contain any domain violations | - | data.frame |
findDuplicateRecords | get a view of records data frame that contain duplicate records. keep = "first" (finds all duplicates while keeping the first instance as unique), keep="last" (finds all duplicates while keeping the last instance as unique), or keep=FALSE (finds all duplicates) | keep = first | data.frame |
generateRecords | convenience method to set standard data.frame formatted records. Will generate records with the Cartesian product of all domain sets. The density argument can take any value on the interval [0,1] . If density is < 1, then randomly selected records will be removed. density will accept a numeric of length 1 or dimension . This allows users to specify a density per symbol dimension (when vector) or the density of records dataframe. Random numbers can be generated by passing a user-defined function func(size) to func argument (runif() by default). Random number state can be set with seed argument. | density=1.0 (numeric ) func=runif() seed=NULL (integer ) | NULL |
getDomainViolations | gets domain violations for the symbol | - | list of DomainViolation |
getMaxValue | get the maximum value in value column | - | numeric |
getMaxAbsValue | get the maximum absolute value in value column | - | numeric |
getMeanValue | get the mean value in value column | - | numeric |
getMinValue | get the minimum value in value column | - | numeric |
getSparsity | get the sparsity of the symbol w.r.t the size of full cartesian product of the domain sets | - | numeric |
getUELs | returns the UELs used in the Symbol | dimension = NULL , codes = NULL , ignoreUnused=FALSE | character vector |
hasDomainViolations | returns TRUE if the symbol contains domain violations, FALSE otherwise | - | logical |
hasDuplicateRecords | returns TRUE if the symbol contains duplicate records, FALSE otherwise | - | logical |
isValid | checks if the symbol is in a valid format, throw exceptions if verbose=TRUE , recheck a symbol if force=TRUE | verbose=FALSE force=FALSE | logical |
removeUELs | removes UELs from the symbol | uels=NULL (character), dimension=NULL | NULL |
renameUELs | renames UELs in the symbol | uels (character of same length as current UELs or named character vector), dimension=NULL , allowMerge=FALSE (logical). If allowMerge = TRUE , the underlying integer mapping of a factor is allowed to change to offer additional data flexibility | NULL |
reorderUELs | reorders UELs in the symbol that appear in the symbol dimensions . If uels is NULL , the UELs are reordered based on symbol records, unused UELs are moved to the end. If dimensions is NULL then reorder UELs in all dimensions of the symbol | uels=NULL (NULL or character of same length as current UELs or named character vector), dimension=NULL (numeric) | NULL |
setRecords | main convenience method to set standard data frame records | records (many types) | NULL |
setUELs | sets UELs for the Symbol | uels (character), dimension , rename=FALSE | NULL |
toDense | convert value column of a symbol to a dense matrix or array format | - | array or matrix |
whereMax | find the row number in records data frame with a maximum value (return the first instance only) | - | integer |
whereMaxAbs | find the row number in records data frame with a maximum absolute value (return the first instance only) | - | integer |
whereMin | find the row number in records data frame with a minimum value (return the first instance only) | - | integer |
- Adding Parameter Records
Three possibilities exist to assign symbol records to a parameter: We show a few examples of ways to create differently structured parameters:
- Example #1 - Create a GAMS scalar
- Note
- GAMS Transfer R will still convert scalar values to a standard format (i.e., a data frame with a single row and column).
- Example #2 - Create a 2D parameter (defined over a set) from a
- data frame slice
- Example #3 - Create a 2D parameter from an array using setRecords
As with Sets, the primary advantage of the setRecords
method is that GAMS Transfer will convert many different (and convenient) data types into the standard data format (data frame). Users that require higher performance will want to directly pass the Container a reference to a valid data frame, thereby skipping some of these computational steps. This places more burden on the user to pass the data in a valid standard form, but it speeds the records setting process. In this section, we walk the user through an example of how to set records directly.
- Example #4 - Correctly set records (directly)
In this example, we create a large parameter (31,536,000 records and 8880 unique domain elements. We mimic data that is labeled for every second in one year) and assign it to a parameter with a$records
. GAMS Transfer R requires that all domain columns must be ordered factors. The records
setter function does very little work other than checking if the object being set is a data frame. This places more responsibility on the user to create a data frame that complies with the standard format. In Example #1, we take care to properly reference the factor from the domain sets, and ensure that the symbol a
is valid with a$isValid() = TRUE
.
Users will need to use the $isValid(verbose=TRUE)
method to debug any structural issues. As an example, we incorrectly generate categorical data types by passing the data frame constructor the generic factor
argument. This creates factor columns, but they are not ordered and they do not reference the underlying domain set. These errors result in a
being invalid.
- Example #5 - Incorrectly set records (directly)
- Note
- One can also use the genereateRecords() method to automatically populate randomly generated symbol records in the standard format.
Variable
- Variable Constructor
Argument | Type | Description | Required | Default |
---|---|---|---|---|
container | Container | A reference to the Container object that the symbol is being added to | Yes | - |
name | string | Name of symbol | Yes | - |
type | string | Type of variable being created [binary , integer , positive , negative , free , sos1 , sos2 , semicont , semiint ] | No | free |
domain | list , vector | List, vector of domains given either as a string ("*" for universe set) or as a reference to a Set object, an empty domain list will create a scalar variable | No | NULL |
records | many | Symbol records | No | NULL |
domainForwarding | logical | Flag or a vector of flags that forces variable elements to be recursively included in corresponding parent sets (i.e.,implicit set definition) | No | FALSE |
description | string | Description of symbol | No | "" |
- Variable Fields
Field | Description | Type |
---|---|---|
container | reference to the Container that the symbol belongs to | Container |
defaultValues | default values for the symbol | numeric (named vector) |
description | description of symbol | string |
dimension | dimension of symbol, setting dimension is a shorthand notation to set domain to a list of size n containing "*" | integer |
domain | list of domains given either as string (* for universe set) or as reference to the Set/Alias object | list |
domainForwarding | Flag or a vector of flags that forces variable elements to be recursively included in corresponding parent sets (i.e.,implicit set definition) | logical |
domainLabels | column headings for the records data frame | list of string |
domainNames | string version of domain names | list of string |
domainType | none , relaxed or regular depending on state of domain links | string |
isScalar | TRUE if self$dimension = 0 | logical |
name | name of symbol | string |
numberRecords | number of symbol records (i.e., returns nrow(self$records) if not NULL ) | integer |
records | the main symbol records | data frame |
shape | a vector describing the array dimensions if records were converted with $toDense() | vector |
summary | output a list of only the metadata | list |
type | string type of variable | list |
- Variable Methods
Method | Description | Arguments/Defaults | Returns |
---|---|---|---|
addUELs | adds UELs to the symbol | uels (character), dimension=NULL | NULL |
copy | copies the symbol to the destination container. overwrite=TRUE overwrites the symbol with the same name in destination . Symbol domains are relaxed if destination Container does not contain equivalent domain sets | destination (Container), overwrite=FALSE | NULL |
countDomainViolations | returns the number of domain violations for the symbol | - | numeric |
countDuplicateRecords | returns the number of duplicate records for the symbol | - | numeric |
countEps | total number of SpecialValues$EPS across all columns | columns = "level" | integer |
countNA | total number of SpecialValues[["NA"]] across all columns | columns = "level" | integer |
countNegInf | total number of SpecialValues$NEGINF across all columns | columns = "level" | integer |
countPosInf | total number of SpecialValues$POSINF across all columns | columns = "level" | integer |
countUndef | total number of SpecialValues$UNDEF across all columns | columns = "level" | integer |
dropDomainViolations | drops domain violations for the symbol | - | - |
dropDuplicateRecords | drops duplicate records for the Symbol. keep = "first" (drops all duplicates while keeping the first instance as unique), keep="last" (drops all duplicates while keeping the last instance as unique), or keep=FALSE (drops all duplicates) | keep = "first" | - |
equals | Check if two Symbol objects are equal | other (Symbol ), columns=NULL (character) (if NULL all columns are compared), checkUELs=TRUE , checkMetaData=TRUE , rtol=0 (relative tolernace), atol=0 (absolute tolerance), verbose=FALSE | logical |
findDomainViolations | get a view of the records data frame that contain any domain violations | - | data.frame |
findDuplicateRecords | get a view of records data frame that contain duplicate records. keep = "first" (finds all duplicates while keeping the first instance as unique), keep="last" (finds all duplicates while keeping the last instance as unique), or keep=FALSE (finds all duplicates) | keep = first | data.frame |
generateRecords | convenience method to set standard data.frame formatted records. Will generate records with the Cartesian product of all domain sets. The density argument can take any value on the interval [0,1] . If density is < 1, then randomly selected records will be removed. density will accept a numeric of length 1 or dimension . This allows users to specify a density per symbol dimension (when vector) or the density of records dataframe. Random numbers can be generated by passing a user-defined function func(size) to func argument (runif() by default). Random number state can be set with seed argument. | density=1.0 (numeric ) func=runif() (named list of functions, function, NULL) seed=NULL (integer ) | NULL |
getDomainViolations | gets domain violations for the symbol | - | list of DomainViolation |
getMaxValue | get the maximum value across all columns | columns = "level" | numeric |
getMaxAbsValue | get the maximum absolute value across all columns | columns = "level" | numeric |
getMinValue | get the minimum value across all columns | columns = "level" | numeric |
getMeanValue | get the mean value across all columns | columns = "level" | numeric |
getSparsity | get the sparsity of the symbol w.r.t the size of full cartesian product of the domain sets | - | numeric |
getUELs | returns the UELs used in the Symbol | dimension = NULL , codes = NULL , ignoreUnused=FALSE | character vector |
hasDomainViolations | returns TRUE if the symbol contains domain violations, FALSE otherwise | - | logical |
hasDuplicateRecords | returns TRUE if the symbol contains duplicate records, FALSE otherwise | - | logical |
isValid | checks if the symbol is in a valid format, throw exceptions if verbose=TRUE , recheck a symbol if force=TRUE | verbose=FALSE force=FALSE | logical |
removeUELs | removes UELs from the symbol | uels=NULL (character), dimension=NULL | NULL |
renameUELs | renames UELs in the symbol | uels (character of same length as current UELs or named character vector), dimension=NULL , allowMerge=FALSE (logical). If allowMerge = TRUE , the underlying integer mapping of a factor is allowed to change to offer additional data flexibility | NULL |
reorderUELs | reorders UELs in the symbol that appear in the symbol dimensions . If uels is NULL , the UELs are reordered based on symbol records, unused UELs are moved to the end. If dimensions is NULL then reorder UELs in all dimensions of the symbol | uels=NULL (NULL or character of same length as current UELs or named character vector), dimension=NULL (numeric) | NULL |
setRecords | main convenience method to set standard data frame records | records (many types) | NULL |
setUELs | sets UELs for the Symbol | uels (character), dimension , rename=FALSE | NULL |
toDense | convert symbol to a dense matrix or array format | column = level | array or matrix |
whereMax | find the row number in records data frame with a maximum value (return the first instance only) | column = "level" | integer |
whereMaxAbs | find the row number in records data frame with a maximum absolute value (return the first instance only) | column = "level" | integer |
whereMin | find the row number in records data frame with a minimum value (return the first instance only) | column = "level" | integer |
- Adding Variable Records
Three possibilities exist to assign symbol records to a variable: We show a few examples of ways to create differently structured variables:
- Example #1 - Create a GAMS scalar variable
- Example #2 - Create a 2D positive variable, specifying no numerical data
- Example #3 - Create a 2D variable (defined over a set) from a matrix
As with Sets, the primary advantage of the setRecords
method is that GAMS Transfer will convert many different (and convenient) data types into the standard data format (data frame). Users that require higher performance will want to directly pass the Container a reference to a valid data frame, thereby skipping some of these computational steps. This places more burden on the user to pass the data in a valid standard form, but it speeds the records setting process. In this section, we walk the user through an example of how to set records directly.
- Example #4 - Correctly set records (directly)
In this example, we create a large variable (31,536,000 records and 8880 unique domain elements. We mimic data that is labeled for every second in one year) and assign it to a variable with a$records
. GAMS Transfer R requires that all domain columns must be ordered factors. The records
setter function does very little work other than checking if the object being set is a data frame. This places more responsibility on the user to create a data frame that complies with the standard format. In Example #1, we take care to properly reference the factor from the domain sets and ensure that the symbol a
is valid with a$isValid() = TRUE
.
As with Set and Parameters, users can use the $isValid(verbose=TRUE)
method to debug any structural issues.
- Note
- One can also use the genereateRecords() method to automatically populate randomly generated symbol records in the standard format.
Equation
- Equation Constructor
Argument | Type | Description | Required | Default |
---|---|---|---|---|
container | Container | A reference to the Container object that the symbol is being added to | Yes | - |
name | string | Name of symbol | Yes | - |
type | string | Type of equation being created [eq (or E /e ), geq (or G /g ), leq (or L /l ), nonbinding (or N /n ), external (or X /x )] | No | free |
domain | list , vector | List, vector of domains given either as a string ("*" for universe set) or as a reference to a Set object, an empty domain list will create a scalar equation | No | NULL |
records | many | Symbol records | No | NULL |
domainForwarding | logical | Flag or a vector of flags that forces equation elements to be recursively included in corresponding parent sets (i.e.,implicit set definition) | No | FALSE |
description | string | Description of symbol | No | "" |
- Equation Fields
Field | Description | Type |
---|---|---|
container | reference to the Container that the symbol belongs to | Container |
defaultValues | default values for the symbol | numeric (named vector) |
description | description of symbol | string |
dimension | dimension of symbol, setting dimension is a shorthand notation to set domain to a list of size n containing "*" | integer |
domain | list of domains given either as string (* for universe set) or as reference to the Set/Alias object | list |
domainForwarding | Flag or a vector of flags that forces equation elements to be recursively included in corresponding parent sets (i.e.,implicit set definition) | logical |
domainLabels | column headings for the records data frame | list of string |
domainNames | string version of domain names | list of string |
domainType | none , relaxed or regular depending on state of domain links | string |
isScalar | TRUE if self$dimension = 0 | logical |
name | name of symbol | string |
numberRecords | number of symbol records (i.e., returns nrow(self$records) if not NULL ) | integer |
records | the main symbol records | data frame |
shape | a vector describing the array dimensions if records were converted with $toDense() | vector |
summary | output a list of only the metadata | list |
type | string type of equation | list |
- Equation Methods
Method | Description | Arguments/Defaults | Returns |
---|---|---|---|
addUELs | adds UELs to the symbol | uels (character), dimension=NULL | NULL |
copy | copies the symbol to the destination container. overwrite=TRUE overwrites the symbol with the same name in destination . Symbol domains are relaxed if destination Container does not contain equivalent domain sets | destination (Container), overwrite=FALSE | NULL |
countDomainViolations | returns the number of domain violations for the symbol | - | numeric |
countDuplicateRecords | returns the number of duplicate records for the symbol | - | numeric |
countEps | total number of SpecialValues$EPS across all columns | columns = "level" | integer |
countNA | total number of SpecialValues[["NA"]] across all columns | columns = "level" | integer |
countNegInf | total number of SpecialValues$NEGINF across all columns | columns = "level" | integer |
countPosInf | total number of SpecialValues$POSINF across all columns | columns = "level" | integer |
countUndef | total number of SpecialValues$UNDEF across all columns | columns = "level" | integer |
dropDomainViolations | drops domain violations for the symbol | - | - |
dropDuplicateRecords | drops duplicate records for the Symbol. keep = "first" (drops all duplicates while keeping the first instance as unique), keep="last" (drops all duplicates while keeping the last instance as unique), or keep=FALSE (drops all duplicates) | keep = "first" | - |
equals | Check if two Symbol objects are equal | other (Symbol ), columns=NULL (character) (if NULL all columns are compared), checkUELs=TRUE , checkMetaData=TRUE , rtol=0 (relative tolernace), atol=0 (absolute tolerance), verbose=FALSE | logical |
findDomainViolations | get a view of records data frame that contain any domain violations | - | data.frame |
findDuplicateRecords | get a view of records data frame that contain duplicate records. keep = "first" (finds all duplicates while keeping the first instance as unique), keep="last" (finds all duplicates while keeping the last instance as unique), or keep=FALSE (finds all duplicates) | keep = first | data.frame |
generateRecords | convenience method to set standard data.frame formatted records. Will generate records with the Cartesian product of all domain sets. The density argument can take any value on the interval [0,1] . If density is < 1, then randomly selected records will be removed. density will accept a numeric of length 1 or dimension . This allows users to specify a density per symbol dimension (when vector) or the density of records dataframe. Random numbers can be generated by passing a user-defined function func(size) to func argument (runif() by default). Random number state can be set with seed argument. | density=1.0 (numeric ) func=runif() (named list of functions, function, NULL) seed=NULL (integer ) | NULL |
getDomainViolations | gets domain violations for the symbol | - | list of DomainViolation |
getMaxValue | get the maximum value across all columns | columns = "level" | numeric |
getMaxAbsValue | get the maximum absolute value across all columns | columns = "level" | numeric |
getMinValue | get the minimum value iacross all columns | columns = "level" | numeric |
getMeanValue | get the mean value across all columns | columns = "level" | numeric |
getSparsity | get the sparsity of the symbol w.r.t the size of full cartesian product of the domain sets | - | numeric |
getUELs | returns the UELs used in the Symbol | dimension = NULL , codes = NULL , ignoreUnused=FALSE | character vector |
hasDomainViolations | returns TRUE if the symbol contains domain violations, FALSE otherwise | - | logical |
hasDuplicateRecords | returns TRUE if the symbol contains duplicate records, FALSE otherwise | - | logical |
isValid | checks if the symbol is in a valid format, throw exceptions if verbose=TRUE , recheck a symbol if force=TRUE | verbose=FALSE force=FALSE | logical |
removeUELs | removes UELs from the symbol | uels=NULL (character), dimension=NULL | NULL |
renameUELs | renames UELs in the symbol | uels (character of same length as current UELs or named character vector), dimension=NULL , allowMerge=FALSE (logical). If allowMerge = TRUE , the underlying integer mapping of a factor is allowed to change to offer additional data flexibility | NULL |
reorderUELs | reorders UELs in the symbol that appear in the symbol dimensions . If uels is NULL , the UELs are reordered based on symbol records, unused UELs are moved to the end. If dimensions is NULL then reorder UELs in all dimensions of the symbol | uels=NULL (NULL or character of same length as current UELs or named character vector), dimension=NULL (numeric) | NULL |
setRecords | main convenience method to set standard data frame records | records (many types) | NULL |
setUELs | sets UELs for the Symbol | uels (character), dimension , rename=FALSE | NULL |
toDense | convert symbol to a dense matrix or array format | column = "value" | array or matrix |
whereMax | find the row number in records data frame with a maximum value (return the first instance only) | column="level" | integer |
whereMaxAbs | find the row number in records data frame with a maximum absolute value (return the first instance only) | column="level" | integer |
whereMin | find the row number in records data frame with a minimum value (return the first instance only) | column="level" | integer |
- Adding Equation Records
Three possibilities exist to assign symbol records to an equation: We show a few examples of ways to create differently structured equations:
- Example #1 - Create a GAMS scalar equation
- Example #2 - Create a 2D positive equation, specifying no numerical data
- Example #3 - Create a 2D equation (defined over a set) from a matrix
As with sets, parameters, and variables the primary advantage of the setRecords
method is that GAMS Transfer will convert many different (and convenient) data types into the standard data format (data frame). Users that require higher performance will want to directly pass the Container a reference to a valid data frame, thereby skipping some of these computational steps. This places more burden on the user to pass the data in a valid standard form, but it speeds the records setting process. In this section, we walk the user through an example of how to set records directly.
- Example #4 - Correctly set records (directly)
In this example, we create a large equation (31,536,000 records and 8880 unique domain elements. We mimic data that is labeled for every second in one year) and assign it to an equation with a$records
. GAMS Transfer R requires that all domain columns must be ordered factors. The records
setter function does very little work other than checking if the object being set is a data frame. This places more responsibility on the user to create a data frame that complies with the standard format. In Example #1, we take care to properly reference the factor from the domain sets and ensure that the symbol a
is valid in the end with a$isValid() = TRUE
.
As with sets, parameters, and variables, users can use the $isValid(verbose=TRUE)
method to debug any structural issues.
- Note
- One can also use the genereateRecords() method to automatically populate randomly generated symbol records in the standard format.
Alias
- Alias Constructor
Argument | Type | Description | Required | Default |
---|---|---|---|---|
container | Container | A reference to the Container object that the symbol is being added to | Yes | - |
name | string | Name of symbol | Yes | - |
aliasWith | Set object | set object to create an alias for | Yes | - |
- Example - Creating an alias from a set
GAMS Transfer R only stores the reference to the parent set as part of the alias structure. Most properties that are called from an alias object simply point to the properties of the parent set (with the exception of container
, name
, and aliasWith
). It is possible to create an alias from another alias object. In this case, a recursive search will be performed to find the root parent set. This is the set that will ultimately be stored as the aliasWith
field. We can see this behavior in the following example:
- Alias Fields
Field | Description | Type |
---|---|---|
aliasWith | aliased object | Set |
description | description of symbol | string |
dimension | dimension of symbol, setting dimension is a shorthand notation to set domain to a list of size n containing "*" | integer |
domainForwarding | Flag or a vector of flags that forces Alias elements to be recursively included in corresponding parent sets (i.e.,implicit set definition) | logical |
domainLabels | column headings for the records data frame | list of string |
domainNames | string version of domain names | list of string |
domainType | none , relaxed or regular depending on state of domain links | string |
isSingleton | logical if symbol is a singleton set | logical |
name | name of symbol | string |
numberRecords | number of symbol records (i.e., returns nrow(self$records) if not NULL ) | integer |
records | the main symbol records | data frame |
container | reference to the Container that the symbol belongs to | Container |
summary | output a list of only the metadata | list |
- Alias Methods
Method | Description | Arguments/Defaults | Returns |
---|---|---|---|
addUELs | adds UELs to the symbol | uels (character), dimension=NULL | NULL |
copy | copies the Alias and the parent Set to the destination container. overwrite=TRUE overwrites the symbol with the same name in destination . Symbol domains are relaxed if destination Container does not contain equivalent domain sets | destination (Container), overwrite=FALSE | NULL |
countDomainViolations | returns the number of domain violations for the symbol | - | numeric |
countDuplicateRecords | returns the number of duplicate records for the symbol | - | numeric |
dropDomainViolations | drops domain violations for the symbol | - | - |
dropDuplicateRecords | drops duplicate records for the Symbol. keep = "first" (drops all duplicates while keeping the first instance as unique), keep="last" (drops all duplicates while keeping the last instance as unique), or keep=FALSE (drops all duplicates) | keep = "first" | - |
equals | Check if two Symbol objects are equal | other (Symbol ), checkUELs=TRUE , checkElementText=TRUE , checkMetaData=TRUE , verbose=FALSE | logical |
findDomainViolations | get a view of records data frame that contain any domain violations | - | data.frame |
findDuplicateRecords | get a view of records data frame that contain duplicate records. keep = "first" (finds all duplicates while keeping the first instance as unique), keep="last" (finds all duplicates while keeping the last instance as unique), or keep=FALSE (finds all duplicates) | keep = first | data.frame |
generateRecords | convenience method to set standard data.frame formatted records. Will generate records with the Cartesian product of all domain sets. The density argument can take any value on the interval [0,1] . If density is < 1, then randomly selected records will be removed. density will accept a numeric of length 1 or dimension . This allows users to specify a density per symbol dimension (when vector) or the density of records dataframe. Random number state can be set with seed argument. | density=1.0 (numeric ) seed=NULL (integer ) | NULL |
getDomainViolations | gets domain violations for the symbol | - | list of DomainViolation |
getSparsity | get the sparsity of the symbol w.r.t the size of full cartesian product of the domain sets | - | numeric |
getUELs | returns the UELs used in the Symbol | dimension = NULL , codes = NULL , ignoreUnused=FALSE | character vector |
hasDomainViolations | returns TRUE if the symbol contains domain violations, FALSE otherwise | - | logical |
hasDuplicateRecords | returns TRUE if the symbol contains duplicate records, FALSE otherwise | - | logical |
isValid | checks if the symbol is in a valid format, throw exceptions if verbose=TRUE , recheck a symbol if force=TRUE | verbose=FALSE force=FALSE | logical |
removeUELs | removes UELs from the symbol | uels=NULL (character), dimension=NULL | NULL |
renameUELs | renames UELs in the symbol | uels (character of same length as current UELs or named character vector), dimension=NULL , allowMerge=FALSE (logical). If allowMerge = TRUE , the underlying integer mapping of a factor is allowed to change to offer additional data flexibility | NULL |
reorderUELs | reorders UELs in the parent set that appear in the parent set dimensions . If uels is NULL , the UELs are reordered based on symbol records, unused UELs are moved to the end. If dimensions is NULL then reorder UELs in all dimensions of the symbol | uels=NULL (NULL or character of same length as current UELs or named character vector), dimension=NULL (numeric) | NULL |
setRecords | main convenience method to set standard data frame formatted records | records (string vector, list, data frame) | NULL |
setUELs | sets UELs for the Symbol | uels (character), dimension , rename=FALSE | NULL |
- Adding Alias Records
The linked structure of Aliases offers some unique opportunities to access some of the setter functionality of the parent set. Specifically, GAMS Transfer allows the user to change the domain
, description
, dimension
, and records
of the underlying parent set as a shorthand notation. We can see this behavior if we look at a modified Example #1 from adding set records.
- Example - Creating set records through an alias link
- Note
- An alias
$isValid()=TRUE
when the underlying parent set is also valid. If the parent set is removed from the Container the alias will no longer be valid. - One can also use the genereateRecords() method to automatically populate randomly generated symbol records in the standard format.
UniverseAlias
- UniverseAlias Constructor
Argument | Type | Description | Required | Default |
---|---|---|---|---|
container | Container | A reference to the Container object that the symbol is being added to | Yes | - |
name | string | Name of symbol | Yes | - |
- Example - Creating an alias for the Universe
- In GAMS it is possible to create aliases to the universe (i.e., the entire list of UELs) with the syntax:
set i / i1, i2 /;
alias(h,*);
set j / j1, j2 /;
GAMS Transfer R allows creating aliases to the universe set.
In this small example, h
would be associated with all four UELs (i1
, i2
, j1
and j2
) even though set j
was defined after the alias declaration. GAMS Transfer mimics this behavior with the UniverseAlias
class. Internally, the records
attribute will always call the <Container>$getUELs()
. The UniverseAlias
class is fundamentally different from the Alias
class because it does not point to a parent set object. It is not possible to perform operations (like setRecords
or findDomainViolations
) on the parent set through a UniverseAlias
(because there is no parent set object). This means that a UniverseAlias
can be created by only defining the symbol name. We can see this behavior in the following example:
- Note
- Unlike other sets, the universe does not hold on to set
element_text
, thus the returneddata frame
for theUniverseAlias
will only have one column.
- UniverseAlias Fields
Field | Description | Type |
---|---|---|
aliasWith | always "*" | string |
description | always Aliased with * | string |
dimension | always 1 | integer |
domainLabels | always "uni" | character vector |
domainNames | always "*" | character vector |
domainType | always none | string |
isSingleton | always FALSE | logical |
name | name of symbol | string |
numberRecords | number of symbol records (i.e., returns nrow(self$records) if not NULL ) | integer |
records | the main symbol records | data frame |
container | reference to the Container that the symbol belongs to | Container |
summary | output a list of only the metadata | list |
- UniverseAlias Methods
Method | Description | Arguments/Defaults | Returns |
---|---|---|---|
equals | Check if two Symbol objects are equal | other (Symbol ), checkMetaData=TRUE , verbose=FALSE | logical |
copy | copies the symbol to the destination container. overwrite=TRUE overwrites the symbol with the same name in destination . | destination (Container), overwrite=FALSE | NULL |
getSparsity | always 0 | - | numeric |
getUELs | returns the UELs from the Container. Returns only UELs in the data if ignoreUnused=TRUE , otherwise returns all UELs | ignoreUnused=FALSE | character vector |
isValid | checks if the symbol is in a valid format, throw exceptions if verbose=TRUE , recheck a symbol if force=TRUE | verbose=FALSE force=FALSE | logical |
Additional Features
Validating Data
GAMS Transfer R requires that the records for all symbols exist in a standard format (Standard Data Formats) in order for them to be understood by the Container
. It is possible that the data could end up in a state that is inconsistent with the standard format (especially if setting symbol attributes directly). GAMS Transfer R includes the $isValid()
method in order to determine if a symbol is valid. This method returns a logical
. This method does not guarantee that a symbol will be successfully written to GDX. Other data errors (duplicate records, long UEL names, or domain violations) could exist that are not tested in $isValid()
. For example, we create two valid sets and then check them with $isValid()
to be sure.
It is possible to run $isValid()
on both the Container
as well as the symbol object. The Container method $isValid()
will also return FALSE
if there are any invalid symbols in the Container
object. In addition, the Container$isValid()
method also detects broken Container references in symbols and inconsistent symbol naming between the Container$data
field and the symbol objects.
- Example (valid data)
- library(gamstransfer)m = Container$new()i = Set$new(m, "i", records = c("seattle", "san-diego", "washington_dc"))j = Set$new(m, "j", i, records = c("san-diego", "washington_dc"))> i$isValid()[1] TRUE> j$isValid()[1] TRUE> m$isValid()[1] TRUE
Now we create some data that is invalid due to incorrect column names in the records for set j
.
In this example, we use records
field of the symbol j
to set the records. As mentioned in setting the records, when setting records directly, users must adhere to Standard Data Formats. In this example, symbol j
does not have the correct number of columns. Moreover, the column headings do not follow the convention (should be "i_1"). The user can get more detailed error reporting if the verbose
argument is set to TRUE
. For example:
The $isValid()
method checks:
- If the symbol belongs to a Container
- If all domain set symbols exist in the Container
- If all domain set symbols objects are valid
- If all domain sets are one dimensional and not singleton sets
- If records are a data frame (or
NULL
) - If the records
domainLabels
are unique - The shape of the records is congruent with the dimensionality of the symbol
- That all data columns are type
numeric
- To make sure that all domain categories are type
string
- Note
- Calling
$isValid()
too often may have a significant impact on the performance.
Comparing GAMS Transfer objects
Equivalence between two symbols or between two containers can be tested using equals
method. Since the order of records in the records
data frame is not important from a GDX point of view, equals
method compares symbol records
independently from the order in which they are stored in the records data frame. As this requires a merge operation over the domain columns, equals
is a computationally expensive call.
- Attention
- We do not recommend using
equals
method inside large loops or when performance is critical. It is, however, very useful for data debugging.
A quick example shows the syntax of equals
:
One can debug the reason for inequality using the option verbose
.
By default, equals
takes the strictest view of symbol "equality", i.e., everything must be equal. In this case, the symbol names and descriptions differ between the two sets i
and j
. We can relax this with a combination of argument flags. Comparing the two symbols again, but ignoring the meta data (i.e., ignoring the symbol name, description and type (if a Variable or Equation)):
The checkUELs
argument will ensure that the symbol "universe" is the same (in order and content) between two symbols, as illustrated in the following example:
Numerical comparisons are enabled for Parameters
, Variables
and Equations
. Equality can be flexibly defined through the equals
method arguments. Again, the strictest view of equality is taken as the default behavior of equals
.
In the case of variables and equations, it is possible for the user to confine the numerical comparison to certain attributes (level
, marginal
, lower
, upper
and scale
) by specifying the columns
argument as the following example illustrates:
Similar to symbols, one can compare two Container
objects using the equals
method. When comparing Containers
, the data
fields are compared and if the same symbol keys exist in the Containers under comparison, symbol equals
method is used to compare the symbols. Here is a brief example:
Domain Forwarding
GAMS includes the ability to define sets directly from data using the implicit set notation (see: Implicit Set Definition (or: Domain Defining Symbol Declarations)). This notation has an analogue in GAMS Transfer R called domainForwarding
.
- Note
- It is possible to recursively update a subset tree in GAMS Transfer R.
Domain forwarding is available as an argument to all symbol object constructors; the user would simply need to pass domainForwarding=TRUE
to forward domain across all dimensions or as a logical vector domainForwarding=c(TRUE, FALSE,....) to forward domain across selected dimensions.
In this example, we have raw data that is in the dist
data frame, and we want to send the domain information into the i
and j
sets. We take care to pass the set objects as the domain for parameter c
.
- Note
- The element order in the sets
i
andj
mirrors that in the raw data.
We can also selectively use domainForwarding for part of the domain by passing a logical vector to the domainForwarding
argument as shown in the following example. The domain records are forwarded only to the domain set i
but not to the domain set j
.
In this example, we show that domain forwarding will also work recursively to update the entire set lineage. The domain forwarding occurs at the creation of every symbol object. The correct order of elements in set i
is (z, a, b, c)
because the records from j
are forwarded first, and then the records from k
are propagated through (back to i
).
Describing Data
The methods describeSets, describeParameters, describeVariables, and describeEquations allow the user to get a summary view of key data statistics. The returned data frame aggregates the output for a number of other methods (depending on symbol type). A description of each Container method is provided in the following subsections:
describeSets
Argument | Type | Description | Required | Default |
---|---|---|---|---|
symbols | list , string | A list of sets in the Container to include in the output. describeSets will include aliases if they are explicitly passed by the user. | No | NULL (if NULL specified, will assume all sets) |
Returns: data frame
The following table includes a short description of the column headings in the return.
Field / Statistic | Description |
---|---|
name | name of the symbol |
isSingleton | logical if the set is a singleton set |
domain | domain labels for the symbol |
domainType | none , relaxed or regular depending on the symbol state |
dimension | dimension |
numberRecords | number of records in the symbol |
sparsity | 1 - numberRecs/dense where dense is the size of full cartesian product of the domain sets |
- Example #1
- library(gamstransfer)m = Container$new("trnsport.gdx")> m$describeSets()name isSingleton domain domainType dimension numberRecords sparsity1 i FALSE * none 1 2 NA2 j FALSE * none 1 3 NA
- Example #2 – with aliases
describeParameters
Argument | Type | Description | Required | Default |
---|---|---|---|---|
symbols | list , string | A list of parameters in the Container to include in the output | No | NULL (if NULL specified, will assume all parameters) |
Returns: data frame
The following table includes a short description of the column headings in the return.
Field / Statistic | Description |
---|---|
name | name of the symbol |
domain | domain labels for the symbol |
domainType | none , relaxed or regular depending on the symbol state |
dimension | dimension |
numberRecords | number of records in the symbol |
min | min value in data |
mean | mean value in data |
max | max value in data |
whereMin | row number min value (if multiple, returns only first occurrence) |
sparsity | 1 - numRecs/dense where where dense is the size of full cartesian product of the domain sets |
describeVariables
Argument | Type | Description | Required | Default |
---|---|---|---|---|
symbols | list , string | A list of variables in the Container to include in the output | No | NULL (if NULL specified, will assume all variables) |
Returns: data frame
The following table includes a short description of the column headings in the return.
Field / Statistic | Description |
---|---|
name | name of the symbol |
type | type of variable (i.e., binary ,integer ,positive ,negative ,free ,sos1 ,sos2 ,semicont ,semiint ) |
domain | domain labels for the symbol |
domainType | none , relaxed or regular depending on the symbol state |
dimension | dimension |
numberRecords | number of records in the symbol |
sparsity | 1 - numRecs/dense , where dense is the size of full cartesian product of the domain sets |
minLevel | min value in the level column |
meanLevel | mean value in the level column |
maxLevel | max value in the level column |
whereMaxAbsLevel | max absolute value in the level column |
describeEquations
Argument | Type | Description | Required | Default |
---|---|---|---|---|
symbols | list , string | A list of equations in the Container to include in the output | No | NULL (if NULL specified, will assume all variables) |
Returns: data frame
The following table includes a short description of the column headings in the return.
Field / Statistic | Description |
---|---|
name | name of the symbol |
type | type of variable (i.e., binary ,integer ,positive ,negative ,free ,sos1 ,sos2 ,semicont ,semiint ) |
domain | domain labels for the symbol |
domainType | none , relaxed or regular depending on the symbol state |
dimension | dimension |
numberRecords | number of records in the symbol |
sparsity | 1 - numRecs/dense , where dense is the size of full cartesian product of the domain sets |
minLevel | min value in the level column |
meanLevel | mean value in the level column |
maxLevel | max value in the level column |
whereMaxAbsLevel | max absolute value in the level column |
describeAliases
Argument | Type | Description | Required | Default |
---|---|---|---|---|
symbols | list , string | A list of aliases in the Container to include in the output. | No | NULL (if NULL specified, will assume all aliases) |
Returns: data frame
The following table includes a short description of the column headings in the return.
Field / Statistic | Description |
---|---|
name | name of the symbol |
aliasWith | name of the parent set |
isSingleton | logical if an alias of a singleton set |
domain | domain labels for the symbol |
domainType | none , relaxed or regular depending on the symbol state |
dimension | dimension |
numberRecords | number of records in the symbol |
sparsity | 1 - numberRecs/dense , where dense is the size of full cartesian product of the domain sets |
- Example #1
- library(gamstransfer)m = Container$new()i = Set$new(m, "i", records = paste0("i",1:5))j = Set$new(m, "j", records = paste0("j",1:10))ip = Alias$new(m, "ip", i)ipp = Alias$new(m, "ipp", ip)jp = Alias$new(m, "jp", j)> m$describeAliases()name aliasWith isSingleton domain domainType dimension numberRecords sparsity1 ip i FALSE * none 1 5 NA2 ipp i FALSE * none 1 5 NA3 jp j FALSE * none 1 10 NA
Matrix Generation
GAMS Transfer R stores data in a "flat" format, that is, one record entry per data frame row. However, it is often necessary to convert this data format into a matrix/array format. GAMS Transfer R enables users to do this with relative ease using the toDense
symbol methods This method will return a dense N
-dimensional array (matrix for 2-Dimensions) with each dimension corresponding to the GAMS symbol dimension; it is possible to output an array up to 20 dimensions (a GAMS limit).
- Example (1D data w/o domain linking (i.e., a relaxed domain))
Note that the parameter a
is not linked to another symbol, so when converting to a matrix, the indexing is referenced to the data structure in a$records
. Defining a sparse parameter a
over a set i
allows us to extract information from the i
domain and construct a very different dense matrix, as the following example shows:
- Example (2D data w/ domain linking)
- Note
- If there are unused UELs in the domain symbol,
toDense()
requires that the unused UELs are at the end of UEL list. One can achieve this by calling thereorderUELs()
method for the domain symbol. Similarly, if the symbol records are in a different order than that of domain symbol UEL, UELs should be reordered to follow the record order. This can also be achived usingreorderUELs()
symbol method.
The Universe Set
A Unique Element (UEL) is an (i,s)
pair where i
is an identification number for a string s
. A list of all UELs is also known as 'the universe' or 'the universe set'. GAMS uses UELs to efficiently store domain entries of a record by storing the UEL ID i
of a domain entry instead of the actual string s
. This avoids storing the same string multiple times. The concept of UELs also exists in R and is called a "factor". GAMS Transfer R leverages these types in order to efficiently store strings and enable domain checking within the R environment.
Each domain column in a data frame can be a factor, the effect is that each symbol maintains its own list of UELs per dimension. R lets the user choose if levels in a factor should be regarded as ordered. GAMS Transfer R relies exclusively on ordered
factors. By using ordered factors, GAMS Transfer R will order the UELs such that elements appear in the order in which they appeared in the data (which is how GAMS defines the UELs). GAMSTransfer
allows the user to reorder the UELs with the uelPriority
argument in the $write()
method.
GAMS Transfer R does not keep track of the UELs separately from other symbols in the Container, it will be created internal to the $write()
method and is based on the order in which data is added to the container. The user can access the current state of UELs with the $getUELs()
container method. For example, we set a two dimensional set:
Customize The Universe Set
GAMS Transfer R allows the users to customize the Universe Set with the help of Symbol UELs methods shown in the following table.
Method | Description | Arguments/Defaults | Returns |
---|---|---|---|
addUELs | adds UELs to the symbol | uels (character), dimension=NULL | NULL |
getUELs | returns the UELs used in the Symbol | dimension = NULL , codes = NULL , ignoreUnused=FALSE | character vector |
removeUELs | removes UELs from the symbol | uels=NULL (character), dimension=NULL | NULL |
renameUELs | renames UELs in the symbol | uels (character of same length as current UELs or named character vector), dimension=NULL , allowMerge=FALSE (logical). If allowMerge = TRUE , the underlying integer mapping of a factor is allowed to change to offer additional data flexibility | NULL |
reorderUELs | reorders UELs in the symbol that appear in the symbol dimensions . If uels is NULL , the UELs are reordered based on symbol records, unused UELs are moved to the end. If dimensions is NULL then reorder UELs in all dimensions of the symbol | uels=NULL (NULL or character of same length as current UELs or named character vector), dimension=NULL (numeric) | NULL |
setUELs | sets UELs for the Symbol | uels (character), dimension , rename=FALSE | NULL |
- Note
- Symbols should be valid in order to use these methods.
-
when
dimension
argument is optional, the method is applied to all dimensions
Some of these methods are also available as Container methods as shown in the following table. Container methods internally call the corresponding Symbol methods.
Method | Description | Arguments/Defaults | Returns |
---|---|---|---|
getUELs | returns the UELs used in the Container | symbols=NULL (character), ignoreUnused = FALSE | character vector |
removeUELs | removes uels from all symbols the Container | uels=NULL (character) | NULL |
renameUELs | renames uels in the Container | uels (named character), allowMerge=FALSE (logical). If allowMerge = TRUE , the underlying integer mapping of a factor is allowed to change to offer additional data flexibility | NULL |
- getUELs Examples
- addUELs Examples
In this example we have added three new (unused) UELs: ham
, and
, cheese
. These three UELs will now appear in the GAMS universe set (accessible with m$getUELs()
). The addition of unused UELs does not impact the validity of the symbols (i.e., unused UELs will not trigger domain violations).
- removeUELs Examples
If a user removes a UEL that appears in data, that data will be lost perminately. The domain label will be transformed into an NA as seen in this example:
- Attention
- A container cannot be written if there are NA entries in any of the domain columns (in any symbol). An error is thrown if there are missing domain labels.
- renameUELs Examples
renameUELs
is a method of all GAMSSymbol
classes as well as theContainer
class. This method allows the user to rename UELs in a symbol dimension(s), over several symbols, or over the entire container. This method is handy when attempting to harmonize labeling schemes between data structures that originated from different sources. For example:
results in the following records:
However, two different data sources were used to generate the parameters a
and b
– one data source used the uppercase postal abbreviation of the state name and the other source used a lowercase full state name as the uniqe identifier. With the following syntax the user can harmonize to a mixed case postal code labeling scheme (without losing any of the original UEL ordering).
This results in the following records and the universe set:
- reorderUELs Examples
reorderUELs
is a method of all GAMS symbol classes. This method allows the user to reorder UELs of a specific symbol dimension. reorderUELs
will not add/remove any UELs. For example:
But perhaps we want to reorder the UELs i1
, i2
, i3
to i3
, i2
, i1
.
- Note
- This example does not change the indexing scheme of the data frame. It only changes the underlying integer numbering scheme for the factor levels.
We can see this by looking at thelevels
:
When reorderUELs()
is used without the uels
argument, the UELs are rearranged based on the records order as illustrated in the following example.
Moreover, if there are unused UELs, they are moved to the end as shown below. Here, i4
is the unused UELs that gets moved to the end after using reorderUELs
.
- setUELs Examples
setUELs
is a method of all GAMS symbol classes. This method allows the user to create new UELs, rename UELs, and reorder UELs all in one method. For example:
A user could accomplish a UEL reorder operation with setUELs
:
A user could accomplish a UEL reorder + add UELs operation with setUELs
:
A user could accomplish a UEL reorder + add + rename with setUELs
:
- Note
- This example does not change the indexing scheme of the data frame, but the
rename=TRUE
flag means that the records will get updated as if arenameUELs
call had been made.
If a user wanted to set new UELs on top of this data, without renaming, they would need to be careful to include the current UELs in the UELs being set. It is possible to lose these labels if they are not included (which will prevent the data from being written to GDX).
Removing Symbols
Removing symbols from a Container is easy when using the removeSymbols
container method; this method accepts either a string
or a list
of string
.
Reordering Symbols
In order to write the contents of the Container, it is required that the symbols are sorted such that, for example, a Set used as a domain of another symbol appears before that symbol. The Container will try to establish a valid ordering when writing the data. This type of situation could be encountered if the user is adding and removing many symbols (and perhaps rewriting symbols with the same name). Users should attempt to only add symbols to a Container
once, and care must be taken when naming. The method reorderSymbols
attempts to fix symbol ordering problems. The following example shows how this can occur:
- Example Symbol reordering
Since the link to i
is broken, Set j
is now invalid. The user has to manually set the domain again.
Now even though j
is valid, the symbols are out of order. The order can be fixed as follows.
Domain Violations
Domain violations occur when a symbol uses other Sets as domain(s) – and is thus of domain type regular, see Symbol Domain – and uses a domain entry in its records that is not present in the corresponding referenced domain set. Such a domain violation will lead to a GDX error when writing the data.
For example, the symbol j
in the following example contains domain violations because j
is defined over domain set i
and the records entry "grayslake" is not present in i
.
Trying to write this container to a GDX file will fail. To ask for domain violations, call the method Symbol$getDomainViolations()
. It returns a list of DomainViolation
objects with respect to each dimension of the symbol. This list can then be used to resolve the domain violations.
The GAMS Transfer R feature of domain forwarding offers an automatic expansion of the domain set with the violated entries in order to eliminate domain violations.
- Note
- Checking for domain violations is not a part of Symbol$isValid() for performance reasons.
-
The method for automatically resolving the domain violations can be convenient, but it effectively disables domain checking, which is a valuable tool for error detection. We encourage to use domain forwarding as rarely as possible. The same holds for using
relaxed
domain informaiton whenregular
domain information would be possible.
GAMS Special Values
The GAMS system contains five special values: UNDEF
(undefined), NA
(not available), EPS
(epsilon), +INF
(positive infinity), -INF
(negative infinity). These special values must be mapped to their R equivalents. GAMS Transfer R follows the following convention to generate the 1:1
mapping:
+INF
is mapped toInf
-INF
is mapped to-Inf
EPS
is mapped to-0.0
(mathematically identical to zero)NA
is mapped to aNA
UNDEF
is mapped toNaN
GAMS Transfer R syntax is designed to quickly get data into a form that is usable in further analyses or visualization. The user does not need to remember these constants as they are provided within the class SpecialValues
as SpecialValues$POSINF
, SpecialValues$NEGINF
, SpecialValues$EPS
, SpecialValues[["NA"]]
, and SpecialValues$UNDEF
. Some examples are shown below.
The following data frame for x
would look like:
The user can now easily test for specific special values in the value
column of the DataFrame (returns a logical vector):
- Note
- The syntax SpecialValues$NA is not allowed in R. Therefore, to access NA, one has to use
SpecialValues[["NA"]]
. As shown in the example above, double bracket syntax works for other special values too.
Standard Data Formats
This section is meant to introduce the standard format that GAMS Transfer R expects for symbol records. It has already been mentioned that we store data as a data frame, but there is an assumed structure to the column headings and column types that will be important to understand. GAMS Transfer R includes convenience functions in order to ease the burden of converting data from a user-centric format to one that is understood by GAMS Transfer R. However, advanced users will want to convert their data first and add it directly to the Container.
- Set Records Standard Format
- All set records (including singleton sets) are stored as a data frame with
n
orn+1
number of columns, wheren
is the dimensionality of the symbol. The firstn
columns include the domain elements while the last column, if present, includes the set element text. Records are organized such that there is one record per row.
The names of the domain columns (domain labels) are unique. If the domain labels are non-unique, they are converted to follow a pattern of <user_domain_label>_<index_position>
by domainLabels
setter. If the records are passed in a non-data frame format (vector, matrix etc.), domain labels follow a pattern of <domain_name>_<index_position>
. A symbol dimension that is referenced to the universe is labeled uni
. The explanatory text column is called element_text
and must take the last position in the data frame.
All domain columns must be factors
and the element_text
column must be a string
type.
Some examples:
- Parameter Records Standard Format
- All parameter records (including scalars) are stored as a data frame with
n
orn + 1
number of columns, wheren
is the dimensionality of the symbol. The firstn
columns include the domain elements while the last column, if present, includes the numerical value of the records. Records are organized such that there is one record per row. Scalar parameters have zero dimension, therefore they only have one column and one row. In cases where thevalue
columns is not present for a parameter, it is assumed that the value is the default parameter value (i.e., 0). Scalar parameters with an empty data frame as records is assumed to contain the default value of 0.
The names of the domain columns (domain labels) are unique. If the domain labels are non-unique, they are converted to follow a pattern of <user_domain_label>_<index_position>
by domainLabels
setter. If the records are passed in a non-data frame format (vector, matrix etc.), domain labels follow a pattern of <domain_name>_<index_position>
. A symbol dimension that is referenced to the universe is labeled uni_<index_position>
. The value column is called value
and must take the last position in the data frame.
All domain columns must be factors
and the value
column must be a numeric
type. GAMS Transfer R requires that all the factor levels are of type string
.
Some examples:
- Variable/Equation Records Standard Format
Variables and equations share the same standard data format. All records (including scalar variables/equations) are stored as a data frame with n
to n
+ 5 number of columns, where n
is the dimensionality of the symbol. The first n
columns include the domain elements while the remaining columns include the numerical values for different attributes of the records. Records are organized such that there is one record per row. Scalar variables/equations have zero dimension, therefore they have one row. In cases where the records data frame has missing attribute columns, it is assumed that the column contains the default value. Similarly, if the records data frame for a scalar is empty, it is assumed that all the attribute values are at their default. Default values for variables and equations depend on their type.
The names of the domain columns (domain labels) are unique. If the domain labels are non-unique, they are converted to follow a pattern of <user_domain_label>_<index_position>
by domainLabels
setter. If the records are passed in a non-data frame format (vector, matrix etc.), domain labels follow a pattern of <domain_name>_<index_position>
. A symbol dimension that is referenced to the universe is labeled uni_<index_position>
. The attribute columns are called level
, marginal
, lower
, upper
, and scale
. These attribute columns must appear in this order. Attributes that are not supplied by the user will be assigned the default GAMS values for that variable/equation type. It is possible to not pass any attributes, GAMS Transfer R would then simply assign default values to all attributes.
All domain columns must be factors
and the attribute columns must be a numeric
type. GAMS Transfer R requires that all the factor levels are of type string
.
Some examples:
Generate Records
Container symbol records in standard format can also be generated using the convenience method generateRecords()
. This method generates records with the cartesian product of domain all sets. If the argument density
is less than 1, randomly selected records are removed. For symbols that are not scalar, using this method requires that the symbol domain type is "regular" (i.e., <symbol_name>$domainType = "regular"
). A few examples using the method generateRecords()
for each type of Container symbol are provided below.
Set
- Example #1 Create a large (dense) 4D set
Generating the initial data.frame
could be difficult for Set
symbols that have a large number of records and a small number of UELs. These higher dimensional symbols will benefit from the generateRecords convenience method.
- Example #2 Create a large (sparse) 4D set
It is also possible to generate a sparse set (randomly selected rows are removed from the dense dataframe) with the density
argument to generateRecords
.
- Example #3 Create a large 4D set with 1 sparse dimension
Parameter
- Example #1 Create a large (dense) 4D Parameter
Generating the initial data.frame
could be difficult for Parameter
symbols that have a large number of records and a small number of UELs. These higher dimensional symbols will benefit from the generateRecords
convenience method.
- Note
- In Example #1 a large 4D parameter was generated. by default, the value of these records are randomly drawn numbers from the interval
[0,1]
(uniform distribution).
- Example #2 - Create a large (sparse) 4D parameter with normally distributed values
- Note
- The custom function passed to the argument
func
must expose asize
argument. It might be tedious to know the exact number of the records that will be generated, especially if a fractional density is specified; therefore, thegenerateRecords
method will pass in the correct size automatically.
- Example #3 - Create a large 4D parameter with a random number seed
- Note
- The
seed
is anint
that will set the random number generator state (enables reproducible sequences of random numbers).
Variable and Equation
Generating records for the symbol types Variable
and Equation
is similar to that of previously shown examples of parameters and sets. However, since there are more than one attributes to variables and equations, there are a few differences. By default, the random sampling is done is only for the level
attribute with default values being passed to the other attributes. To randomly generate other attributes, one can use the custom func
argument. This is shown in the following example.
- Example #1 Create a large (sparse) 4D variable and Equation
Alias
The method generateRecords
for an alias simply calls the corresponding method for its referenced set.
- Example #1 Create a large (dense) 4D set from an Alias
Data Exchange with GDX
Up until now, we have been focused on using GAMS Transfer R to create symbols in an empty Container using the symbol constructors (or their corresponding container methods). These tools will enable users to ingest data from many different formats and add them to a Container
. However, it is also possible to read in symbol data directly from GDX files using the read
container method. In the following sections, we will discuss this method in detail as well as the write
method, which allows users to write out to new GDX files.
Reading from GDX
There are two main ways to read in GDX based data.
- Pass the file path directly to the Container constructor (will read all symbols and records)
- Pass the file path directly to the
read
method (default read all symbols, but can read partial files)
The first option here is provided for convenience and will, internally, call the read
method. For the following examples, we leverage the GDX output generated from the trnsport.gms model file.
- Example (reading full data into a Container using the constructor)
A user could also read in data with the read method as shown in the following example.
- Example (reading full data into a Container with
read
method)
It is also possible to read in a partial GDX file with the read method, as shown in the following example:
This syntax assumes that the user will always want to read in both the metadata as well as the actual data records, but it is possible to skip the reading of the records by passing the argument records=FALSE
.
- Attention
- The
read
method attempts to preserve the symbol domain type from the source but if domain sets are not part of the read operation there is no choice but to default to a "relaxed"domainType
. This can be seen in the last example where we only read in the variablex
and not the domain sets (i
andj
) that the variable is defined over. All the data will be available to the user, but domain checking is no longer possible. The symbolx
will remain with "relaxed" domain type even if the user were to read in setsi
andj
in a secondread
call.
Writing to GDX
A user can write data to a GDX file by simply passing a file path (as a string). The write
method will then create the GDX and write all data in the Container
.
- Note
- It is not possible to write the Container when any of its symbols are invalid. If any symbols are invalid an error will be raised and the user will need to inspect the problematic symbols (perhaps using a combination of the
listSymbols(isValid=FALSE)
andisValid(verbose=TRUE)
methods).
- Example
- Example (write a compressed GDX file)
Advanced users might want to specify an order to their UELs (i.e., the universe set); recall that the UEL ordering follows that dictated by the data. As a convenience, it is possible to prepend the list of UELs with a user specified order using the uelPriority
argument.
- Example (change the order of the UEL)
The original UEL order for this GDX file would have been c("a", "b", "c")
, but since this example reorders the UELs with uelPriority
, the positions of b
and c
have been swapped. This can be verified with the gdxdump utility (using the uelTable
argument):
gdxdump foo.gdx ueltable=foo Set foo / 'a' , 'c' , 'b' /; $onEmpty Set i(*) / 'a', 'c', 'b' /; $offEmpty
Data Exchange between Containers
GAMS Transfer R allows data exchange between two Containers with the help of read and copy methods.
Data exchange with read
Similar to reading from a GDX file, a Container can read from another Container object. Following examples demonstrate this with the help of the GDX output generated from trnsport.gms model file.
- Example (reading data from Container)
- Example (reading data when symbol with the same name already exists)
The container read method does not allow reading from another source (Container, or a GDX file) when a symbol with the same name already exists. The existing symbol must be removed or renamed.
Data exchange with copy
Symbol copy
method provides an alternative way to exchange data between Containers. Following examples demonstrate this starting from a Container containing data from GDX output generated from trnsport.gms model file.
- Example (copy symbol from one container to another)
- > library(gamstransfer)> c = Container$new("trnsport.gdx")> c$listSymbols()[1] "i" "j" "a" "b" "d" "f" "c" "x"[9] "z" "cost" "supply" "demand"> m = Container$new()> c["f"]$copy(m)> m$listSymbols()[1] "f"
The above example copies symbol f
from Container c
to Container m
. If one copies a symbol with domain that does not exist in the destination Container, domain is relaxed as shown in the following example.
- Example (copy symbol to another container without domain symbols)
- > library(gamstransfer)> c = Container$new("trnsport.gdx")> c$listSymbols()[1] "i" "j" "a" "b" "d" "f" "c" "x"[9] "z" "cost" "supply" "demand"m = Container$new()> c["d"]$copy(m)> m$listSymbols()[1] "d"> m["d"]$domain[1] "i" "j"> m["d"]$domainType[1] "relaxed"
- Example (copy symbol to another container with overwrite)
- > library(gamstransfer)> c = Container$new()> i = Set$new(c, "i", records=c("i1","i2"))> i$recordsuni1 i12 i2> m = Container$new()> i = Set$new(m, "i", records= c("i3","i4"))> i$recordsuni1 i32 i4# the following command throws an error> c["i"]$copy(m)Error in private$.copy(destination, overwrite) :Symbol i already exists in `destination`> c["i"]$copy(m, overwrite = TRUE)> m["i"]$recordsuni1 i12 i2
- Example (bulk copy operation via Container
copy
method) - A bulk operation is also possible via Container
copy
method as shown in the following example.> library(gamstransfer)> c = Container$new("trnsport.gdx")> c$listSymbols()[1] "i" "j" "a" "b" "d" "f" "c" "x"[9] "z" "cost" "supply" "demand"> m = Container$new()> c$copy(m) # copy all symbols> c$listSymbols()[1] "i" "j" "a" "b" "d" "f" "c" "x"[9] "z" "cost" "supply" "demand"> m = Container$new()> c$copy(m, symbols=c("a","b","d")) # copy a subset of symbols> m$listSymbols()[1] "a" "b" "d"> c$copy(m, symbols="a", overwrite = TRUE) # copy symbols with overwrite> m$listSymbols()[1] "a" "b" "d"