
  # -------------------------------------------------------------------------------------------------------------------------  #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  #                                                                                                                            #
  #           File Name              :  cleanDTColumns.R                                                                       #
  #           Last Updated Funclist  :  15 Feb 2014,  1:13 AM (Saturday)                                                       #
  #                                                                                                                            #
  #           Author Name            :  Rick Saporta                                                                           #
  #           Author Email           :  RickSaporta@gmail.com                                                                  #
  #           Author URL             :  www.github.com/rsaporta                                                                #
  #                                                                                                                            #
  #           Packages Called        :  NA                                                                                     #
  #           Packages Used via NS   :  NA                                                                                     #
  #                                                                                                                            #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  #                                                                                                                            #
  #   cleanDTColumns     ( .DT, ColumnGroups=names(DictClassFUN), delWhenDone=TRUE, verbose=FALSE, pos=1                       #
  #                        , e=parent.frame(pos) )                                                                             #
  #   cleanDTColumns     ( .DT, ColumnGroups=names(DictClassFUN), delWhenDone=TRUE, pos=1 )                                    #
  #                                                                                                                            #
  #                                                                                                                            #
  #                                                     <END FUNCS>                                                            #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  # -------------------------------------------------------------------------------------------------------------------------  #

# Basic Usage:  
#      cleanDTColumns(DT)  
#
# In the calling environment, there should exists vectors of column names 
# indicating which columns are to be converted.  The name of the vector indicates 
# the class to be converted *to*.  For example, .numCols are converted to numeric class.   
#
# The vector of column names should have a name that exists in DictClassFUN  
#
# DictClassFUN is a dictionary, indicating which function to use to convert the columns.  
# the `names(DictClassFUN)` are the column names. The valuse of DictClassFUN are  
# the function names.   
 
# ------------------------ #

## DICTIONARY

DictClassFUN <- c(
    # Variable Name =  # Function To Use
     ".dateCols"    = as.Date
  , ".intCols"      = as.integer
  , ".boolCols"     = as.logical
  , ".numericCols"  = as.numeric
  , ".numerCols"    = as.numeric
  , ".numCols"      = as.numeric
  , ".factorCols"   = factor
  , ".charCols"     = as.character
  , ".stringCols"   = as.character
  )
  
# ------------------------ #
  cleanDTColumns <- function(.DT, ColumnGroups=names(DictClassFUN), delWhenDone=TRUE, verbose=FALSE, pos=1, e=parent.frame(pos))  {
      # ColumnGroups :  the list of *potential* column groups from the names of the dictionary. 

            ## Newer and better function available. 
  warning("Have a look at  `fixColTypes_`() in  the general utils functions")


      # Force the environment variable, since it depends on pos
      force(e)

      nms <- names(.DT)

      # only keep those which currently exist
      ColumnGroups <- ColumnGroups[sapply(ColumnGroups, exists, envir=e)]

      ## error test
      if (!length(ColumnGroups))  {
        warning("DT was *NOT* modified because no ColumnGroups were found. Check for the existence of the names(DictClassFun)")
        return(invisible(.DT))
      }

      if (verbose) {
        cat("Found the following groups of columns to modify: ", pasteC(ColumnGroups, C=",  "), "\n")
      }

      # get a full list of all columns that will be modified. We will check which are vectors. 
      .colsToModify <- unlist(sapply(ColumnGroups, get, envir=e, USE.NAMES=FALSE))
      .colsToModify <- intersect(nms, .colsToModify)

      if(!length(.colsToModify))
        warning("\nNo columns identified. Variables to use are:\n\t`.dateCols`  `.intCols`  `.boolCols`  `.numericCols`  `.factorCols`  `.charCols`\n")

      # identify which of the columns that will be modified are facotrs.  
      # Convert those to character before any other modification 
      .colsFromFactor <- .colsToModify[.DT[, sapply(.SD, is.factor), .SDcols=.colsToModify]]
      if(length(.colsFromFactor))
        .DT[, c(.colsFromFactor) := lapply(.SD, as.character), .SDcols=.colsFromFactor]

      for(ColGroup in ColumnGroups) {
        .cols <- intersect(nms, get(ColGroup, envir=e))
        if (verbose)
           cat(sprintf("Processing %15s  [ %2d of %2d Columns Found  ]", ColGroup, length(.cols), length(unique(get(ColGroup, envir=e)))), "\n")
        if(length(.cols))
           .DT[, c(.cols) := lapply(.SD, DictClassFUN[[ColGroup]]), .SDcols=.cols]
      }

      if (delWhenDone)
        rm(list=ColumnGroups, envir=e )

      return(invisible(.DT))
    }

cleanDTColumns <- function(.DT, ColumnGroups=names(DictClassFUN), delWhenDone=TRUE, pos=1)  {
  # ColumnGroups :  the list of *potential* column groups from the names of the dictionary. 



  nms <- names(.DT)

  
  # only keep those which currently exist
  ColumnGroups <- ColumnGroups[sapply(ColumnGroups, exists, envir=parent.frame(pos))]

  # get a full list of all columns that will be modified. We will check which are vectors. 
  .colsToModify <- unlist(sapply(ColumnGroups, get, envir=parent.frame(pos), USE.NAMES=FALSE))
  .colsToModify <- intersect(nms, .colsToModify)

  if(!length(.colsToModify))
    warning("\nNo columns identified. Variables to use are:\n\t`.dateCols`  `.intCols`  `.boolCols`  `.numericCols`  `.factorCols`  `.charCols`\n")

  # identify which of the columns that will be modified are facotrs.  
  # Convert those to character before any other modification 
  .colsFromFactor <- .colsToModify[.DT[, sapply(.SD, is.factor), .SDcols=.colsToModify]]
  if(length(.colsFromFactor))
    .DT[, c(.colsFromFactor) := lapply(.SD, as.character), .SDcols=.colsFromFactor]

  for(ColGroup in ColumnGroups) {
    .cols <- intersect(nms, get(ColGroup, envir=parent.frame(pos)))
    if(length(.cols))
       .DT[, c(.cols) := lapply(.SD, DictClassFUN[[ColGroup]]), .SDcols=.cols]
  }

  if (delWhenDone)
    rm(list=ColumnGroups, envir=parent.frame(pos) )
}
