Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merge matrices from two lists in R

Tags:

merge

list

r

matrix

Suppose I have two lists that include several matrices. The first list includes matrices with dimensions that differ from matrix to matrix:

Code to create list1:

d<-c(0,1,0,1)
e<-c(1,0,0,0)
f<-c(0,0,0,0)
g<-c(1,0,0,0)
cn<-c(1,2,3,4)
p<-data.frame(d,e,f,g)
dimnames(p)<-list(cn,cn)

d<-c(0,1,0,1,0)
e<-c(1,0,0,0,0)
f<-c(0,0,0,0,0)
g<-c(1,0,0,0,1)
h<-c(0,0,0,1,0)
cn<-c(1,2,3,4,5)
q<-data.frame(d,e,f,g,h)
dimnames(q)<-list(cn,cn)

list1<-list(p,q)
names(list1)<-1990:1991

List1:

list1

$`1990`
  1 2 3 4
1 0 1 0 1
2 1 0 0 0
3 0 0 0 0
4 1 0 0 0

$`1991`
  1 2 3 4 5
1 0 1 0 1 0
2 1 0 0 0 0
3 0 0 0 0 0
4 1 0 0 0 1
5 0 0 0 1 0

The second list includes matrices that always have the same dimensions and include all cases that ever occur in the matrices of List1 (6,7 would occur in additional matrices in list1).

Code to produce list2:

o<-matrix(NA,nrow=7,ncol=7)
dimnames(o)<-list(1:7, 1:7)
list2<-list(o,o)
names(list2)<-1990:1991

List2:

list2
$`1990`
   1  2  3  4  5  6  7
1 NA NA NA NA NA NA NA
2 NA NA NA NA NA NA NA
3 NA NA NA NA NA NA NA
4 NA NA NA NA NA NA NA
5 NA NA NA NA NA NA NA
6 NA NA NA NA NA NA NA
7 NA NA NA NA NA NA NA

$`1991`
   1  2  3  4  5  6  7
1 NA NA NA NA NA NA NA
2 NA NA NA NA NA NA NA
3 NA NA NA NA NA NA NA
4 NA NA NA NA NA NA NA
5 NA NA NA NA NA NA NA
6 NA NA NA NA NA NA NA
7 NA NA NA NA NA NA NA

What I would like to do is to replace the NA's in list2 with, if available, the values from the respective matrix from list1, so that the result looks like this:

$`1990`
   1  2  3  4  5  6  7
1  0  1  0  1 NA NA NA
2  1  0  0  0 NA NA NA
3  0  0  0  0 NA NA NA
4  1  0  0  0 NA NA NA
5 NA NA NA NA NA NA NA
6 NA NA NA NA NA NA NA
7 NA NA NA NA NA NA NA

$`1991`
   1  2  3  4  5  6  7
1  0  1  0  1  0  NA NA
2  1  0  0  0  0  NA NA
3  0  0  0  0  0  NA NA
4  1  0  0  0  1  NA NA
5  0  0  0  1  0  NA NA
6  NA NA NA NA NA NA NA
7  NA NA NA NA NA NA NA

I suppose there is a way to do this by using the merge command. However, I have not figured any solution out yet, so any input is highly welcome!

like image 324
jsts Avatar asked Jan 27 '15 17:01

jsts


People also ask

How do I combine two matrices in R?

To combine two or more matrices in R, we use the following functions: rbind() : Used to add the matrices as rows. cbind() : Used to add the matrices as columns.

How do you combine two matrices?

Concatenating Matrices You can also use square brackets to append existing matrices. This way of creating a matrix is called concatenation. For example, concatenate two row vectors to make an even longer row vector. To arrange A and B as two rows of a matrix, use the semicolon.

How do I combine multiple lists into one in R?

Two or more R lists can be joined together. For that purpose, you can use the append , the c or the do. call functions. When combining the lists this way, the second list elements will be appended at the end of the first list.

What is a list explain the concept of lists in R with examples?

In R, lists are the second type of vector. Lists are the objects of R which contain elements of different types such as number, vectors, string and another list inside it. It can also contain a function or a matrix as its elements. A list is a data structure which has components of mixed data types.


1 Answers

Good opportunity to use Map (you have data.frame in your first list, convert them in matrix first!):

lst1 = lapply(list1, data.matrix)

> Map(function(m,p) {m[1:nrow(p),1:ncol(p)]=p;m}, list2, lst1)
$`1990`
   1  2  3  4  5  6  7
1  0  1  0  1 NA NA NA
2  1  0  0  0 NA NA NA
3  0  0  0  0 NA NA NA
4  1  0  0  0 NA NA NA
5 NA NA NA NA NA NA NA
6 NA NA NA NA NA NA NA
7 NA NA NA NA NA NA NA

$`1991`
   1  2  3  4  5  6  7
1  0  1  0  1  0 NA NA
2  1  0  0  0  0 NA NA
3  0  0  0  0  0 NA NA
4  1  0  0  0  1 NA NA
5  0  0  0  1  0 NA NA
6 NA NA NA NA NA NA NA
7 NA NA NA NA NA NA NA

As per @akrun suggestion, a more generalist solution:

f = function(A,B)
{
    A[row.names(A) %in% row.names(B), colnames(A) %in% colnames(B)]=B
    A
}

Map(f, list2, lapply(list1, data.matrix))
like image 89
Colonel Beauvel Avatar answered Nov 15 '22 08:11

Colonel Beauvel