Using rbind on matrices in nested lists? - r

I am working in R, and I have a dataset that is a list of lists of matrices. Each sublist in the mainlist has two matrices of equal dimension (10 rows x 2 cols). I would like to rbind() each list of matrices into a single matrix (20 rows x 2 cols). But I do not want to combine every sublist into a single big matrix. Gonna try my best to write a sample code for it but the real data is pretty complex so I'll do my best.
> matrix_1 <- matrix(c(1, 2, 3, 4, 5, 6, 7, 8, 9), nrow = 5, ncol = 2, byrow = TRUE)
> matrix_2 <- matrix(c(9, 8, 7, 6, 5, 4, 3, 2, 1), nrow = 5, ncol = 2, byrow = TRUE)
> matrix_3 <- matrix(c(101, 91, 81, 71, 61, 51, 41, 31, 21, 11), nrow = 5, ncol = 2, byrow = TRUE)
> matrix_4 <- matrix(c(22, 20, 19, 18, 17, 16, 15, 14, 13, 12), nrow = 5, ncol = 2, byrow = TRUE)
> sublist_1 <- list(matrix_1, matrix_2)
[[1]]
[,1] [,2]
[1,] 1 5
[2,] 2 6
[3,] 1 3
[4,] 7 4
[5,] 8 3
[[2]]
[,1] [,2]
[1,] 10 9
[2,] 8 7
[3,] 6 5
[4,] 4 3
[5,] 2 1
> sublist_2 <- list(matrix_3, matrix_4)
[[1]]
[,1] [,2]
[1,] 101 91
[2,] 81 71
[3,] 61 51
[4,] 41 31
[5,] 21 11
[[2]]
[,1] [,2]
[1,] 22 20
[2,] 19 18
[3,] 17 16
[4,] 15 14
[5,] 13 12
> mainlist <- list(sublist_1, sublist_2)
What I really want is to make this:
> rbind(sublist_1[[1]], sublist_1[[2]])
[,1] [,2]
[1,] 1 5
[2,] 2 6
[3,] 1 3
[4,] 7 4
[5,] 8 3
[6,] 10 9
[7,] 8 7
[8,] 6 5
[9,] 4 3
[10,] 2 1
apply to all of the sublists in the mainlist.
I've tried to use various combinations of lapply, mapply, map, do.call, etc. to make it work, but either I don't know the right combinations or I need something else.
I've also noticed that rbind(sublist_1) does not work, which is making it difficult to use lapply. It has to be written as rbind(sublist_1[[1]], sublist_1[[2]]).
Thank you very much for your help.

Loop over the outer list, convert the inner list elements to data.frame and use do.call with rbind
out <- lapply(mainlist, function(x) do.call(rbind, lapply(x, as.data.frame)))

Related

Elegant way to obtain order(rank) of each column of a matrix

I want each element of each column of a matrix to be ranked like one will rank a vector. For instance given that A is a matrix as defined below.
(A = matrix(c(36, 37, 33, 38, 36, 32), nrow = 3, byrow = TRUE))
How do I tell R to get the rank of each column in the matrix A as shown below?
[,1] [,2]
[1,] 36 37
[2,] 33 38
[3,] 36 32
The rank or order is
(rank_A = matrix(c(2.5, 2, 1, 3, 2.5, 1), nrow = 3, byrow = TRUE))
[,1] [,2]
[1,] 2.5 2
[2,] 1.0 3
[3,] 2.5 1
I could have written it as below.
(rank_A <- matrix(rank(A[ ,1]), rank(A[ ,2]), nrow = 3, byrow = FALSE))
which will give me what I want but I wan a elegant way of doing it.
Perhaps you can try this
> apply(A, 2, rank)
[,1] [,2]
[1,] 2.5 2
[2,] 1.0 3
[3,] 2.5 1
We may use colRanks from matrixStats
library(matrixStats)
t(colRanks(A, ties.method = 'average'))
[,1] [,2]
[1,] 2.5 2
[2,] 1.0 3
[3,] 2.5 1
Or using dapply and frank
library(collapse)
library(data.table)
dapply(A, MARGIN = 2, FUN = frank)
[,1] [,2]
[1,] 2.5 2
[2,] 1.0 3
[3,] 2.5 1

How to multiple elements of two lists without using a for loop?

Here is a simple example. How can I perform -a[[ith element]]*b[[ith element]], with i=1:4 without using a for-loop? Thanks so much!
a = list(
c(1, 2),
c(2, 7),
c(5, 3),
c(1, 4))
b = list(
matrix(1:4, 2, 2),
matrix(7:10, 2, 2),
matrix(2:5, 2, 2),
matrix(40:43, 2, 2))
OPERATIONS:
-a[[1]]*b[[1]]
-a[[2]]*b[[2]]
-a[[3]]*b[[3]]
-a[[4]]*b[[4]]
DIMENSION of FINAL OUTPUT: 4 x 2 x2
We could use Map to do elementwise operations between corresponding list elements
Map(`*`, a, b)
-output
[[1]]
[,1] [,2]
[1,] 1 3
[2,] 4 8
[[2]]
[,1] [,2]
[1,] 14 18
[2,] 56 70
[[3]]
[,1] [,2]
[1,] 10 20
[2,] 9 15
[[4]]
[,1] [,2]
[1,] 40 42
[2,] 164 172

Compare columns of 2 matrices to determine the column values in one matrix that should be paired with the other matrix

I have matrix M and N given by
> M
[,1] [,2] [,3] [,4] [,5]
[1,] 5 1 1 7 7
[2,] 4 7 4 2 7
[3,] 11 19 20 50 30
> N
[,1] [,2]
[1,] 7 1
[2,] 7 7
I want to find the column values in M that should be paired with N to get
[,1] [,2]
7 1
7 7
30 19
I tried the code below. Can i get an efficient way of doing it or especially doing it without using the for commands?
E=numeric()
for (i in 1:2){
for (j in 1:5) {
if (N[1,i]==M[1,j] & N[2,i]==M[2,j]){
E[i]= M[3,j]
}
}
}
E
rbind(N,E)
Well here is your loop re-written
E <- vapply(seq(nrow(N)), function(i) M[3,M[1,] == N[1,i] & M[2,] == N[2,i]], numeric(1))
# with
> rbind(N,E)
[,1] [,2]
7 1
7 7
E 30 19
there is only one loop (vapply - a wrapper for a loop) which runs through the rows of N.
Here's a way using multiple calls to apply. We iterate over the columns of M and N to find which column in M matches the first column in N and then which matches the second column in N.
logicals <- apply(M[-3,], # exclude third row
2, # iterate over columns
FUN = function(x)
apply(N, 2, #then iterate over columns of N
FUN = function(y) all(x == y)))
# [,1] [,2] [,3] [,4] [,5]
# [1,] FALSE FALSE FALSE FALSE TRUE
# [2,] FALSE TRUE FALSE FALSE FALSE
M[,apply(logicals, 1, which)]
[,1] [,2]
[1,] 7 1
[2,] 7 7
[3,] 30 19
data
M <- structure(c(5, 4, 11, 1, 7, 19,
1, 4, 20, 7, 2, 50,
7, 7, 30),
.Dim = c(3L, 5L))
N <- structure(c(7, 7, 1, 7), .Dim = c(2L, 2L))

Selecting all the row combinations from a matrix

I have a matrix consisting of 10 rows ,
I would like to make a combination between these row using R such as:
M= matrix(c(
1,2,3,4,
5,6,7,3,
5,5,4,8,
5,2,7,8,
4,8,7,8,
2,6,7,9,
5,6,7,4,
5,6,7,2,
5,6,7,3,
5,6,7,0),nrow=10, byrow=TRUE)
First step
combination (3 row ) from ( 10 row ).
This means that we have other matrices (resulting from matrix M) their number 120- matrix(3*4)
Second step
combination (6 row ) from ( 10 row )
This means that we have other matrices (we also resulting from matrix M) their number 210-matrix(6*4)
You can split matrix with apply to list of rows than use combn function as below:
M <- structure(c(1, 5, 5, 5, 4, 2, 5, 5, 5, 5, 2, 6, 5, 2, 8, 6, 6,
6, 6, 6, 3, 7, 4, 7, 7, 7, 7, 7, 7, 7, 4, 3, 8, 8, 8, 9, 4, 2,
3, 0), .Dim = c(10L, 4L))
x <- apply(M, 1, list)
# combinations for three rows
cmbs3 <- combn(x, 3)
ncol(cmbs3)
# 120
cmbs3[, 2]
# second combination
# [[1]]
# [[1]][[1]]
# [1] 1 2 3 4
#
#
# [[2]]
# [[2]][[1]]
# [1] 5 6 7 3
#
#
# [[3]]
# [[3]][[1]]
# [1] 5 2 7 8
# combinations for six rows
cmbs6 <- combn(x, 6)
ncol(cmbs6)
# 210
EDIT:
Or use elgant solution provided by nicola - subsetting by row index generated by combn (I like it much more :):
lapply(combn(10, 3, simplify = FALSE), function(x) M[x, ])
Output:
[[1]]
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 5 6 7 3
[3,] 5 5 4 8
[[2]]
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 5 6 7 3
[3,] 5 2 7 8
...
[[119]]
[,1] [,2] [,3] [,4]
[1,] 5 6 7 4
[2,] 5 6 7 3
[3,] 5 6 7 0
[[120]]
[,1] [,2] [,3] [,4]
[1,] 5 6 7 2
[2,] 5 6 7 3
[3,] 5 6 7 0

Alternative of reshape () of matlab in R?

I want to implement reshape(X3, [ ], 5) command which i use in matlab in R
I have X3.tif file ( 200 * 150*5)
nrows = 200 ncols= 150 and nbands = 5
I use this command to save tif in datafeame
a <- brick('X3.tif')
X3 is a 3D data but I want to save it as matrix of dimension
[ (200*150) * 5 ]
so that I have ( nbands as number of colums )
If a use :
A <- as.data.frame.matrix(a)
it stores matrix of dimension 200*150 and eliminates the nband =5
Thanks
I think that what you're looking for is this:
#Sample matrix
myMatrix <- matrix(c(1, 2, 3, 4, 5, 6, 7, 8))
myMatrix
[,1]
[1,] 1
[2,] 2
[3,] 3
[4,] 4
[5,] 5
[6,] 6
[7,] 7
[8,] 8
Try this:
myMatrix_new <- matrix(myMatrix, nrow = 2, byrow = TRUE)
myMatrix_new
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 5 6 7 8
Under help ?matrix you can find the arguments nrow, ncol, byrow which allows you to set the number of rows, columns and automatically, if you'd like.

Resources