[R] How to avoid automatic coercion to factor?

Dutky, Steve steve.dutky at thomson.com
Thu Sep 4 01:09:51 CEST 2003


Prof Brian Ripley <ripley at stats.ox.ac.uk> wrote:
>...
>If you really want character columns, the way to do it is underhand:
>
>f <- function() {
>    a <- list(Int1=1:5,Char1=letters[1:5],Char2=letters[6:10])
>    attr(a, "row.names") <- 1:5
>    attr(a, "class") <- "data.frame"
>    a
>}
>...
This certainly appears to me to be the least ugly of the suggested methods.
Is there a point at which "underhand" becomes "inadvisable"?

>...
>We should ask why you want character columns in a data frame? 

The short answer is that it is closer to how I get the original data.  The
remaining manipulations appear more convenient to me as character columns in
a data frame (e.g.. as arguments to functions for fix, string and regular
expressions) than either factors or lists.  In this particular application,
the character columns share the same domain of values, however more often
than not, as factors, the same values appear as distinct levels in different
columns.

I grant that my S programming occurs in a vacuum and exhibits all the bad
habits I acquired from a life spent in impoverished development
environments.  I certainly appreciate the generosity of your feedback and
the availability of 'r-help at stat.math.ethz.ch'

Thanks, Steve Dutky
-----Original Message-----
From: Prof Brian Ripley [mailto:ripley at stats.ox.ac.uk]
Sent: Wednesday, September 03, 2003 12:51 AM
To: Deepayan Sarkar
Cc: Dutky, Steve; 'r-help at stat.math.ethz.ch'
Subject: Re: [R] How to avoid automatic coercion to factor?


Deepayan is correct, but note that I() creates a column of class "AsIs", 
not "character".  We should ask why you want character columns in a data 
frame?   (Certainly prior to 1.8.0 there is a fair chance that unless they 
are of class "AsIs" manipulations would turn them into factors.)

If you really want character columns, the way to do it is underhand:

f <- function() {
    a <- list(Int1=1:5,Char1=letters[1:5],Char2=letters[6:10])
    attr(a, "row.names") <- 1:5
    attr(a, "class") <- "data.frame"
    a
}

However, you might consider returning a list.


On Tue, 2 Sep 2003, Deepayan Sarkar wrote:

> 
> >From ?data.frame:
> 
>      Character variables passed to 'data.frame' are converted
>      to factor columns unless protected by 'I'. If a list or data frame
>      or matrix is passed to 'data.frame' it is as if each column had
>      been passed as a separate argument.
> 
> See the Examples section for an example.
> 
> On Tuesday 02 September 2003 17:30, Dutky, Steve wrote:
> > I have a function that manipulates a list of numeric and character
> > components of equal length and wants to return a data.frame.
> >
> > EG,
> >
> > f<-function() {
> > 	a<-list(Int1=1:5,Char1=letters[1:5],Char2=letters[6:10])
> > 	b<-data.frame(a)
> > }
> >
> > How can I get the columns Char1, Char2, (...CharN) returned coerced to
> > character and not factor?
> >
> > It appears that I could coerce individual columns by
> > b$CharI<-as.character(b$CharI). Is there a less ugly way of doing this?
> 
> ______________________________________________
> R-help at stat.math.ethz.ch mailing list
> https://www.stat.math.ethz.ch/mailman/listinfo/r-help
> 
> 

-- 
Brian D. Ripley,                  ripley at stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595




More information about the R-help mailing list