From dev@kurt @end|ng |rom v@nd|jck-|@ur|j@@en@be  Fri Mar 22 18:16:22 2019
From: dev@kurt @end|ng |rom v@nd|jck-|@ur|j@@en@be (Kurt Van Dijck)
Date: Fri, 22 Mar 2019 18:16:22 +0100
Subject: [Rd] [PATCH 1/2] readtable: add hook for type conversions per column
Message-ID: <1553274983-15970-1-git-send-email-dev.kurt@vandijck-laurijssen.be>

This commit adds a function parameter to readtable. The function is called
for every column.
The goal is to allow specific (non-standard) type conversions depending on the input.
When the parameter is not given, or the function returns NULL, the legacy default applies.
The colClasses parameter still takes precedence, i.e. the colConvertFn only applies to
the default conversions.
This allows to properly load a .csv with timestamps expressed in the (quite common) %d/%m/%y %H:%M format,
which was impossible since overruling as.POSIXlt makes a copy in the users namespace, and
read.table would still take the base version of as.POSIXlt.
Rather than fixing my specific requirement, this hook allows to probe for any custom format
and do smart things with little syntax.

Signed-off-by: Kurt Van Dijck <dev.kurt at vandijck-laurijssen.be>
---
 src/library/utils/R/readtable.R | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/src/library/utils/R/readtable.R b/src/library/utils/R/readtable.R
index 238542e..076a707 100644
--- a/src/library/utils/R/readtable.R
+++ b/src/library/utils/R/readtable.R
@@ -65,6 +65,7 @@ function(file, header = FALSE, sep = "", quote = "\"'", dec = ".",
          strip.white = FALSE, blank.lines.skip = TRUE,
          comment.char = "#", allowEscapes = FALSE, flush = FALSE,
          stringsAsFactors = default.stringsAsFactors(),
+         colConvert = NULL,
          fileEncoding = "", encoding = "unknown", text, skipNul = FALSE)
 {
     if (missing(file) && !missing(text)) {
@@ -226,9 +227,18 @@ function(file, header = FALSE, sep = "", quote = "\"'", dec = ".",
     if(rlabp) do[1L] <- FALSE # don't convert "row.names"
     for (i in (1L:cols)[do]) {
         data[[i]] <-
-            if (is.na(colClasses[i]))
+            if (is.na(colClasses[i])) {
+                tmp <- NULL
+                if (!is.null(colConvert))
+                    # attempt to convert from user provided hook
+                    tmp <- colConvert(data[[i]])
+                if (!is.null(tmp))
+                    (tmp)
+                else
+                    # fallback, default
                 type.convert(data[[i]], as.is = as.is[i], dec=dec,
 			     numerals=numerals, na.strings = character(0L))
+            }
         ## as na.strings have already been converted to <NA>
             else if (colClasses[i] == "factor") as.factor(data[[i]])
             else if (colClasses[i] == "Date") as.Date(data[[i]])
-- 
1.8.5.rc3



[Rd] [PATCH 1/2] readtable: add hook for type conversions per column
Kurt Van Dijck