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.comhttp://truepeace.orghttp://openvotingconsortium.orghttp://ffii.orghttp://www.memritv.org
Diplomacy is the art of saying "nice doggy" until you can find a nice rock.