Dear all, A few months ago, I asked for your help on the following problem: I have a list with three (named) numeric vectors:> lst = list(a=c(A=1,B=8) , b=c(A=2,B=3,C=0), c=c(B=2,D=0) ) > lst$a A B 1 8 $b A B C 2 3 0 $c B D 2 0 Now, I'd love to use this list to create the following data frame:> dtf = data.frame(a=c(A=1,B=8,C=NA,D=NA),+ b=c(A=2,B=3,C=0,D=NA), + c=c(A=NA,B=2,C=NA,D=0) )> dtfa b c A 1 2 NA B 8 3 2 C NA 0 NA D NA NA 0 That is, I wish to "merge" the three vectors in the list into a data frame by their "(row)"names. And I got the following answer: library(zoo) z <- do.call(merge, lapply(lst, function(x) zoo(x, names(x)))) rownames(z) <- time(z) coredata(z) However, it does not seem to be working. Here's what I get when I try it:> lst = list(a=c(A=1,B=8) , b=c(A=2,B=3,C=0), c=c(B=2,D=0) ) > library(zoo) > z <- do.call(merge, lapply(lst, function(x) zoo(x, names(x))))Error in if (freq > 1 && identical(all.equal(freq, round(freq)), TRUE)) freq <- round(freq) : missing value where TRUE/FALSE needed In addition: Warning message: NAs introduced by coercion and z was not created. Any ideas on what is going on here? Thank you, Dimitri
Dmitri: As you apparently have not received a reply.... IMHO, one of the glories of R is the ease with which you can create de novo solutions for little problems like this yourself. While there may be more efficient,robust, and elegant solutions already available, it can frequently be considerably more time consuming to find and figure them out, as you appear to have experienced. (And once outside base R and standard packages, documentation can be problematic). Anyway, whether you agree with that propoganda or not, here is a little function (no claim for elegance or efficiency!) that does what you want, I think: makeFrame<-function(xlist) { allnames <- sort(unique(unlist(sapply(xlist,names)))) data.frame(lapply(xlist,function(y,an)structure(y[match(an,names(y))], names=NULL), an=allnames),row.names=allnames) } ##test it> lst$a A B 1 8 $b A B C 2 3 0 $c B D 2 0> makeFrame(lst)a b c A 1 2 NA B 8 3 2 C NA 0 NA D NA NA 0 Cheers, Bert Gunter Genentech Nonclinical Statistics South San Francisco, CA 94404 650-467-7374 -----Original Message----- From: r-help-bounces at stat.math.ethz.ch [mailto:r-help-bounces at stat.math.ethz.ch] On Behalf Of Dimitri Szerman Sent: Thursday, April 05, 2007 11:58 AM To: R-Help Subject: [R] creating a data frame from a list Dear all, A few months ago, I asked for your help on the following problem: I have a list with three (named) numeric vectors:> lst = list(a=c(A=1,B=8) , b=c(A=2,B=3,C=0), c=c(B=2,D=0) ) > lst$a A B 1 8 $b A B C 2 3 0 $c B D 2 0 Now, I'd love to use this list to create the following data frame:> dtf = data.frame(a=c(A=1,B=8,C=NA,D=NA),+ b=c(A=2,B=3,C=0,D=NA), + c=c(A=NA,B=2,C=NA,D=0) )> dtfa b c A 1 2 NA B 8 3 2 C NA 0 NA D NA NA 0 That is, I wish to "merge" the three vectors in the list into a data frame by their "(row)"names. And I got the following answer: library(zoo) z <- do.call(merge, lapply(lst, function(x) zoo(x, names(x)))) rownames(z) <- time(z) coredata(z) However, it does not seem to be working. Here's what I get when I try it:> lst = list(a=c(A=1,B=8) , b=c(A=2,B=3,C=0), c=c(B=2,D=0) ) > library(zoo) > z <- do.call(merge, lapply(lst, function(x) zoo(x, names(x))))Error in if (freq > 1 && identical(all.equal(freq, round(freq)), TRUE)) freq <- round(freq) : missing value where TRUE/FALSE needed In addition: Warning message: NAs introduced by coercion and z was not created. Any ideas on what is going on here? Thank you, Dimitri ______________________________________________ R-help at stat.math.ethz.ch 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.
Hi Dimitri, You can try this one if you'd like: lst = list(a=c(A=1,B=8) , b=c(A=2,B=3,C=0), c=c(B=2,D=0)) # get unique names nms <- unique(rapply(lst,function(x) names(x))) # create a vector of NA's and then fill it according # to matching names for each element of list doit <- function(x,nms) { y <- rep(NA,length(nms)); names(y) <- nms y[match(names(x),names(y))] <- x return(y) } # apply it to the data dtf <- as.data.frame(sapply(lst,doit,nms)) --- Dimitri Szerman <dimitrijoe at gmail.com> wrote:> Dear all, > > A few months ago, I asked for your help on the following problem: > > I have a list with three (named) numeric vectors: > > > lst = list(a=c(A=1,B=8) , b=c(A=2,B=3,C=0), c=c(B=2,D=0) ) > > lst > $a > A B > 1 8 > > $b > A B C > 2 3 0 > > $c > B D > 2 0 > > Now, I'd love to use this list to create the following data frame: > > > dtf = data.frame(a=c(A=1,B=8,C=NA,D=NA), > + b=c(A=2,B=3,C=0,D=NA), > + c=c(A=NA,B=2,C=NA,D=0) ) > > > dtf > a b c > A 1 2 NA > B 8 3 2 > C NA 0 NA > D NA NA 0 > > That is, I wish to "merge" the three vectors in the list into a data frame > by their "(row)"names. > > And I got the following answer: > > library(zoo) > z <- do.call(merge, lapply(lst, function(x) zoo(x, names(x)))) > rownames(z) <- time(z) > coredata(z) > > However, it does not seem to be working. Here's what I get when I try it: > > > lst = list(a=c(A=1,B=8) , b=c(A=2,B=3,C=0), c=c(B=2,D=0) ) > > library(zoo) > > z <- do.call(merge, lapply(lst, function(x) zoo(x, names(x)))) > Error in if (freq > 1 && identical(all.equal(freq, round(freq)), > TRUE)) freq <- round(freq) : > missing value where TRUE/FALSE needed > In addition: Warning message: > NAs introduced by coercion > > and z was not created. > > Any ideas on what is going on here? > Thank you, > Dimitri > > ______________________________________________ > R-help at stat.math.ethz.ch 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. >____________________________________________________________________________________ Be a PS3 game guru.