合并R中两个列表的矩阵

Merge matrices from two lists in R

假设我有两个包含多个矩阵的列表。第一个列表包括维度因矩阵而异的矩阵:

创建列表 1 的代码:

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

列表 1:

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

第二个列表包含始终具有相同维度的矩阵,并且包含 List1 的矩阵中曾经出现的所有情况(6,7 将出现在 list1 的其他矩阵中)。

生成列表 2 的代码:

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

列表 2:

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

我想做的是用 list1 中相应矩阵的值(如果可用)替换 list2 中的 NA,这样结果如下所示:

$`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

我想有一种方法可以通过使用合并命令来实现。但是,我还没有想出任何解决方案,所以非常欢迎任何意见!

使用 Map 的好机会(您的第一个列表中有 data.frame,请先将它们转换为 matrix!):

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

根据@akrun 的建议,一个更通用的解决方案:

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))