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.k...@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

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to