R Turning a list into a matrix when the list contains objects of “different size”

徘徊边缘 提交于 2019-12-11 19:53:54

问题


I've seen a couple of questions about turning matrices into lists (not really clear why you would want that) but the reverse operation I've been unable to find.

Basically, following

# ind.dum = data frame with 29 observations and 2635 variables
for (i in 1:ncol(ind.dum))
tmp[[i]]<-which(rollapply(ind.dum[,i],4,identical,c(1,0,0,0),by.column=T))

I got a list of 2635 objects, most of which contain 1 value, bust some up to 7. I'd need to convert this to a matrix with 2635 rows and as many columns as necessary to fit every value in a separate cells (with 0 values for the rest).

I tried all the coerce measures I know (as.data.frame, as.matrix ...) and also the option to define a new matrix with the maximum dimensions but nothing works.

m<-matrix(0,nrow=2635,ncol=7)
tmp_m<-structure(tmp,dim=dim(m))
Error in structure(tmp,dim=dim(m))dims [product 18445] do not match the length of object [2635]

I'm sure there's a quick fix for this so I'm hoping someone can help me with it. Btw, my values in the tmp list's objects are numeric, although some are "integer(0)" , i.e. when the pattern c(1,0,0,0) was not found in the columns of the original ind.dum matrix.

Not sure if there is a way to use unlist without losing the information about which values belong originally to the same row...

Desired Output A matrix or dataframe with 2635 rows and 7 columns and looking like this

12 0 0 0 0 0 0
8 14 0 0 0 0 0 
0  0 0 0 0 0 0 
1  4 8 12 0 0 0 
...

The values basically refer to years in which a specific pattern started. I need to be able to be able to use that information to tie this problem to an earlier problem described before (see this link).


回答1:


Try this for example:

do.call(rbind,lapply(ll,
               function(x)
                 if(length(x)==1)c(x,rep(0,6))
               else x))



回答2:


Here's a fast alternative that does what it sounds like you are describing:

First, sample data always helps:

LL <- list(1:3, numeric(0), c(1:3,1), 1:7)
LL
# [[1]]
# [1] 1 2 3
# 
# [[2]]
# numeric(0)
# 
# [[3]]
# [1] 1 2 3 1
# 
# [[4]]
# [1] 1 2 3 4 5 6 7

Second, we'll make use of a little trick referred to as matrix indexing to fill an empty matrix with the values from your list.

## We need to know how many columns are needed for each list item
Ncol <- vapply(LL, length, 1L)

## M is our empty matrix, pre-filled with zeroes
M <- matrix(0, nrow = length(LL), ncol = max(Ncol))

## IJ is the row/column combination where values need to be inserted
IJ <- cbind(rep(seq_along(Ncol), times = Ncol), sequence(Ncol)) 

## Extract and insert!
M[IJ] <- unlist(LL, use.names = FALSE)

## View the result
M
#      [,1] [,2] [,3] [,4] [,5] [,6] [,7]
# [1,]    1    2    3    0    0    0    0
# [2,]    0    0    0    0    0    0    0
# [3,]    1    2    3    1    0    0    0
# [4,]    1    2    3    4    5    6    7



回答3:


I have a solution.

Not sure if it is good enough or there's any bug.

LL <- list(1:3, numeric(0), c(1:3, 1), 1:7)

with(data.frame(m <- plyr::rbind.fill.matrix(lapply(LL, matrix, nrow = 1))), replace(m, is.na(m), 0))


来源:https://stackoverflow.com/questions/22616292/r-turning-a-list-into-a-matrix-when-the-list-contains-objects-of-different-size

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!