检查矩阵中至少有 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)
对是所需的输出。
假设我有一个如下所示的矩阵:
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)
对是所需的输出。