How do I make a matrix from a list of vectors in R?
One option is to use do.call()
:
> do.call(rbind, a)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 1 2 3 4 5
[2,] 2 1 2 3 4 5
[3,] 3 1 2 3 4 5
[4,] 4 1 2 3 4 5
[5,] 5 1 2 3 4 5
[6,] 6 1 2 3 4 5
[7,] 7 1 2 3 4 5
[8,] 8 1 2 3 4 5
[9,] 9 1 2 3 4 5
[10,] 10 1 2 3 4 5
Efficiently create a matrix from list of named vectors
You can try rbindlist
function from the data.table
package. See the example.
require(data.table)
require(dplyr)
all_names <- unique(do.call(paste0, replicate(5, sample(LETTERS, 1e4, TRUE), FALSE)))
anyDuplicated(all_names)
n <- 5e3
vec_a <- rnorm(n)
names(vec_a) <- sample(all_names, n)
vec_b <- rnorm(n)
names(vec_b) <- sample(all_names, n)
length(union(names(vec_a), names(vec_b)))
system.time(tmp1 <- bind_rows(vec_a, vec_b))
system.time(tmp2 <- rbindlist(list(as.list(vec_a), as.list(vec_b)), fill = T))
all.equal(tmp1, tmp2)
The output:
> system.time(tmp1 <- bind_rows(vec_a, vec_b))
user system elapsed
3.20 0.00 3.21
> system.time(tmp2 <- rbindlist(list(as.list(vec_a), as.list(vec_b)), fill = T))
user system elapsed
0.01 0.00 0.01
> all.equal(tmp1, tmp2)
[1] TRUE
Make a list of 2x2 matrices from a list of vectors
How about this? Here, x
is taking the place of your SC_sum
.
x <- split(seq_len(16), gl(4, 4))
x <- lapply(x, `names<-`, letters[1:4])
x
$`1`
a b c d
1 2 3 4
$`2`
a b c d
5 6 7 8
$`3`
a b c d
9 10 11 12
$`4`
a b c d
13 14 15 16
m <- matrix(unlist(x), nrow = length(x[[1]]), ncol = length(x),
dimnames = list(names(x[[1]]), NULL))
m
[,1] [,2] [,3] [,4]
a 1 5 9 13
b 2 6 10 14
c 3 7 11 15
d 4 8 12 16
l <- apply(m, 1, matrix, ncol = 2, simplify = FALSE)
l
$a
[,1] [,2]
[1,] 1 9
[2,] 5 13
$b
[,1] [,2]
[1,] 2 10
[2,] 6 14
$c
[,1] [,2]
[1,] 3 11
[2,] 7 15
$d
[,1] [,2]
[1,] 4 12
[2,] 8 16
If you really want to use lapply
and not apply
, then you can do this:
index <- seq_along(x[[1]])
names(index) <- names(x[[1]])
l <- lapply(index, function(i) matrix(vapply(x, `[[`, 0, i), ncol = 2))
But since your data are fundamentally rectangular, constructing and operating on a matrix is (I think) much more intuitive.
Convert list of vectors into matrix
Have a look at ?do.call
and ?cbind
, e.g:
## create an example list with 3 vectors
l <- list(c(1:3), c(4:6), c(7:9))
## columnwise binding of all vectors in the list `l`
do.call(cbind, l)
Or you could use a simple for
loop:
for (i in seq(along=l)) {
n <- length(l[[i]])
b[seq(n), i] <- l[[i]]
}
How to create a matrix of lists in R?
This builds that matrix although the print method does not display it in the manner you imagined:
matrix( list(c(1,2,4), c(NULL), c(1,2), c(3,4,5,6), c(1), c(1,3)), 2,3)
#---------
[,1] [,2] [,3]
[1,] Numeric,3 Numeric,2 1
[2,] NULL Numeric,4 Numeric,2
Inspect the first element:
> Mlist <- matrix( list(c(1,2,4), c(NULL), c(1,2), c(3,4,5,6), c(1), c(1,3)), 2,3)
> Mlist[1,1]
[[1]]
[1] 1 2 4
> is.matrix(Mlist)
[1] TRUE
> class( Mlist[1,1] )
[1] "list"
Demonstration of creating "matrix of lists" from a list:
> will.become.a.matrix <- list(c(1,2,4), c(NULL), c(1,2), c(3,4,5,6), c(1), c(1,3))
> is.matrix(will.become.a.matrix)
[1] FALSE
> dim(will.become.a.matrix) <- c(2,3)
> is.matrix(will.become.a.matrix)
[1] TRUE
> dim(will.become.a.matrix)
[1] 2 3
> class(will.become.a.matrix[1,1])
[1] "list"
Further requested demonstration:
A<- list(); F=list() E=list()
A[1]<-c(3) ; F[[1]]<-numeric(0); E[[1]]<-numeric(0)
A[2]<-c(1) ; F[2]<-c(1) ; E[2]<-c(1)
A[3]<-c(1) ; F[3]<-c(2) ; E[[3]]<-numeric(0)
A[[4]]<-list(1,3) ;F[[4]]<-numeric(0) ; E[[4]]<-numeric(0)
A[5]<-c(4) ; F[5]<-c(4) ; E[5]<-c(4)
Mlist= c(A,F,E)
M <- matrix(Mlist, length(A), 3)
#=====================================
> M
[,1] [,2] [,3]
[1,] 3 Numeric,0 Numeric,0
[2,] 1 1 1
[3,] 1 2 Numeric,0
[4,] List,2 Numeric,0 Numeric,0
[5,] 4 4 4
You asked (in comments) "....is there a way to define number of column and rows , but not the element itself because they are unknown?"
Answered (initially in comments)
b<-matrix(rep(list(), 6),nrow = 2, ncol =3)
#.... then replace the NULL items with values.
# Need to use "[[": for assignment (which your 'Update 1' did not
# ....and your Update2 only did for some but not all of the assignments.)
b[[1]] <- c(1,2,3,4)
Convert a matrix to a list of column-vectors
In the interests of skinning the cat, treat the array as a vector as if it had no dim attribute:
split(x, rep(1:ncol(x), each = nrow(x)))
How to extract a vector from a list of vectors via matrix in R
You could use paste
:
X[paste0("x", newX[newX != 0])]
$`x4`
[1] 5 6 7
$x7
[1] 3 4 5 6
$x9
[1] 44 56 7
$x10
[1] 34 5 4
paste0("x", newX[newX != 0]
will create the character vector "x4", "x7", "x9", "x10"
which you can use for indexing the list.
Related Topics
Replace Na with Groups Mean in a Non Specified Number of Columns
Plot Size and Resolution with R Markdown, Knitr, Pandoc, Beamer
Remove Rows Where All Variables Are Na Using Dplyr
Colorize Parts of the Title in a Plot
Unnest a List Column Directly into Several Columns
How Can R Loop Over Data Frames
How to Automate Multiple Requests to a Web Search Form Using R
How to Get Ggplot to Order Facets Correctly
When Using Ggplot in R, How to Remove Margins Surrounding the Plot Area
Get All the Rows with Rownames Starting with Abc111
How to Convert a Huge List-Of-Vector to a Matrix More Efficiently
Generating a Vector of Difference Between Two Vectors
Alternatives to Nested Ifelse Statements in R
Programmatically Insert Text, Headers and Lists with R Markdown
How to Display Verbatim Inline R Code with Backticks Using Rmarkdown