Learn R Programming

ForecastFramework (version 0.10.3)

AbstractIncidenceMatrix: AbstractIncidenceMatrix

Description

An abstract class for storing an actual matrix. It has an actual matrix of data mat, which it is responsible for storing. For creating matrices with particular metadata, consider extending IncidenceMatrix instead of this class. Extend this class if you have data which can be thought of as a matrix, but that is not its true form. ## TODO: Include an example of this.

Arguments

Fields

cellData

A list of metadata associated with the cells of the data.

cnames

The names of columns in the data.

colData

A list of metadata associated with the columns of the data.

mat

This is the matrix. For extensibility, it cannot be written to directly and must be modified through methods.

metaData

Any data not part of the main data structure.

ncol

The number of columns in the data.

nrow

The number of rows in the data

rnames

The names of rows in the data.

rowData

A list of metadata associated with the columns of the data.

Methods

addColumns(columns,mutate=TRUE)

This method must be extended. This function adds empty columns to the right side of the data.

Value

If mutate=FALSE, a clone of this object will run the method and be returned. Otherwise, there is no return.

addRows(rows,mutate=TRUE)

This method must be extended. This function adds empty rows to the data.

Value

If mutate=FALSE, a clone of this object will run the method and be returned. Otherwise, there is no return.

debug(string)

A function for debugging the methods of this class. It calls the browser command. In order for methods to opt into to debugging, they need to implement the following code at the beginning: if(<method_name> %in% private$.debug){browser()}. This method exists, because the debugger is not always intuitive when it comes to debugging R6 methods.

diff(lag=1,mutate=TRUE)

This method must be extended. This function replaces the matrix value at column i with the difference. between the values at columns i and (i-lag).

Value

If mutate=FALSE, a clone of this object will run the method and be returned. Otherwise, there is no return.

head(k,direction,mutate=TRUE...)

This method must be extended. Select the first k slices of the data in dimension direction.

Value

If mutate=FALSE, a clone of this object will run the method and be returned. Otherwise, there is no return.

initialize(...)

This function should be extended. Create a new instance of this class.

lag(indices,mutate=TRUE,na.rm=FALSE)

This method must be extended. This function replaces the current matrix with a new matrix with one column for every column, and a row for every row/index combination. The column corresponding to the row and index will have the value of the original matrix in the same row, but index columns previous. This shift will introduce NAs where it passes off the end of the matrix.

Value

If mutate=FALSE, a clone of this object will run the method and be returned. Otherwise, there is no return.

mutate(rows,cols,data)

This method must be extended. This function is a way to modify the data as though it were a matrix.

scale(f,mutate=TRUE)

This method must be extended. This function rescales each element of our object according to f

Value

If mutate=FALSE, a clone of this object will run the method and be returned. Otherwise, there is no return.

subset(rows,cols,mutate=TRUE...)

This method must be extended. Select the data corresponding to the rows rows and the columns columns. rows and columns can be either numeric or named indices.

Value

If mutate=FALSE, a clone of this object will run the method and be returned. Otherwise, there is no return.

tail(k,direction,mutate=TRUE...)

This method must be extended. Select the last k slices of the data in dimension direction.

Value

If mutate=FALSE, a clone of this object will run the method and be returned. Otherwise, there is no return.

undebug(string)

A function for ceasing to debug methods. Normally a method will call the browser command every time it is run. This command will stop it from doing so.

See Also

Inherits from : MatrixData

Is inherited by : IncidenceMatrix

Examples

Run this code
# NOT RUN {
IncidenceMatrix <- R6Class(
  classname = "IncidenceMatrix",
  inherit = AbstractIncidenceMatrix,
  public = list(
    initialize = function(
      data=matrix(),
      metaData=list(),
      rowData=list(),
      colData=list()
    ){
      if(Reduce(
        '&&',
        c('MatrixData','DataContainer','Generic','R6') %in% class(data))
      ){
        private$.mat <- data$mat
        private$.metaData <- data$metaData
        private$.nrow <- data$nrow
        private$.ncol <- data$ncol
        private$.rnames <- data$rnames
        private$.cnames <- data$cnames
        private$.rowData <- data$rowData
        private$.colData <- data$colData
        private$.metaData <- data$metaData
        private$.cellData <- data$cellData
      }
      else{
        rtoggle = FALSE
        ctoggle = FALSE
        try({
          rnames <- dimnames(data)[[1]]
          rtoggle = TRUE
        })
        try({
          cnames <- dimnames(data)[[2]]
          ctoggle = TRUE
        })
        if(!private$checkType(name='.mat',val=data,type='private')){
          data <- as.matrix(data)
          if(rtoggle){
            rownames(data) = rnames
          }
          if(ctoggle){
            colnames(data) = cnames
          }
        }
        if(!private$checkType(name='.mat',val=data,type='private')){
          stop(paste(
            "invalid data of type",
            paste(class(data),collapse=','),
            "expected",
            paste(class(private$.mat),collapse = ',')
          ))
        }
        if(length(dim(data)) > 2){
          stop("The matrix is not intended to hold things with more than 3 dimensions.")
        }
        ndim = dim(data)
        private$.nrow = ndim[[1]]
        private$.ncol = ndim[[2]]
        private$.rnames = rownames(data)
        private$.cnames = colnames(data)
        private$.mat <- 0+data
        self$rowData <- rowData
        self$colData <- colData
        self$metaData <- metaData
      }
    },
    subset = function(rows,cols,mutate=TRUE){
      if('subset' %in% private$.debug){
        browser()
      }
      if(!mutate){
        temp = self$clone(TRUE)
        temp$subset(rows,cols,mutate=TRUE)
        return(temp)
      }
      if(missing(rows) && missing(cols)){
      }
      else if(missing(rows)){
        private$.mat = self$mat[,cols,drop=FALSE]
        if(length(private$.colData) > 0){
          private$.colData <- lapply(
            private$.colData,function(x){x[cols,drop=FALSE]}
          )
        }
      }
      else if(missing(cols)){
        private$.mat = self$mat[rows,,drop=FALSE]
        if(length(private$.rowData) > 0){
          private$.rowData <- lapply(
            private$.rowData,function(x){x[rows,drop=FALSE]}
          )
        }
      }
      else{
        private$.mat = self$mat[rows,cols,drop=FALSE]
        if(length(private$.rowData)>0){
          private$.rowData <- lapply(
            private$.rowData,function(x){x[rows,drop=FALSE]}
          )
        }
        if(length(private$.colData)>0){
          private$.colData <- lapply(
            private$.colData,function(x){x[cols,drop=FALSE]}
          )
        }
      }
      private$.nrow = nrow(private$.mat)
      private$.rnames = rownames(private$.mat)
      private$.ncol = ncol(private$.mat)
      private$.cnames = colnames(private$.mat)
    },
    head = function(k,direction=2){
      if('head' %in% private$.debug){
        browser()
      }
      if(k>dim(private$.mat)[[direction]]){
        stop("The size of the head is too large.")
      }
      indices = 1:k
      if(direction==1){
        private$.mat = self$mat[indices,,drop=FALSE]
        if(length(private$.rowData)>0){
          for(i in 1:length(private$.rowData)){
            private$.rowData[[i]] = private$.rowData[[i]][indices,drop=FALSE]
          }
        }
      }
      else if(direction==2){
        private$.mat = self$mat[,indices,drop=FALSE]
        if(length(private$.colData)>0){
          for(i in 1:length(private$.colData)){
            private$.colData[[i]] = private$.colData[[i]][indices,drop=FALSE]
          }
        }
      }
      else{
        stop("This direction is not allowed.")
      }
      private$.nrow = nrow(private$.mat)
      private$.ncol = ncol(private$.mat)
      private$.cnames = colnames(private$.mat)
      private$.rnames = rownames(private$.mat)
    },
    tail = function(k,direction=2){
      if('tail' %in% private$.debug){
        browser()
      }
      if(k>dim(private$.mat)[[direction]]){
        stop("The size of the tail is too large.")
      }
      indices = (dim(self$mat)[[direction]]-k+1):dim(self$mat)[[direction]]
      if(direction==1){
        private$.mat = self$mat[indices,,drop=FALSE]
        if(length(private$.rowData)>0){
          for(i in 1:length(private$.rowData)){
            private$.rowData[[i]] = private$.rowData[[i]][indices,drop=FALSE]
          }
        }
      }
      else if(direction==2){
        private$.mat = self$mat[,indices,drop=FALSE]
        if(length(private$.colData)>0){
          for(i in 1:length(private$.colData)){
            private$.colData[[i]] = private$.colData[[i]][indices,drop=FALSE]
          }
        }
      }
      else{
        stop("This direction is not allowed.")
      }
      private$.nrow = nrow(private$.mat)
      private$.ncol = ncol(private$.mat)
      private$.cnames = colnames(private$.mat)
      private$.rnames = rownames(private$.mat)
    },
    lag = function(indices,mutate=TRUE,na.rm=FALSE){
      if('lag' %in% private$.debug){
        browser()
      }
      if(mutate==FALSE){
        tmp = self$clone(TRUE)
        tmp$lag(indices=indices,mutate=TRUE,na.rm=na.rm)
        return(tmp)
      }
      if((1+max(indices)) > self$ncol){
        stop("We cannot go further back than the start of the matrix")
      }
      numLags = length(indices)
      oldNrow = self$nrow
      if(is.null(rownames(private$.mat))){
        rownames(private$.mat) = 1:(dim(private$.mat)[[1]])
      }
      rownames = replicate(numLags,rownames(private$.mat))
      colnames = colnames(private$.mat)
      private$.mat <- 0+array(self$mat,c(dim(self$mat),numLags))
      if(numLags <= 0){
        stop("indices must be nonempty for the calculation of lags to make sense.")
      }
      for(lag in 1:numLags){
        private$.mat[,(1+indices[[lag]]):self$ncol,lag] <-
          private$.mat[,1:(self$ncol-indices[[lag]]),lag]
        if(indices[[lag]] > 0){
          private$.mat[,1:(indices[[lag]]),lag] = NA
        }
      }
      private$.mat = aperm(private$.mat,c(1,3,2))
      private$.mat = matrix(private$.mat,self$nrow*numLags,self$ncol)
      lagnames = t(replicate(self$nrow,paste('L',indices,sep='')))
      rownames(private$.mat) <-
        as.character(paste(lagnames,"R",rownames,sep=''),numLags*self$nrow)
      colnames(private$.mat) <- colnames
      private$.nrow = self$nrow * numLags
      private$.rnames = rownames(private$.mat)
      if(length(private$.rowData) > 0){
        private$.rowData <- lapply(
          private$.rowData,
          function(x){
            c(unlist(recursive=FALSE,lapply(1:numLags,function(y){x})))
          }
        )
      }
      if(na.rm==T){
        self$subset(cols=!apply(private$.mat,2,function(x){any(is.na(x))}))
      }
    },
    scale = function(f,mutate=TRUE){
      if('scale' %in% private$.debug){
        browser()
      }
      if(!mutate){
        tmp = self$clone(TRUE)
        tmp$scale(f=f,mutate=TRUE)
        return(tmp)
      }
      private$.mat[] = f(private$.mat[])
    },
    diff = function(lag = 1,mutate=TRUE){
      if('diff' %in% private$.debug){
        browser()
      }
      if(lag == 0){
        if(!is.null(private$.rnames)){
          rownames(private$.mat) =
            paste("D",lag,"R",private$.rnames,sep='')
          private$.rnames = rownames(private$.mat)
        } else {
          rownames(private$.mat) =
            paste("D",lag,"R",1:private$.nrow,sep='')
          private$.rnames = rownames(private$.mat)
        }
        return()
      }
      if(lag < 0){
        stop("Lag should be non-negative.")
      }
      if(!mutate){
        tmp = self$clone(TRUE)
        tmp$diff(lag=lag,mutate=TRUE)
        return(tmp)
      }
      private$.mat <-
        self$mat - self$lag(indices=lag,mutate=FALSE,na.rm=FALSE)$mat
      if(!is.null(private$.rnames)){
        rownames(private$.mat) =
          paste("D",lag,"R",private$.rnames,sep='')
        private$.rnames = rownames(private$.mat)
      } else {
        rownames(private$.mat) =
          paste("D",lag,"R",1:private$.nrow,sep='')
        private$.rnames = rownames(private$.mat)
      }
    },
    addColumns = function(columns){
      if('addColumns' %in% private$.debug){
        browser()
      }
      if(columns == 0){
        return()
      }
      cbind(private$.mat , matrix(NA,private$.nrow,columns)) -> private$.mat
      private$.ncol = ncol(private$.mat)
      if(!is.null(private$.cnames)){
        colnames(private$.mat) = c(private$.cnames,replicate(columns,"NA"))
        private$.cnames = colnames(private$.mat)
      }
      if(length(private$.colData) > 0){
        private$.colData <- lapply(
          private$.colData,
          function(x){
            c(x,replicate(columns,NA))
          }
        )
      }
    },
    addRows = function(rows){
      if('addRows' %in% private$.debug){
        browser()
      }
      if(rows == 0){
        return()
      }
      rbind(private$.mat , matrix(NA,rows,private$.ncol)) -> private$.mat
      private$.nrow = nrow(private$.mat)
      if(!is.null(private$.rnames)){
        rownames(private$.mat) = c(private$.rnames,replicate(rows,"NA"))
        private$.rnames = rownames(private$.mat)
      }
      if(length(private$.rowData) > 0){
        private$.rowData <- lapply(
          private$.rowData,
          function(x){
            c(x,replicate(rows,NA))
          }
        )
      }
    },
    mutate = function(rows,cols,data){
      if('mutate' %in% private$.debug){
        browser()
      }
      data = as.matrix(data)
      if(missing(rows)){
        rows = 1:private$.nrow
        if(!(is.null(private$.cnames) || is.null(colnames(data)))){
          private$.cnames[cols] = colnames(data)
          colnames(private$.mat) = private$.cnames
        }
      }
      if(missing(cols)){
        cols = 1:private$.ncol
        if(!(is.null(private$.rnames) || is.null(rownames(data)))){
          private$.rnames[rows] = rownames(data)
          rownames(private$.mat) = private$.rnames
        }
      }
      if(is.null(dim(data))){
        stop("Not yet implemented for non-matrixlike objects")
      }
      if(length(dim(data)) > 2){
        stop("There are too many dimensions in data.")
      }
      if(length(dim(data)) == 2){
        private$.mat[rows,cols] = data
      }
    }
  ),
  active = list(
    mat = function(value){
      "The matrix of data."
      if('mat' %in% private$.debug){
        browser()
      }
      if(missing(value)){
        return(private$.mat)
      }
      stop(
        "Do not write directly to the mat. Either use methods to modify the mat,
         or create a new instance."
      )
    },
    colData = function(value){
      "The metaData associated with column in the matrix"
      if('colData' %in% private$.debug){
        browser()
      }
      if(missing(value)){
        if(length(private$.colData) > 0){
          for(i in 1:length(private$.colData)){
            if(private$.ncol != length(private$.colData[[i]])){
              stop("If you alter the matrix, please also edit the column metaData.")
            }
          }
        }
        return(private$.colData)
      }
      if(class(value) != 'list'){
        stop("Column metaData should be a list of lists.")
      }
      if(length(value)>0){
        for(i in 1:length(value)){
          if(
            Reduce(
              '&&',
              class(value[[i]]) !=
                c(
                  'list',
                  'character',
                  'numeric',
                  'integer',
                  'logical',
                  'raw',
                  'complex'
                )
            )
          ){
            if(dim(as.matrix(value[[i]]))[[1]] != private$.ncol){
              stop(paste(
                'The ',
                i,
                'th element of column metaData does not have one element for',
                'each column.',
                sep=''
              ))
            }
          }
          else{
            if(length(value[[i]])!=private$.ncol){
              stop(paste(
                'The ',
                i,
                'th element of column metaData does not have one element for',
                'each column.',
                sep=''
              ))
            }
          }
        }
      }
      private$.colData <- value
      if(length(private$.colData) > 0){
        for(i in 1:length(private$.colData)){
          names(private$.colData[[i]]) <- colnames(self$mat)
        }
      }
    },
    rowData = function(value){
      "The metaData associated with rows in the matrix"
      if('rowData' %in% private$.debug){
        browser()
      }
      if(missing(value)){
        if(length(private$.rowData) > 0){
          for(i in 1:length(private$.rowData)){
            if(private$.nrow != length(private$.rowData[[i]])){
              stop("If you alter the matrix, please also edit the row metaData.")
            }
          }
        }
        return(private$.rowData)
      }
      if(class(value) != 'list'){
        stop("row metaData should be a list of lists.")
      }
      if(length(value) > 0){
        for(i in 1:length(value)){
          if(
            Reduce('&&',
              class(value[[i]]) !=
                c(
                  'list',
                  'character',
                  'numeric',
                  'integer',
                  'logical',
                  'raw',
                  'complex'
                )
            )
          ){
            if(dim(as.matrix(value[[i]]))[[1]] != private$.nrow){
              stop(paste(
                'The ',
                i,
                'th element of row metaData does not have one element for each',
                'row.',
                sep=''
              ))
            }
          }
          else{
            if(length(value[[i]])!=private$.nrow){
              stop(paste(
                'The ',
                i,
                'th element of row metaData does not have one element for each',
                'row.',
                sep=''
              ))
            }
          }
        }
      }
      private$.rowData <- value
      if(length(private$.rowData)>0){
        for(i in 1:length(value)){
          names(private$.rowData[[i]]) <- rownames(self$mat)
        }
      }
    }
  )
)
# }

Run the code above in your browser using DataLab