
  # -------------------------------------------------------------------------------------------------------------------------  #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  #                                                                                                                            #
  #           File Name              :  reshapeDT.r                                                                            #
  #           Last Updated Funclist  :  08 Feb 2015,  5:12 AM (Sunday)                                                         #
  #                                                                                                                            #
  #           Author Name            :  Rick Saporta                                                                           #
  #           Author Email           :  RickSaporta@gmail.com                                                                  #
  #           Author URL             :  www.github.com/rsaporta                                                                #
  #                                                                                                                            #
  #           Packages Called        :  NA                                                                                     #
  #           Packages Used via NS   :  NA                                                                                     #
  #                                                                                                                            #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  #                                                                                                                            #
  #   reshapeDT          ( DT, namesCol, values, byCols=setdiff(names(DT), c(namesCol, values)), pad=FALSE )                   #
  #                                                                                                                            #
  #                                                                                                                            #
  #                                                     <END FUNCS>                                                            #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  # -------------------------------------------------------------------------------------------------------------------------  #

## TODO Have a look at 
"~/git/data.table/reshape with DT.r"



reshapeDT <- function(DT, namesCol, values, byCols=setdiff(names(DT), c(namesCol, values)), pad=FALSE) {

  ## For the tryCatch error handling
  missing.pad <- missing(pad)

  if (length(miss.col <- setdiff(c(namesCol, values, byCols), names(DT))))
    stop(warningCols(paste("The following", plrl("columns", miss.col), "not found in the DT "), paste_l(miss.col)))

  if (!is.null(pad) && !identical(pad, FALSE)) {
    pad.value <- pad
    pad <- TRUE
  }

  if (pad) {
    key.bak <- key(DT)
    cols.using <- c(byCols, namesCol)
    setkeyv(DT, cols.using)
    
    DT.all.values <- as.data.table(do.call(CJ, lapply(cols.using, function(col) unique(DT[[col]]))))
    setnames(DT.all.values, cols.using)
  } else 
    DT.all.values <- TRUE

  ret <- tryCatch(DT[DT.all.values, allow.cartesian=TRUE][, setNames(as.list(get(values)), get(namesCol)), keyby=byCols], 
          error=function(e) 
              if (missing.pad && grepl("j doesn't evaluate to the same number of columns for each group", e$message))
                reshapeDT(DT=DT, namesCol=namesCol, values=values, byCols=byCols, pad=TRUE)
              else
                stop(e) 
            )

  if (pad)
    setkeyv(DT, key.bak)

  return(ret)
}

#  ## ---------------------------------------------- ##
#  ##  TODO:   bug when non-unique values of byCols  ##
#  ## ---------------------------------------------- ##
#  # eg: #   dt2 <- data.table(structure(list(state = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 2L), .Label = c("Aaa", "Dd"), class = "factor"), city = structure(c(1L,2L, 3L, 4L, 4L, 5L, 6L), .Label = c("bb", "ccc", "ddd", "fff","ggg", "hh"), class = "factor"), type = structure(c(1L, 2L, 2L,2L, 2L, 2L, 3L), .Label = c("Type 1", "Type 2", "Type 4"), class = "factor"),value = 1:7), .Names = c("state", "city", "type", "value"), sorted = c("state", "city", "type"), class = c("data.table","data.frame"), row.names = c(NA, -7L)), key='state,city,type')
#  # eg: #   reshapeDT(dt2, "type", "value", byCols=c("state", "city"))
#  reshapeDT(dt2, "type", "value", byCols=c("state", "city"))
#  reshapeDT(dt2, "type", "value", byCols=c("state", "city"), pad=NA)
