我希望在匹配变量的数量等于数字的条件下对我的数据帧进行子集化,例如
example <- rbind(sample(letters[1:5]),
sample(letters[1:5]),
sample(letters[1:5]),
sample(letters[1:5]),
sample(letters[1:5]))
example
[,1] [,2] [,3] [,4] [,5]
[1,] "b" "a" "d" "e" "c"
[2,] "e" "c" "a" "d" "b"
[3,] "c" "a" "d" "b" "e"
[4,] "b" "d" "e" "c" "a"
[5,] "b" "c" "e" "d" "a"
如果我希望我的匹配变量数为3,则会选择最后两行,因为它们共有3个字母(相同的位置和相同的字母)。
答案 0 :(得分:2)
创建可重现的数据
set.seed(47)
example <- rbind(sample(letters[1:5]),
sample(letters[1:5]),
sample(letters[1:5]),
sample(letters[1:5]),
sample(letters[1:5]))
example
# [,1] [,2] [,3] [,4] [,5]
#[1,] "e" "b" "c" "d" "a"
#[2,] "d" "b" "e" "c" "a"
#[3,] "a" "c" "e" "b" "d"
#[4,] "e" "b" "a" "c" "d"
#[5,] "a" "c" "b" "e" "d"
我能想到的一种方法是使用双循环
n <- 3
example[sapply(apply(example, 1, function(x)
which(colSums(x == t(example)) >= n)), length) > 1, ]
# [,1] [,2] [,3] [,4] [,5]
#[1,] "a" "c" "e" "b" "d"
#[2,] "a" "c" "b" "e" "d"
在这里,我们将每一行与每一行进行比较,如果它等于或大于阈值(n
),则按元素计算并计算相等比较的数量。另一个循环是过滤掉与自身相等的行。
答案 1 :(得分:0)
另一种方法是使用combn
两次,首先枚举对,然后再进行成对比较。
使用ronak-shah的例子,
combn(seq_len(nrow(example)), 2)[, combn(seq_len(nrow(example)), 2,
FUN=function(x) sum(example[x[1],] == example[x[2],]) >= 3)]
[1] 3 5
表示要保留的行。
这通常会返回一个矩阵,并且可以重复这组行。例如,将阈值设置为2,我们得到
[,1] [,2] [,3] [,4]
[1,] 1 1 2 3
[2,] 2 4 4 5
要将其转化为有用的内容,请使用c
将结果转换为向量,然后unique
删除重复的行。当我们处于这种状态时,我们也可以将整个事物包装成一个允许选择阈值的函数。
rowKeeper <- function(myMat, thresh) {
myMat[unique(c(combn(seq_len(nrow(myMat)), 2)[,
combn(seq_len(nrow(example)), 2,
FUN=function(x) sum(myMat[x[1],] == myMat[x[2],]) >= thresh)])),]
}
然后尝试一下
rowKeeper(example, 3)
[,1] [,2] [,3] [,4] [,5]
[1,] "a" "c" "e" "b" "d"
[2,] "a" "c" "b" "e" "d"