在看到(Merge matrices from two lists in R)之前,我问了一个类似的问题。但是,与我之前的问题相反,在这种情况下:
在下文中,您将找到详细的问题:
假设我有两个包含多个矩阵的列表。第一个列表包括尺寸不同于矩阵的矩阵:
创建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,7,4)
p<-data.frame(d,e,f,g)
dimnames(p)<-list(cn,cn)
p<-as.matrix(p)
d<-c(0,0,0,1,1)
e<-c(0,0,1,0,0)
f<-c(0,1,0,0,0)
g<-c(1,0,0,0,0)
h<-c(1,0,0,0,0)
cn<-c(1,5,3,2,4)
q<-data.frame(d,e,f,g,h)
dimnames(q)<-list(cn,cn)
q<-as.matrix(q)
d<-c(0,1,0,1,0,0)
e<-c(1,0,0,0,0,0)
f<-c(0,0,0,0,0,1)
g<-c(1,0,0,0,1,0)
h<-c(0,0,0,1,0,0)
i<-c(0,0,1,0,0,0)
cn<-c(1,2,3,6,8,9)
r<-data.frame(d,e,f,g,h,i)
dimnames(r)<-list(cn,cn)
r<-as.matrix(r)
list1<-list(p,q,r)
names(list1)<-1990:1992
list1的:
$`1990`
1 2 7 4
1 0 1 0 1
2 1 0 0 0
7 0 0 0 0
4 1 0 0 0
$`1991`
1 5 3 2 4
1 0 0 0 1 1
5 0 0 1 0 0
3 0 1 0 0 0
2 1 0 0 0 0
4 1 0 0 0 0
$`1992`
1 2 3 6 8 9
1 0 1 0 1 0 0
2 1 0 0 0 0 0
3 0 0 0 0 0 1
6 1 0 0 0 1 0
8 0 0 0 1 0 0
9 0 0 1 0 0 0
第二个列表包括始终具有相同尺寸的矩阵。 list1中的矩阵可以更小,更大或与list2中的矩阵大小相同。此外,list2中的标准矩阵有时不包含lst1中各个矩阵的所有情况。
生成list2的代码:
o<-matrix(NA,nrow=5,ncol=5)
dimnames(o)<-list(1:5, 1:5)
list2<-list(o,o,o)
names(list2)<-1990:1992
列表2:
$`1990`
1 2 3 4 5
1 NA NA NA NA NA
2 NA NA NA NA NA
3 NA NA NA NA NA
4 NA NA NA NA NA
5 NA NA NA NA NA
$`1991`
1 2 3 4 5
1 NA NA NA NA NA
2 NA NA NA NA NA
3 NA NA NA NA NA
4 NA NA NA NA NA
5 NA NA NA NA NA
$`1992`
1 2 3 4 5
1 NA NA NA NA NA
2 NA NA NA NA NA
3 NA NA NA NA NA
4 NA NA NA NA NA
5 NA NA NA NA NA
我想要做的是用list1中相应矩阵的值替换list2中的NA(如果可用)。 list2中矩阵的维数在此过程中应保持不变。结果应如下所示:
$`1990`
1 2 3 4 5
1 0 1 NA 1 NA
2 1 0 NA 0 NA
3 NA NA NA NA NA
4 1 0 NA 0 NA
5 NA NA NA NA NA
$`1991`
1 2 3 4 5
1 0 1 0 1 0
2 1 0 0 0 0
3 0 0 0 0 1
4 1 0 0 0 0
5 0 0 1 0 0
$`1992`
1 2 3 4 5
1 0 1 0 NA NA
2 1 0 0 NA NA
3 0 0 0 NA NA
4 NA NA NA NA NA
5 NA NA NA NA NA
非常感谢任何帮助!
答案 0 :(得分:3)
Map
仍然是可行的方法,只需更新功能并按colnames
和row.names
对第一个列表进行排序:
list11 = lapply(list1, function(u){
m=data.matrix(u)
m[order(as.integer(row.names(m))),order(as.integer(colnames(m)))]
})
f = function(A,B)
{
A[row.names(A) %in% row.names(B), colnames(A) %in% colnames(B)]=B[row.names(B) %in% row.names(A), colnames(B) %in% colnames(A)]
A
}
Map(f, list2, list11)
#$`1990`
# 1 2 3 4 5
#1 0 1 NA 1 NA
#2 1 0 NA 0 NA
#3 NA NA NA NA NA
#4 1 0 NA 0 NA
#5 NA NA NA NA NA
#$`1991`
# 1 2 3 4 5
#1 0 1 0 1 0
#2 1 0 0 0 0
#3 0 0 0 0 1
#4 1 0 0 0 0
#5 0 0 1 0 0
#$`1992`
# 1 2 3 4 5
#1 0 1 0 NA NA
#2 1 0 0 NA NA
#3 0 0 0 NA NA
#4 NA NA NA NA NA
#5 NA NA NA NA NA
答案 1 :(得分:2)
这是与@Colonel Beauvel的解决方案类似的方法,但match
f1 <- function(x,y) {rInd1 <- match(row.names(x), row.names(y))
rInd2 <- match(row.names(y), row.names(x))
cInd1 <- match(colnames(x), colnames(y))
cInd2 <- match(colnames(y), colnames(x))
x[rInd1[!is.na(rInd1)], cInd1[!is.na(cInd1)]] <-
y[rInd2[!is.na(rInd2)], cInd2[!is.na(cInd2)]]
x}
Map(f1, list2, list1)
# $`1990`
# 1 2 3 4 5
#1 0 1 NA 1 NA
#2 1 0 NA 0 NA
#3 NA NA NA NA NA
#4 1 0 NA 0 NA
#5 NA NA NA NA NA
#$`1991`
# 1 2 3 4 5
#1 0 1 0 1 0
#2 1 0 0 0 0
#3 0 0 0 0 1
#4 1 0 0 0 0
#5 0 0 1 0 0
#$`1992`
# 1 2 3 4 5
#1 0 1 0 NA NA
#2 1 0 0 NA NA
#3 0 0 0 NA NA
#4 NA NA NA NA NA
#5 NA NA NA NA NA