Reputation: 1909
Say I have a list of indices, including elements that are empty, like:
l <- list(c(1,2,3), c(1), c(1,5), NULL, c(2, 3, 5))
Which specify the non-zero elements in a matrix, like:
(m <- matrix(c(1,1,1,0,0, 1,0,0,0,0, 1,0,0,0,5, 0,0,0,0,0, 0,1,1,0,1), nrow=5, byrow=TRUE))
[,1] [,2] [,3] [,4] [,5]
[1,] 1 1 1 0 0
[2,] 1 0 0 0 0
[3,] 1 0 0 0 5
[4,] 0 0 0 0 0
[5,] 0 1 1 0 1
What is the fastest way, using R, to make m
from l
, giving that the matrix is very big, say 50.000 rows and 2000 columns?
Upvotes: 2
Views: 122
Reputation: 887501
You can Filter
the non-NULL list elements from 'l' and use melt
to reshape it to 'data.frame' with 'key/value' columns or `row/column' index columns.
library(reshape2)
d2 <- melt(Filter(Negate(is.null), setNames(l, seq_along(l))))
Un1 <- unlist(l)
m1 <- matrix(0, nrow=length(l), ncol=max(Un1))
m1[cbind(as.numeric(d2[,2]), d2[,1])] <- 1
m1
# [,1] [,2] [,3] [,4] [,5]
#[1,] 1 1 1 0 0
#[2,] 1 0 0 0 0
#[3,] 1 0 0 0 1
#[4,] 0 0 0 0 0
#[5,] 0 1 1 0 1
Or
library(Matrix)
as.matrix(sparseMatrix(as.numeric(d2[,2]), d2[,1], x=1))
# [,1] [,2] [,3] [,4] [,5]
#[1,] 1 1 1 0 0
#[2,] 1 0 0 0 0
#[3,] 1 0 0 0 1
#[4,] 0 0 0 0 0
#[5,] 0 1 1 0 1
Upvotes: 4
Reputation: 31171
You can do:
do.call(rbind, lapply(l, function(x) (1:max(unlist(l)) %in% x)+0L))
# [,1] [,2] [,3] [,4] [,5]
#[1,] 1 1 1 0 0
#[2,] 1 0 0 0 0
#[3,] 1 0 0 0 1
#[4,] 0 0 0 0 0
#[5,] 0 1 1 0 1
Even if akrun solution should be faster!
Upvotes: 2