[R] apply --> data.frame

William Dunlap wdunlap at tibco.com
Thu Aug 30 19:35:08 CEST 2012


Here are two ways of turning a character vector like yours into a data.frame,
neither of which uses an apply-like function.
  > s <- c(XVI="p,16", XVII="q,17", XVIII="r,18")
  > d1 <- data.frame(Letter=sub(",.*", "", s), Number=as.integer(sub(".*,","",s)))
  > d2 <- read.table(text=s, sep=",", col.names=c("Letter","Number"), row.names=names(s))
  > d1
        Letter Number
  XVI        p     16
  XVII       q     17
  XVIII      r     18
  > all.equal(d1, d2)
  [1] TRUE

I don't agree with your analysis of what went wrong with your example
  > z0 <- as.data.frame(t(sapply(c("a,1","b,2","c,3"),function (n) strsplit(n,",")[[1]])))
  > str(z0)
  'data.frame':   3 obs. of  2 variables:
   $ V1: Factor w/ 3 levels "a","b","c": 1 2 3
    ..- attr(*, "names")= chr  "a,1" "b,2" "c,3"
   $ V2: Factor w/ 3 levels "1","2","3": 1 2 3
    ..- attr(*, "names")= chr  "a,1" "b,2" "c,3"
You wrote
> I could, of course, do ret$V2 <- as.numeric(ret$V2) but this would mean
> a double conversion: from number to string first (by c()) and then back.
The "numbers" 1,2,3 were always considered to be strings, because
strsplit() takes strings, like "a,1", and returns a list of vectors of strings,
like list(c("a","1")).  The c() function has nothing to do with it.

Functions like read.table() will guess when it is appropriate to convert things
from strings to numbers, but most times you have to do the conversion explicitly.

Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com


> -----Original Message-----
> From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf
> Of Sam Steingold
> Sent: Thursday, August 30, 2012 9:44 AM
> To: r-help at r-project.org
> Subject: Re: [R] apply --> data.frame
> 
> > * Sam Steingold <fqf at tah.bet> [2012-08-30 08:56:17 -0400]:
> >
> > Is there a way for an apply-type function to return a data frame?
> > the closest thing I think of is
> >
> >   foo <- as.data.frame(t(sapply(...)))
> >   names(foo) <- c(....)
> 
> alas, this has a problem of creating a "homogeneous" data frame, i.e.,
> all the columns are numbers or characters, because the function passed
> to sapply returns c(....) and
> > c(1,2,"a")
> [1] "1" "2" "a"
> 
> e.g.,
> as.data.frame(t(sapply(c("a,1","b,2","c,3"),function (n) strsplit(n,",")[[1]])))
>     V1 V2
> a,1  a  1
> b,2  b  2
> c,3  c  3
> 
> 'data.frame':	3 obs. of  2 variables:
>  $ V1: Factor w/ 3 levels "a","b","c": 1 2 3
>   ..- attr(*, "names")= chr  "a,1" "b,2" "c,3"
>  $ V2: Factor w/ 3 levels "1","2","3": 1 2 3
>   ..- attr(*, "names")= chr  "a,1" "b,2" "c,3"
> 
> I wanted the V1 column to be a string, and V2 to be a number.
> (I know stringsAsFactors=FALSE would replace factors with strings, but I
> need a string and a number)
> 
> I could, of course, do ret$V2 <- as.numeric(ret$V2) but this would mean
> a double conversion: from number to string first (by c()) and then back.
> 
> thanks.
> 
> --
> Sam Steingold (http://sds.podval.org/) on Ubuntu 12.04 (precise) X 11.0.11103000
> http://www.childpsy.net/ http://mideasttruth.com http://truepeace.org
> http://openvotingconsortium.org http://ffii.org http://www.memritv.org
> Diplomacy is the art of saying "nice doggy" until you can find a nice rock.
> 
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.




More information about the R-help mailing list