合并来自R中两个列表的矩阵

时间:2015-01-27 17:37:24

标签: r list matrix merge

假设我有两个包含多个矩阵的列表。第一个列表包括尺寸不同于矩阵的矩阵:

创建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

第二个列表包括总是具有相同维度的矩阵,并包括List1矩阵中出现的所有情况(6,7将出现在list1的其他矩阵中)。

生成list2的代码:

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

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

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

我想有一种方法可以使用merge命令来完成此操作。但是,我还没有想出任何解决方案,所以非常欢迎任何意见!

1 个答案:

答案 0 :(得分:5)

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