I have a model object described as a named list of vector and matrix parameters. Two basic operations with this class of objects are the loading and storing from/to a numeric vector, based on a mapping between the elements of each parameter vector or matrix and the indices in the vector. Here is a simplified example:
LoadModelFromVector <- function(vecParams) {
model <- list(
A = diag(5), # a diagonal square matrix
B = matrix(0, 5, 5) # un upper triangular square matrix
)
attr(model, "p") <- 15
diag(model$A) <- vecParams[1:5]
model$B[upper.tri[model$B]] <- vecParams[5 + (1:(5*(5-1)/2)))]
model
}
StoreModelToVector <- function(model) {
vecParams <- double(length = attr(model, "p"))
vecParams[1:5] <- diag(model$A)
vecParams[5 + (1:(5*(5-1)/2)))] <- model$B[upper.tri[model$B]]
vecParams
}
I don't like the above example because it replicates the mapping in two places in the code. Instead, I would like to have this mapping in one place. I thought that this could be elegantly done using an abstraction of the assignment operator <-
:
LoadStoreModel <- function(vecParams, model = NULL) {
if(is.null(model)) {
model <- list(
A = diag(5), # a diagonal square matrix
B = matrix(0, 5, 5) # un upper triangular square matrix
)
`%op%` <- `<-` # WORKS FINE :-)
mode <- "load"
} else {
vecParams <- double(length = attr(model, "p"))
`%op%` <- `->` # GENERATES "Error: object '->' not found" :-(
mode <- "store"
}
diag(model$A) %op% vecParams[1:5]
model$B[upper.tri[model$B]] %op% vecParams[5 + (1:(5*(5-1)/2)))]
if(mode == "load") {
model
} else {
vecParams
}
}
LoadModelFromVector(vecParams) {LoadStoreModel(vecParams)}
StoreModelToVector(model) {LoadStoreModel(NULL, model)}
The above code generates the error "Error: object '->' not found". Both operators, '->' and '<-', are documented in the R help page ?assignOps
from the package base.