Skip to content
Snippets Groups Projects
lagdf.R 6.19 KiB
Newer Older
  • Learn to ignore specific revisions
  • pbac's avatar
    pbac committed
    ## Do this in a separate file to see the generated help:
    #library(devtools)
    #document()
    #load_all(as.package("../../onlineforecast"))
    
    pbac's avatar
    pbac committed
    
    
    #' Lagging by shifting the values back or fourth always returning a data.frame.
    
    pbac's avatar
    pbac committed
    #'
    
    #' This function lags (shifts) the values of the vector. A data.frame is always returned with the columns
    #' as the vectors lagged with the values in lagseq. The column names are set to "kxx", where xx are the lag of the column.
    
    pbac's avatar
    pbac committed
    #'
    #' 
    
    #' @title Lagging which returns a data.frame
    
    pbac's avatar
    pbac committed
    #' @param x The vector to be lagged.
    
    #' @param lagseq The integer(s) setting the lag steps.
    
    #' @return A data.frame.
    #' @rdname lagdf
    #' @seealso \code{\link{lagdf.data.frame}} which is run when \code{x} is a data.frame.
    
    pbac's avatar
    pbac committed
    #' @examples
    #' # The values are simply shifted
    #' # Ahead in time
    
    pbac's avatar
    pbac committed
    #' # Back in time
    
    pbac's avatar
    pbac committed
    #' # Works but returns a numric
    
    pbac's avatar
    pbac committed
    #' # Works and returns a character
    
    #' lagdf(as.character(1:10), 3)
    
    pbac's avatar
    pbac committed
    #' # Giving several lag values
    
    #' lagdf(1:10, c(1:3))
    #' lagdf(1:10, c(5,3,-1))
    
    pbac's avatar
    pbac committed
    #'
    
    pbac's avatar
    pbac committed
    #' # See also how to lag a forecast data.frame with: ?lagdf.data.frame
    
    pbac's avatar
    pbac committed
    #'
    
    pbac's avatar
    pbac committed
    #'@export
    
    
    lagdf <- function(x, lagseq){
        UseMethod("lagdf")
    
    pbac's avatar
    pbac committed
    }
    
    
    pbac's avatar
    pbac committed
    
    
    lagdf.numeric <- function(x, lagseq) {
        ## Return a data.frame
        tmp <- lapply_cbind_df(lagseq, function(lag){
            return(lagvec(x, lag))
        })
        names(tmp) <- pst("k",lagseq)
        return(tmp)
    
    pbac's avatar
    pbac committed
    }
    
    
    #' @export
    
    lagdf.factor <- function(x, lagseq) {
        lagdf.numeric(x, lagseq)
    
    pbac's avatar
    pbac committed
    }
    
    
    #' @export
    
    lagdf.character <- function(x, lagseq) {
        lagdf.numeric(x, lagseq)
    
    pbac's avatar
    pbac committed
    }
    
    #' @export
    
    lagdf.logical <- function(x, lagseq) {
        lagdf.numeric(x, lagseq)
    
    pbac's avatar
    pbac committed
    }
    
    
    #' Lagging of a data.frame
    #'
    #' This function lags the columns with the integer values specified with the argument \code{lagseq}.
    #' 
    #' @title Lagging of a data.frame
    
    #' @param x The data.frame to have columns lagged
    #' @param lagseq The sequence of lags as an integer. Alternatively, as a character "+k", "-k", "+h" or "-h", e.g. "k12" will with "+k" be lagged 12.
    #' @return A data.frame with columns that are lagged
    
    pbac's avatar
    pbac committed
    #' @examples
    
    pbac's avatar
    pbac committed
    #' # dataframe of forecasts
    #' X <- data.frame(k1=1:10, k2=1:10, k3=1:10)
    #' X
    #'
    #' # Lag all columns
    
    #' lagdf(X, 1)
    #' \dontshow{if(!all(is.na(lagdf(X, 1)[1, ]))){stop("Lag all columns didn't work")}}
    
    pbac's avatar
    pbac committed
    #'
    #' # Lag each column different steps
    
    pbac's avatar
    pbac committed
    #' # Lag each columns with its k value from the column name
    
    #'     if(any(lagdf(X, 1:3) != lagdf(X, "+k"),na.rm=TRUE)){stop("Couldn't lag +k")}
    
    pbac's avatar
    pbac committed
    #' # Also works for columns named hxx
    #' names(X) <- gsub("k", "h", names(X))
    
    pbac's avatar
    pbac committed
    #'
    
    pbac's avatar
    pbac committed
    #' # If lagseq must have length as columns in X, it doesn't know how to lag and an error is thrown
    #' try(lagdf(X, 1:2))
    #' 
    
    pbac's avatar
    pbac committed
    #' \dontshow{
    
    #' if(!class(lagdf(data.frame(k1=1:10), 2)) == "data.frame"){stop("Trying to lag data.frame with 1 column, but return is not class data.frame")}
    #' if(!all(dim(lagdf(data.frame(k1=1:10), "+k")) == c(10,1))){stop("Trying to lag data.frame with 1 column, but return is not class data.frame")}
    
    pbac's avatar
    pbac committed
    #' }
    #'
    #' @export
    
    lagdf.data.frame <- function(x, lagseq) {
    
    pbac's avatar
    pbac committed
        X <- x
        nms <- nams(X)
        if (length(lagseq) == 1) {
            if (lagseq %in% c("+k","+h")) {
                lagseq <- rep(0, length(nms))
                ## lagseq according to the k value of the columnnames
                i <- grep("^[k|h][[:digit:]]+$", nms)
                lagseq[i] <- as.integer(sapply(strsplit(nms[i], "[k|h]"), function(x){ x[length(x)] }))
            } else if (lagseq %in% c("-k","-h")) {
                lagseq <- rep(0, length(nms))
                ## lagseq according to the negative k value of the columnnames
                i <- grep("^[k|h][[:digit:]]+$", nms)
                lagseq[i] <- -as.integer(sapply(strsplit(nms[i], "[k|h]"), function(x){ x[length(x)] }))
            }
        }
        if (length(lagseq) > 1) {
            if(length(lagseq) != ncol(X)){
                stop(pst("Must have same columns as length of lagseq: data.frame has ",ncol(X)," columns and laqseq is of length ",length(lagseq)))
            }else{
                ## lagseq has length equal to the number of columns in X
                X <- as.data.frame(sapply(1:length(lagseq), function(i) {
    
    pbac's avatar
    pbac committed
                }))
                nams(X) <- nms
             }
        } else {
            ## X is a data.frame, but lag is a factor, so lag all
            lag <- lagseq
            ## If only one row in X given, then X it is a not a data.frame anymore (code above has changed it)
            if(is.vector(X)){
    
              X <- as.data.frame(lagvec(X, lag))
    
    pbac's avatar
    pbac committed
              nams(X) <- nms
            } else {
                if (lag > 0) {
                    X[(lag + 1):nrow(X), ] <- X[1:(nrow(X) - lag), ]
                    X[1:lag, ] <- NA
                } else if (lag < 0) {
                    lag <- -lag
                    X[1:(nrow(X) - lag), ] <- X[(lag + 1):nrow(X), ]
                    X[(nrow(X) - lag + 1):nrow(X), ] <- NA
                }
            }
         }
        return(X)
    }
    
    #' @export
    
    lagdf.matrix <- function(x, lagseq){
        lagdf.data.frame(x, lagseq)
    
    pbac's avatar
    pbac committed
    }
    
    ## ## Test
    ## x <- data.frame(k1=1:5,k2=6:10)
    ## ##
    
    pbac's avatar
    pbac committed
    ## source("nams.R")
    
    ## lagdf(as.matrix(x), lagseq=c(1,2))
    
    pbac's avatar
    pbac committed
    ## ##
    
    ## lagdf(x, lagseq="+k")
    ## lagdf(x, "+k")
    ## lagdf(x, "-k")
    
    pbac's avatar
    pbac committed
    
    
    ## lagdf.data.table <- function(x, nms, lagseq, per_reference = FALSE) {
    
    pbac's avatar
    pbac committed
    ##     DT <- x
    ##     if (!per_reference) {
    ##         ## Don't do it per reference
    ##         X <- DT[, ..nms]
    ##         for (i in 1:length(lagseq)) {
    ##             if (lagseq[i] > 0) {
    ##                 X[, `:=`(c(nams(X)[i]), shift(.SD, lagseq[i], NA, "lag")), .SDcols = c(nams(X)[i])]
    ##             } else if (lagseq[i] < 0) {
    ##                 X[, `:=`(c(nams(X)[i]), shift(.SD, -lagseq[i], NA, "lead")), .SDcols = c(nams(X)[i])]
    ##             }
    ##         }
    ##         return(X)
    ##     } else {
    ##         ## Here also names of the columns to be shifted should be given Do it per
    ##         ## reference
    ##         for (i in 1:length(lagseq)) {
    ##             if (lagseq[i] > 0) {
    ##                 DT[, `:=`(c(nms[i]), shift(.SD, lagseq[i], NA, "lag")), .SDcols = c(nms[i])]
    ##             } else if (lagseq[i] < 0) {
    ##                 DT[, `:=`(c(nms[i]), shift(.SD, -lagseq[i], NA, "lead")), .SDcols = c(nms[i])]
    ##             }
    ##         }
    ##         invisible(NULL)
    ##     }
    ## }