#' An S4 class to represent model input
#' @name class-modInp
#'
#' @description
#' `modInp` class is used to store interpolated date for the model input parameters.
#' It includes all the model sets, mappings, and parameters, interpolated to the
#' scenario's calendar and horizon. The class is automatically created during the
#' interpolation step and is not intended to be created by users.
#'
#' @slot set `r get_slot_info("modInp", "set")`
#' @slot parameters `r get_slot_info("modInp", "parameters")`
#' @slot gams.equation `r get_slot_info("modInp", "gams.equation")`
#' @slot costs.equation `r get_slot_info("modInp", "costs.equation")`
#' @slot misc `r get_slot_info("modInp", "misc")`
#'
#' @include class-parameter.R
#'
setClass(
"modInp",
representation(
set = "list", # rename to dimSets
parameters = "list", #
# modelVersion = "character", # !!! in use ???
# solver = "character", # !!! in use ???
gams.equation = "list", # add_constraints?
costs.equation = "character", # list? add_to_objective?
misc = "list"
),
prototype(
set = list(), # !!! rename to `dimSets`???
parameters = list(),
# modelVersion = "",
# solver = "",
gams.equation = list(),
costs.equation = character(),
misc = list()
)
)
#' Initialization of `modInp` class.
#'
#' @details
#' This is an internal method, it is called during creation of `scenario` objects, and it is not intended to run by users.
#' Initialization of `modInp` adds empty structures of the model sets, mappings, and parameters to the `modInp@parameters` slot. The `@defVal` and `@interpolation` are filled with default values from internal `.modInp` list object (edit `modInp.yml` and rebuild to modify). The `@data` slot is empty (added on the interpolation step).
#'
#' @param modInp an uninitialized (created by "new", empty) model input class object.
#' @noRd
setMethod("initialize", "modInp", function(.Object) {
# browser()
# x <- .Object@parameters
x <- list()
# .dimSets <- c("horizon", .dimSets) |> unique() #!!! test
# x[["horizon"]] <- newSet("horizon")
ob <- .modInp
for (i in 1:length(ob)) {
nm <- ob[[i]]$name
# if (nm == "DEBUG") browser() # DEBUG
# if (nm == "pTechRet") browser() # DEBUG
if (ob[[i]]$type == "set") {
# browser()
x[[nm]] <- newSet(nm)
} else if (ob[[i]]$type == "map") {
x[[nm]] <- newParameter(
nm,
ob[[i]]$dimSets,
type = ob[[i]]$type
)
} else {
# if (nm == "pStorageCout") browser()
x[[nm]] <- newParameter(
nm,
ob[[i]]$dimSets,
type = ob[[i]]$type,
defVal = ob[[i]]$defVal,
interpolation = ob[[i]]$interpolation,
colName = ob[[i]]$colName,
cls = ob[[i]]$class
)
}
}
# browser()
.Object@parameters <- x
return(.Object)
})
# ============================================================================ #
# Internal functions ####
# ============================================================================ #
.get_default_values <- function(modInp, name, drop.unused.values) {
# Returns data.frame with default values of parameters on
# expanded grid of all (or used only, like horizon-mid-period)
# values of the parameter dimension (e.g. sets)
# name - "character", name of the parameter
# drop_duplicates <- function(x) x[!duplicated(x), , drop = FALSE]
# if (name == "pTechShare") browser() # DEBUG
drop_duplicates <- function(x) filter(x, !duplicated(x))
sets0 <- modInp@parameters[[name]]@dimSets
sets <- NULL
for (i in sets0) {
j <- i
if (any(i == c("src", "dst"))) j <- "region"
tmp <- .get_data_slot(modInp@parameters[[j]])
colnames(tmp) <- i
if (nrow(tmp) == 0) {
return(NULL)
}
if (drop.unused.values) {
if (i == "slice" && any(colnames(sets) == "comm")) {
tmp <- merge(.get_data_slot(modInp@parameters$mCommSlice), tmp)
}
if (i == "comm" && any(colnames(sets) == "sup")) {
tmp <- merge(.get_data_slot(modInp@parameters$mSupComm), tmp)
}
if (i == "region" && any(colnames(sets) == "sup") &&
all(sets0 != "year")) {
tmp <- merge(drop_duplicates(
.get_data_slot(modInp@parameters$mSupSpan)[, c("sup", "region")]
), tmp)
}
if (i == "year" && any(colnames(sets) == "sup") &&
any(colnames(sets) == "region")) {
tmp <- merge(.get_data_slot(modInp@parameters$mSupSpan), tmp)
}
if (i == "year") {
tmp <- merge(.get_data_slot(modInp@parameters$mMidMilestone), tmp)
}
if (i == "year" && any(colnames(sets) == "tech")) {
tmp <- merge(.get_data_slot(modInp@parameters$mTechSpan), tmp)
}
if (i == "region" && any(colnames(sets) == "tech") &&
all(sets0 != "year")) {
tmp <- merge(drop_duplicates(
.get_data_slot(modInp@parameters$mTechSpan)[, c("tech", "region")]
), tmp)
}
if (i == "comm" && any(colnames(sets) == "tech")) {
tmp <- merge(rbind(
.get_data_slot(modInp@parameters$mTechInpComm),
.get_data_slot(modInp@parameters$mTechOutComm)
), tmp)
}
if (i == "slice" && any(colnames(sets) == "tech")) {
tmp <- merge0(.get_data_slot(modInp@parameters$mTechSlice), tmp)
}
if (i == "src") {
aa <- .get_data_slot(modInp@parameters$mTradeSrc)
colnames(aa)[2] <- "src"
tmp <- merge(aa, tmp)
}
if (i == "dst") {
aa <- .get_data_slot(modInp@parameters$mTradeDst)
colnames(aa)[2] <- "dst"
tmp <- merge(aa, tmp)
}
if (i == "comm" && any(colnames(sets) == "trade")) {
tmp <- merge(.get_data_slot(modInp@parameters$mTradeComm), tmp)
}
}
if (is.null(sets)) {
sets <- tmp
} else {
# browser()
sets <- merge0(sets, tmp)
}
}
if (modInp@parameters[[name]]@type == "numpar" &&
(is.null(sets) || nrow(sets) != 0)) {
sets$value <- modInp@parameters[[name]]@defVal
if (!is.data.frame(sets)) sets <- as.data.frame(sets)
}
if (modInp@parameters[[name]]@type == "bounds" &&
(is.null(sets) || nrow(sets) != 0)) {
sets$type <- "lo"
sets$value <- modInp@parameters[[name]]@defVal[1]
sets2 <- sets
sets2$type <- "up"
sets2$value <- modInp@parameters[[name]]@defVal[2]
sets <- rbind(sets, sets2)
}
sets
}
.add_dropped_zeros <- function(modInp, name, drop.unused.values = TRUE,
use.dplyr = FALSE) {
# Returns data.frame filled the parameter ("name") data with added, previous dropped zeros (if any)
# rare use - currently reserved for "fix to scenario" routines (and some excessive/double-checking use)
# if (name == "pTechShare") browser() # DEBUG
tmp <- .get_default_values(modInp, name, drop.unused.values)
# tmp$value <- 0
dtt <- .get_data_slot(modInp@parameters[[name]])
# browser()
if (!is.null(tmp)) {
if (use.dplyr) {
cols <- colnames(dtt)
# gg <- suppressMessages(dplyr::anti_join(tmp, dtt[, cols],
# by = cols[cols != "value"]))
gg <- suppressMessages(dplyr::anti_join(tmp, dtt, by = cols[cols != "value"]))
gg <- suppressMessages(dplyr::left_join(dtt, gg))
return(gg)
} else {
if (ncol(dtt) == ncol(tmp)) {
gg <- rbind(dtt, tmp)
} else {
# gg <- rbind(dtt, unique(tmp[, colnames(dtt), drop = FALSE]))
if (anyDuplicated(colnames(dtt))) browser() # mappings check
gg <- rbind(dtt, unique(select(tmp, all_of(colnames(dtt)))))
}
if (ncol(gg) == 1) {
return(dtt)
}
}
} else {
gg <- dtt
}
# gg[!duplicated(gg[, colnames(gg) != "value"]), , drop = FALSE]
ii <- gg |> select(-value) |> duplicated()
filter(gg, !ii)
}
#### end ===================================================================####
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.