检查矩阵中至少有 2 列至少有 3 个值...但它们必须在同一行(用于成对测试)

Check that at least 2 columns in a matrix have at least 3 values... But they have to be in the same rows (for pairwise test)

假设我有一个如下所示的矩阵:

set.seed(123)
newmat=matrix(rnorm(25),ncol=5)
colnames(newmat)=paste0('mark',1:5)
rownames(newmat)=paste0('id',1:5)
newmat[,2]=NA
newmat[c(2,5),4]=NA
newmat[c(1,4,5),5]=NA
newmat[1,1]=NA
newmat[5,3]=NA

> newmat
          mark1 mark2     mark3      mark4      mark5
id1          NA    NA 1.2240818  1.7869131         NA
id2 -0.23017749    NA 0.3598138         NA -0.2179749
id3  1.55870831    NA 0.4007715 -1.9666172 -1.0260044
id4  0.07050839    NA 0.1106827  0.7013559         NA
id5  0.12928774    NA        NA         NA         NA

我想在这里以简单的方式检查的唯一一件事是至少有 2 列具有 3 个值,而且这些列的值在同一行中...

在上面的例子中,我有一对第 1 列和第 3 列满足这个条件,还有一对第 3 列和第 4 列......第 1 列和第 4 对不满足这个条件。总共3列。

我如何在 R 中执行此检查?我知道我会做一些涉及 colSums(!is.na(newmat)) 但不确定其余部分的事情...谢谢!

这是一种方法。

首先,创建所有可能的列对的数据框,不包括 self-pairings:

pairs <- expand.grid(a = colnames(newmat), b = colnames(newmat))
pairs <- pairs[pairs$a != pairs$b,]

现在,对于此数据框中的每一行,使用列 a 和 b 中的条目从 newmat 中提取相关列。计算每个列对中非NA的条目数,并将其作为列存储在pairs中。这一切都可以通过 apply 调用来完成:

pairs$matches <- apply(pairs, 1, function(row) {
  sum(!is.na(newmat[,row[1]]) & !is.na(newmat[,row[2]]))
  })

现在过滤掉 pairs 中少于 3 个匹配项的行:

pairs <- pairs[pairs$matches > 2,]

现在 pairs 看起来像这样:

pairs
#>        a     b matches
#> 3  mark3 mark1       3
#> 11 mark1 mark3       3
#> 14 mark4 mark3       3
#> 18 mark3 mark4       3

如果我们取消列出前两列,找到所有唯一值并对它们进行排序,我们就有了一个包含我们想要的列名的向量,所以我们用它来对矩阵进行子集化以删除冗余列:

newmat[,sort(unique(as.character(unlist(pairs[1:2]))))]
#>           mark1     mark3      mark4
#> id1          NA 1.2240818  1.7869131
#> id2 -0.23017749 0.3598138         NA
#> id3  1.55870831 0.4007715 -1.9666172
#> id4  0.07050839 0.1106827  0.7013559
#> id5  0.12928774        NA         NA

这是一个矩阵(通过使用 crossprod + is.na 获得),显示哪些对满足您的 objective

> `diag<-`(crossprod(!is.na(newmat)), 0) >= 3
      mark1 mark2 mark3 mark4 mark5
mark1 FALSE FALSE  TRUE FALSE FALSE
mark2 FALSE FALSE FALSE FALSE FALSE
mark3  TRUE FALSE FALSE  TRUE FALSE
mark4 FALSE FALSE  TRUE FALSE FALSE
mark5 FALSE FALSE FALSE FALSE FALSE

如我们所见,(mark1, mark3)(mark3, mark4) 对是所需的输出。