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!
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.
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.
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.
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.
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))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With