Bug 17269 - Enhanced type.convert()
Summary: Enhanced type.convert()
Status: CLOSED FIXED
Alias: None
Product: R
Classification: Unclassified
Component: Wishlist (show other bugs)
Version: R 3.3.*
Hardware: Other All
: P5 enhancement
Assignee: R-core
URL:
Depends on:
Blocks:
 
Reported: 2017-05-09 16:29 UTC by Arni Magnusson
Modified: 2017-08-03 14:21 UTC (History)
1 user (show)

See Also:


Attachments
NAMESPACE (6.69 KB, text/plain)
2017-05-10 15:33 UTC, Arni Magnusson
Details
NAMESPACE (diff) (114 bytes, patch)
2017-05-10 15:34 UTC, Arni Magnusson
Details | Diff
readtable.R (11.68 KB, text/x-r-source)
2017-05-10 15:39 UTC, Arni Magnusson
Details
readtable.R (diff) (718 bytes, patch)
2017-05-10 15:40 UTC, Arni Magnusson
Details | Diff
type.convert.Rd (4.07 KB, text/x-matlab)
2017-05-10 15:40 UTC, Arni Magnusson
Details
type.convert.Rd (diff) (3.12 KB, patch)
2017-05-10 15:41 UTC, Arni Magnusson
Details | Diff
Patch to enhance utils::type.convert (6.47 KB, patch)
2017-05-10 18:56 UTC, Arni Magnusson
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Arni Magnusson 2017-05-09 16:29:47 UTC
The type.convert() function coerces data columns/vectors to an appropriate type. This is very useful, not only when importing data from files, but also for common data manipulation tasks.

I would like to suggest enhancing the type.convert() function so it can be used to directly to handle data frames, lists, matrices, and non-character vectors:

type.convert <-
function(x, na.strings = "NA", as.is = FALSE, dec = ".",
	 numerals = c("allow.loss", "warn.loss", "no.loss"))
{
    if(is.list(x)) {
        for(i in seq_len(length(x)))
            x[[i]] <- .External2(C_typeconvert, as.character(x[[i]]),
                        na.strings, as.is, dec, match.arg(numerals))
    }
    else if(is.matrix(x)) {
        mode(x) <- "character"
        x <- .External2(C_typeconvert, x,
                        na.strings, as.is, dec, match.arg(numerals))
    }
    else {
        x <- .External2(C_typeconvert, as.character(x),
                        na.strings, as.is, dec, match.arg(numerals))
    }
    x
}

To test the added functionality without R, the function environment can be defined as:

environment(type.convert) <- environment(utils::type.convert)

Example:

class(999)
class(type.convert(999))
auto <- type.convert(mtcars)
str(mtcars) # all numeric
str(auto)   # mix of numeric and integer

I'm hoping the Core Team agrees that this enhancement of type.convert() provides a very useful function for the R users and developers, at a minimal cost.

All the best,

Arni
Comment 1 Michael Lawrence 2017-05-09 18:02:54 UTC
Seems fine to me. Would you mind providing a patch? The posted code needs some clean up (hints: it should only call .External2() in one place, use seq_along(), recurse, etc). Also, it should probably be made an S3 generic.
Comment 2 Arni Magnusson 2017-05-10 15:33:05 UTC
Created attachment 2247 [details]
NAMESPACE
Comment 3 Arni Magnusson 2017-05-10 15:34:06 UTC
Created attachment 2248 [details]
NAMESPACE (diff)
Comment 4 Arni Magnusson 2017-05-10 15:39:41 UTC
Created attachment 2249 [details]
readtable.R
Comment 5 Arni Magnusson 2017-05-10 15:40:01 UTC
Created attachment 2250 [details]
readtable.R (diff)
Comment 6 Arni Magnusson 2017-05-10 15:40:58 UTC
Created attachment 2251 [details]
type.convert.Rd
Comment 7 Arni Magnusson 2017-05-10 15:41:49 UTC
Created attachment 2252 [details]
type.convert.Rd (diff)
Comment 8 Arni Magnusson 2017-05-10 16:00:36 UTC
Thank you for the positive response. I have made the suggested changes - to call .External2() in one place, use seq_along(), recurse, and write as S3 generic.

Working from the current SVN repo (r72665) I have modified three files inside trunk/src/library/utils:

  man/type.convert.Rd
  R/readtable.R
  NAMESPACE

The new functionality can be tested using example(type.convert) after rebuilding R. The updated help page could be linked to from other help pages, such as mode.Rd.

All the best,

Arni
Comment 9 Michael Lawrence 2017-05-10 16:41:46 UTC
Thanks. 

I was thinking that by default as.character() would be applied to any incoming object, except for arrays (is.array) which use storage.mode<-().

Please add an example for the matrix case.

Also, please combine the patches into a single file to simplify things.
Comment 10 Arni Magnusson 2017-05-10 18:56:29 UTC
Created attachment 2253 [details]
Patch to enhance utils::type.convert

Thanks again for constructive comments.

I have revised the type.convert function so as.character() is applied to any incoming object, except for arrays (is.array) which use storage.mode<-().

Added an example for the matrix case and "see also" crosslinks to the class() and storage.mode() help pages, as well as a link back from the storage.mode() help page.

The single-file patch created with 'svn diff' is hopefully a more convenient format than earlier attachments.

All the best,

Arni
Comment 11 Michael Lawrence 2017-05-10 22:12:08 UTC
Thanks for this contribution. The extra man page cross-references are thoughtful. I'll try to commit this soon.
Comment 12 Michael Lawrence 2017-08-03 14:21:39 UTC
Thanks, committed.