R/calculateGMRAEs.R

#' Geometric Mean Relative Absolute Error for the given data from dataset (GMRAEs)
#'
#' This function calculates and returns list of two dataframes,
#' where the first data frame contains GMRAEs for the given data, diferent horizons and methods,
#' the second one contains ranked list of the methods according to GMRAEs.
#' Also the function plots GMRAEs for different hirizons and methods.
#'
#' @aliases calculateGMRAEs
#' @param frame A data frame containing columns "actual", "forecast", "method" and "horizon".
#' @param benchmark_method Name of method called for benchmark.
#' @param sort logical. If TRUE the resulting list of GMRAEs dataframe and ranked dataframe of GMRAEs sorting by average value.
#' @return \code{calculatePB_MAEs} function calculates and returns list of two dataframes,
#' where the first data frame contains GMRAEs for the given data, diferent horizons and methods,
#' the second one contains ranked dataframe of the methods according to GMRAEs.
#' Also the function plots GMRAEs for different hirizons and methods.
#' @author Sai Van Cuong, Maixm Shcherbakov and Andrey Davydenko
#' @seealso \code{\link{calculateAvgRelMAEs}}, \code{\link{calculateGMAPEs}}, \code{\link{calculateMAD_MEAN_ratio}},
#' \code{\link{calculateMAEs}}, \code{\link{calculateMAPEs}}, \code{\link{calculateMASEs}},
#' \code{\link{calculateMdAPEs}}, \code{\link{calculateMPEs}}, \code{\link{calculateMSEs}},
#' \code{\link{calculatePB_MAEs}}, \code{\link{calculateRMSEs}}, \code{\link{calculateSMAPEs}},
#' \code{\link{calculateSMdAPEs}}.
#' @references Andrey Davydenko, Robert Fildes (2015) Volume title: \emph{Forecast Error Measures: Critical Review and Practical Recommendations}. \url{https://www.researchgate.net/publication/284947381_Forecast_Error_Measures_Critical_Review_and_Practical_Recommendations}.
#' @references Chao Chen, Jamie Twycross, Jonathan M. Garibaldi (2017) Volume title: \emph{A new accuracy measure based on bounded relative error for time series forecasting}. \url{http://journals.plos.org/plosone/article?id=10.1371/journal.pone.0174202}.
#' @references MV Shcherbakov, A Brebels, NL Shcherbakova (2013) Volume title: \emph{Information Technologies in Modern Industry, Education & Society}. \url{https://www.researchgate.net/publication/281718517_A_survey_of_forecast_error_measures}.
#' \url{http://eva.fcea.edu.uy/pluginfile.php/109034/mod_resource/content/0/2006_Hyndman_Predicc.pdf}.
#' @references Chao Chen, Jamie Twycross, Jonathan M. Garibaldi (2017) Volume title: \emph{A new accuracy measure based on bounded relative error for time series forecasting}. \url{http://journals.plos.org/plosone/article?id=10.1371/journal.pone.0174202}.
#' @references MV Shcherbakov, A Brebels, NL Shcherbakova (2013) Volume title: \emph{Information Technologies in Modern Industry, Education & Society}. \url{https://www.researchgate.net/publication/281718517_A_survey_of_forecast_error_measures}.
#' @keywords dataframe
#' @examples
#' calculateGMRAEs(frame = FORAYearForecast, benchmark_method = "NAIVE2")
#' calculateGMRAEs(frame = FORAYearForecast, benchmark_method = "NAIVE2",  sort = TRUE)
#'
#' @export
calculateGMRAEs <- function(frame, benchmark_method, sort = FALSE){
  out <-matrix(NA, nrow = length(unique(frame$method)), ncol = length(unique(frame$horizon)))
  methodlist <- list()
  horizonlist <- list()
  GMRAElist <- list()
  GMRAE <- c()
  df1 = data.frame(out)
  colnames(df1) <- paste("horizon = ", 1:length(unique(frame$horizon)), sep ="")
  rownames(df1) <- unique(frame$method)
  ranks = data.frame(out)
  colnames(ranks) <- paste("horizon = ", 1:length(unique(frame$horizon)), sep ="")
  rownames(ranks) <- unique(frame$method)
  AE <- abs(frame$actual - frame$forecast)
  df <- cbind(frame, "AE" = AE)
  bmethod = list()
  for(i in as.vector(unique(frame$series_id))){
    bmethod[[i]] <- rep(subset(df, series_id ==i & method == benchmark_method)$AE, length(unique(frame$method)))
  }
  bmethod <- Reduce(c, bmethod)
  df <- cbind(df, "bmethod" = bmethod)
  rel_error <- df$AE/df$bmethod
  df <- cbind(df, "rel_error" = rel_error)
  lnr <- log(df$rel_error)
  df <- cbind(df, "lnr" = lnr)
  df <- df[Reduce(`&`, lapply(df, function(x) !is.nan(x) & is.finite(x))),]

  for(j in as.vector(unique(df$horizon))){
    for(i in as.vector(unique(df$method))){
      df1[i, j] <- exp(mean(subset(df, method == i & horizon == j)$lnr))
    }
  }

  for (k in 1:length(unique(frame$horizon))){
    ranks[,k] <- rank(df1[, k])
  }
  averagerank <- rowMeans(ranks, na.rm =TRUE)
  averageGMRAE <- rowMeans(df1, na.rm =TRUE)
  ranks <- cbind(ranks, "average rank" = averagerank)
  df1 <- cbind(df1, " average GMRAE" = averageGMRAE)

  for(m in 1:length(unique(frame$method))){
    GMRAElist[[m]] <- unname(df1[m, 1:length(unique(frame$horizon))])
    methodlist[[m]] <- rep(as.vector(unique(frame$method))[m],length(unique(frame$horizon)))
    horizonlist[[m]]<- as.vector(unique(frame$horizon))
  }
  GMRAE1 <- Reduce(c, GMRAElist)
  GMRAE <- Reduce(c, GMRAE1)
  horizon <- Reduce(c, horizonlist)
  method = Reduce(c, methodlist)
  df2 <- data.frame(GMRAE, horizon, method )
# Plot GMRAEs
  gp1 <- ggplot2::ggplot(df2, ggplot2::aes(x=horizon, y=GMRAE, group=method,color=method, shape=method))+
    ggplot2::scale_shape_manual(values=1:nlevels(df2$method)) +
    ggplot2::labs(title = "GMRAE for different horizons") +
    ggplot2::geom_line() +
    ggplot2::geom_point(size=3)+
    ggplot2::theme(plot.title = ggplot2::element_text(hjust = 0.5))
  print(gp1)
  outlist <- list("GMRAE" = df1,"rank" =ranks)
  if(sort == FALSE){
    return(outlist)
  }else{
    frame1 <-df1[order(df1$` average GMRAE`),]
    frame11 <- ranks[order(ranks$`average rank`),]
    outlist <- list("GMRAE" = frame1,"rank" = frame11)
    return(outlist)
  }
}
svcuonghvktqs/FORA documentation built on May 20, 2019, 9:57 a.m.