Chris Conner
2012-Jan-11 19:40 UTC
[R] turning a list of vectors into a data.frame (as rows of the DF)?
As a newer R practicioner, it seems I stump myself weekly (at least) with issues that have spinning my wheels. Here is yet another... I'm trying to turn a list of numeric vectors (of uneual length) inot a dataframe. Each vector held in the list represents a row, and there are some rows of unequal length. I would like NAs as placeholders for "missing" data in the shorter vectors. I think I'm missing something quite basic. v1 <- c(1,2,3,4) v2 <- c(1,2) lst1 <- list(v1,v2) Of course there is the intuitive: as.data.frame(lst1) However, the recycling rule (expectedly) reclycles 1,2 versus using NAs as placeholders. Then, looking into Teetor's R Cookbook, there is a piece of code that looked (from the description) like it might do the trick: do.call(rbind, Map(as.data.frame,lst1) But I get the error: Error in match.names(clabs, names(xi)) : names do not match previous names Thinking the source of the error had to do with the vectors of unequal lenght, I tried Hadley's rbind.fill thusly: library(reshape) do.call(rbind.fill, Map(as.data.frame,lst1) Which produced a dataset, but gain, not in the desired format. Thanks in advance to anyone that can bring my frustrations to end! C [[alternative HTML version deleted]]
R. Michael Weylandt
2012-Jan-11 20:34 UTC
[R] turning a list of vectors into a data.frame (as rows of the DF)?
Most methods take the rows of data.frame()s to be very significant
(indicating multiple values from a single observation) so what you're
doing seems like it may be "against the spirit of R", but if you want
a simple NA padding at the end, this should do it:
listToDF <- function(inputList, fill = NA){
# Use fill = NULL for regular recycling behavior
maxLen = max(sapply(inputList, length))
for(i in seq_along(inputList))
inputList[[i]] <- c(inputList[[i]], rep(fill, maxLen -
length(inputList[[i]])))
return(as.data.frame(inputList))
}
listToDF(list(x = 1:4, y = 1:2))
Michael
On Wed, Jan 11, 2012 at 2:40 PM, Chris Conner <connerpharmd at yahoo.com>
wrote:> As a newer R practicioner, it seems I stump myself weekly (at least) with
issues that have spinning my wheels.? Here is yet another... I'm trying to
turn a list of numeric vectors (of uneual length) inot a dataframe.? Each vector
held in the list represents a row, and there are some rows of unequal length.? I
would like NAs as placeholders for "missing" data in the shorter
vectors.? I think I'm missing something quite basic.
>
> v1 <- c(1,2,3,4)
> v2 <- c(1,2)
> lst1 <- list(v1,v2)
>
> Of course there is the intuitive:
>
> as.data.frame(lst1)
>
> However, the recycling rule (expectedly) reclycles 1,2 versus using NAs as
placeholders.
>
> Then, looking into Teetor's R Cookbook, there is a piece of code that
looked (from the description) like it might do the trick:
>
> do.call(rbind, Map(as.data.frame,lst1)
>
> But I get the error:
> Error in match.names(clabs, names(xi)) :
> ? names do not match previous names
>
> Thinking the source of the error had to do with the vectors of unequal
lenght, I tried Hadley's rbind.fill thusly:
>
> library(reshape)
> do.call(rbind.fill, Map(as.data.frame,lst1)
>
> Which produced a dataset, but gain, not in the desired format.
>
> Thanks in advance to anyone that can bring my frustrations to end!
> C
> ? ? ? ?[[alternative HTML version deleted]]
>
>
> ______________________________________________
> 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.
>
William Dunlap
2012-Jan-11 20:47 UTC
[R] turning a list of vectors into a data.frame (as rows of the DF)?
Perhaps the following does what you want. It extends
each element of your list to a common length, converts
that to a matrix, then to a data.frame:
f <- function(data) {
nCol <- max(vapply(data, length, 0))
data <- lapply(data, function(row) c(row, rep(NA, nCol-length(row))))
data <- matrix(unlist(data), nrow=length(data), ncol=nCol, byrow=TRUE)
data.frame(data)
}
E.g.,
> rawData <- list(c(1,2,3), c(11,12), integer(), 31)
> f(rawData)
X1 X2 X3
1 1 2 3
2 11 12 NA
3 NA NA NA
4 31 NA NA
What sort of data is this? If it is longitudinal
it might be more straigtforward to store it as a
three-column data.frame (columns "subject", "time",
"value").
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 Chris Conner
> Sent: Wednesday, January 11, 2012 11:41 AM
> To: HelpR
> Subject: [R] turning a list of vectors into a data.frame (as rows of the
DF)?
>
> As a newer R practicioner, it seems I stump myself weekly (at least) with
issues that have spinning my
> wheels.? Here is yet another... I'm trying to turn a list of numeric
vectors (of uneual length) inot a
> dataframe.? Each vector held in the list represents a row, and there are
some rows of unequal
> length.? I would like NAs as placeholders for "missing" data in
the shorter vectors.? I think I'm
> missing something quite basic.
>
> v1 <- c(1,2,3,4)
> v2 <- c(1,2)
> lst1 <- list(v1,v2)
>
> Of course there is the intuitive:
>
> as.data.frame(lst1)
>
> However, the recycling rule (expectedly) reclycles 1,2 versus using NAs as
placeholders.
>
> Then, looking into Teetor's R Cookbook, there is a piece of code that
looked (from the description)
> like it might do the trick:
>
> do.call(rbind, Map(as.data.frame,lst1)
>
> But I get the error:
> Error in match.names(clabs, names(xi)) :
> ? names do not match previous names
>
> Thinking the source of the error had to do with the vectors of unequal
lenght, I tried Hadley's
> rbind.fill thusly:
>
> library(reshape)
> do.call(rbind.fill, Map(as.data.frame,lst1)
>
> Which produced a dataset, but gain, not in the desired format.
>
> Thanks in advance to anyone that can bring my frustrations to end!
> C
> [[alternative HTML version deleted]]
Marc Schwartz
2012-Jan-11 20:51 UTC
[R] turning a list of vectors into a data.frame (as rows of the DF)?
On Jan 11, 2012, at 1:40 PM, Chris Conner wrote:> As a newer R practicioner, it seems I stump myself weekly (at least) with issues that have spinning my wheels. Here is yet another... I'm trying to turn a list of numeric vectors (of uneual length) inot a dataframe. Each vector held in the list represents a row, and there are some rows of unequal length. I would like NAs as placeholders for "missing" data in the shorter vectors. I think I'm missing something quite basic. > > v1 <- c(1,2,3,4) > v2 <- c(1,2) > lst1 <- list(v1,v2) > > Of course there is the intuitive: > > as.data.frame(lst1) > > However, the recycling rule (expectedly) reclycles 1,2 versus using NAs as placeholders. > > Then, looking into Teetor's R Cookbook, there is a piece of code that looked (from the description) like it might do the trick: > > do.call(rbind, Map(as.data.frame,lst1) > > But I get the error: > Error in match.names(clabs, names(xi)) : > names do not match previous names > > Thinking the source of the error had to do with the vectors of unequal lenght, I tried Hadley's rbind.fill thusly: > > library(reshape) > do.call(rbind.fill, Map(as.data.frame,lst1) > > Which produced a dataset, but gain, not in the desired format. > > Thanks in advance to anyone that can bring my frustrations to end! > C > [[alternative HTML version deleted]]There may be an easier way, but try this: list2df <- function(x) { MAX.LEN <- max(sapply(x, length), na.rm = TRUE) DF <- data.frame(lapply(x, function(x) c(x, rep(NA, MAX.LEN - length(x))))) colnames(DF) <- paste("V", seq(ncol(DF)), sep = "") DF }> list2df(lst1)V1 V2 1 1 1 2 2 2 3 3 NA 4 4 NA HTH, Marc Schwartz