The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

gdxtools

gdxtools reads and writes GDX files (the GAMS database exchange format) from R, exposing parameters, sets, variables and equations as plain data.frames with domain columns + a value column. From v1.0.0 onward the package is backed by gamstransfer, the GDX I/O package maintained by GAMS Software GmbH. No compiled code ships with gdxtools.

Installation

if (!requireNamespace("remotes")) install.packages("remotes")
remotes::install_github("lolow/gdxtools")

gamstransfer (CRAN) is the only required dependency. A working GAMS installation is needed only if you call gams() to run a .gms file.

Reading a GDX

library(gdxtools)

mygdx <- gdx("results.gdx")

print(mygdx)                    # <results.gdx, 8 symbols>
print(mygdx$parameters$name)    # parameters available
all_items(mygdx)                # lists of names by symbol type

# Parameter — returns a data.frame with domain columns + value
travel_cost <- mygdx["travel_cost"]

# Variable / equation fields: "l" (level, default), "m" (marginal),
# "lo" (lower bound), "up" (upper bound)
lo_travel_time     <- mygdx["travel_time",     field = "lo"]
m_time_constraint  <- mygdx["time_constraint", field = "m"]

# Extract the same item from several GDX files
allparam <- batch_extract("myparam", files = c("test1.gdx", "test2.gdx"))

Writing a GDX

# Parameters
param1 <- data.frame(x = c("1","2","4","8"), value = 1:4)
attributes(param1) <- c(attributes(param1), gams = "definition of parameter 1")
param2 <- data.frame(a = c("london","paris","tahiti"), value = c(50, 0.2, 1e-2))
write.gdx("test.gdx", params = list(param1 = param1, param2 = param2))

# Sets — pass each one as a data.frame; column names become its dimensions
myset1 <- data.frame(a = c("london","paris","tahiti"))
myset2 <- data.frame(a = c("london","paris","tahiti"),
                     b = c("tahiti","tahiti","paris"))
write.gdx("test1.gdx", sets = list(city = myset1, road = myset2))

# Variables — give level / lower / upper as separate named lists; missing
# entries fall back to free-var defaults (level 0, lower -Inf, upper +Inf)
var_l  <- data.frame(a = c("london","paris","tahiti"), value = 0.2)
var_lo <- data.frame(a = c("london","paris","tahiti"), value = 1e-2)
var_up <- data.frame(a = c("london","paris","tahiti"), value = 50)
write.gdx("test2.gdx",
          vars_l  = list(travel_time = var_l),
          vars_lo = list(travel_time = var_lo),
          vars_up = list(travel_time = var_up))

# Compressed output
write.gdx("test.gdx", params = list(param1 = param1), compress = TRUE)

# write2.gdx — alias of write.gdx for params + sets only (kept for
# backward compatibility; both use the same fast path)
write2.gdx("test.gdx", params = list(param1 = param1, param2 = param2))

Policies for NA values and duplicate keys

write.gdx() exposes two policy arguments that default to the legacy v0.7 semantics so existing code keeps producing bit-identical output. Opt in when you want the alternate behaviour:

# NA / NaN values in parameter `value` columns
write.gdx("out.gdx", params = list(p = p), na = "drop")   # default: silently drop
write.gdx("out.gdx", params = list(p = p), na = "keep")   # preserve as GAMS NA
write.gdx("out.gdx", params = list(p = p), na = "error")  # stop on any NA

# Duplicate index keys
write.gdx("out.gdx", params = list(p = p), dup = "first")  # default: keep first
write.gdx("out.gdx", params = list(p = p), dup = "last")   # keep last (GAMS-process semantic)
write.gdx("out.gdx", params = list(p = p), dup = "error")  # stop on duplicates

A warning fires when rows are actually dropped so the count is always audible.

Migrating from 0.7.x

0.7 call 1.0 equivalent
write.gdx(..., removeLST = FALSE, usetempdir = FALSE) arguments accepted but ignored (no .gms/.lst)
write.gdx(..., digits = 16) accepted but ignored (full double precision)
rgdx, wgdx, gdxInfo, rgdx.param, rgdx.set, rgdx.scalar (low-level gdxrrw) removed — use gamstransfer::Container directly
igdx(), gams() kept as thin shims (PATH-based GAMS discovery + system2 runner)

A sparse parameter no longer densifies on read: only entries actually stored in the GDX come back. Variables and equations are unaffected.

See NEWS.md for the complete list of behaviour changes and bug fixes in 1.0.0.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.