【问题标题】:Populate matrix by colname identity按 colname 标识填充矩阵
【发布时间】:2019-09-21 21:25:13
【问题描述】:

我有很多样本,每个样本都有一个对应的丰度矩阵。从这些丰度矩阵中,我想创建一个大矩阵,其中包含行中每个样本的丰度信息。

例如,单个丰度矩阵如下所示:

           A  B  C  D 
sample1    1  3  4  2

其中 A、B、C 和 D 代表列名,丰度是行值。

我想通过匹配 colname 值来填充我的较大矩阵,该矩阵将所有可能的字母 (A:Z) 和所有可能的样本 (sample1:sampleN) 作为行名。

例如。 :

         A  B  C  D  E  F  G ....  Z
sample1  1  3  4  2  NA NA NA ....
sample2  NA NA 2  5  7  NA NA ....
sample3  4  NA 6  9  2  NA 2 .....
....
sampleN

不同的样品有不同的丰度组合,没有保证的顺序。

当迭代地添加到这个更大的矩阵时,我如何确保正确的列填充了正确的丰度值(例如,列“A”仅由与不同样本中“A”丰度对应的值填充)?谢谢!

【问题讨论】:

  • Darth_Vedar,我并不着急(甚至假设我的内容是你应该接受的),但你没有接受任何关于你之前问题的答案。如果答案解决了您的问题,请accept it;这样做不仅为回答者提供了一些积分,而且还为有类似问题的读者提供了一些关闭。尽管您只能接受一个答案,但您可以选择对您认为有帮助的人进行投票。 (如果仍有问题,您可能需要编辑您的问题并提供更多详细信息。)

标签: r matrix matching


【解决方案1】:

起始数据,稍作改动以突出差异:

m1 <- as.matrix(read.table(header=TRUE, text="
           A  B  C  Z
sample1    1  3  4  2"))
m2 <- as.matrix(read.table(header=TRUE, text="
         A  B  C  D  E  F  G
sample2  NA NA 2  5  7  NA NA
sample3  4  NA 6  9  2  NA 2"))

首先,我们需要确保两个矩阵具有相同的列名:

newcols <- setdiff(colnames(m2), colnames(m1))
m1 <- cbind(m1, matrix(NA, nr=nrow(m1), nc=length(newcols), dimnames=list(NULL, newcols)))
newcols <- setdiff(colnames(m1), colnames(m2))
m2 <- cbind(m2, matrix(NA, nr=nrow(m2), nc=length(newcols), dimnames=list(NULL, newcols)))

m1
#         A B C Z  D  E  F  G
# sample1 1 3 4 2 NA NA NA NA
m2
#          A  B C D E  F  G  Z
# sample2 NA NA 2 5 7 NA NA NA
# sample3  4 NA 6 9 2 NA  2 NA

现在我们将它们结合起来;常规 cbind 也需要对齐列名:

rbind(m2, m1[,colnames(m2),drop=FALSE])
#          A  B C  D  E  F  G  Z
# sample2 NA NA 2  5  7 NA NA NA
# sample3  4 NA 6  9  2 NA  2 NA
# sample1  1  3 4 NA NA NA NA  2

【讨论】:

    【解决方案2】:

    您应该能够利用矩阵索引,如下所示:

    big[cbind(rownames(abun),colnames(abun))] <- abun
    

    使用此示例abundance 矩阵和big 矩阵来填充:

    abun <- matrix(c(1,3,4,2),nrow=1,dimnames=list("sample1",LETTERS[1:4]))
    big <- matrix(NA,nrow=5,ncol=26,dimnames=list(paste0("sample",1:5),LETTERS))
    

    【讨论】:

      【解决方案3】:

      使用来自purrr 包的reduce 和来自dplyr 包的union_all 的另一种解决方案:

      library(purrr)
      library(dplyr)
      
      sample_names <- c("sample1","sample2","sample3")
      

      生成 3 个随机丰度数据框:

      num1 <- round(runif(runif(1,min = 1, max = 10),min = 1, max = 10))
      df1 <- data.frame(t(num1))
      colnames(df1) <- sample(LETTERS,length(num1))
      
      num2 <- round(runif(runif(1,min = 1, max = 10),min = 1, max = 10))
      df2 <- data.frame(t(num2))
      colnames(df2) <- sample(LETTERS,length(num2))
      
      num3 <- round(runif(runif(1,min = 1, max = 10),min = 1, max = 10))
      df3 <- data.frame(t(num3))
      colnames(df3) <- sample(LETTERS,length(num3))
      

      这实际上是发挥所有魔力的代码:

      A <- reduce(list(df1,df2,df3),union_all)
      col_order <- sort(colnames(A),decreasing = FALSE)
      A <- A[,col_order]
      rownames(A) <- sample_names
      

      输出:

      > A
               A  C  E  F  O  P  Q  U  W  Y
      sample1  9 NA NA NA  9 NA  5  6 NA NA
      sample2 NA NA NA NA  5  4 NA NA  5 NA
      sample3 NA  6  5  9 NA NA  3 NA  5  7
      

      【讨论】:

        猜你喜欢
        • 2020-04-19
        • 2020-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-22
        • 2016-10-28
        • 2018-09-20
        • 2010-10-15
        相关资源
        最近更新 更多