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

时间:2015-02-03 10:42:41

标签: r list matrix

在看到(Merge matrices from two lists in R)之前,我问了一个类似的问题。但是,与我之前的问题相反,在这种情况下:

  1. 我在list1中有一些矩阵,它们的大小比list2中的标准矩阵小,大或相同。
  2. list1中的某些矩阵包含未包含在list2中的个案。
  3. 在下文中,您将找到详细的问题:

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

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

    非常感谢任何帮助!

2 个答案:

答案 0 :(得分:3)

Map仍然是可行的方法,只需更新功能并按colnamesrow.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