如何通过跳过某些列来查找匹配的行?

时间:2014-07-14 15:49:17

标签: r

假设我有一个向量a,那么

a<-c(0, NA, 1, NA)

和这样的数据框:

set.seed(123)
out1<-data.frame(y1=rbinom(10, 1, 0.3),
                y2=rbinom(10, 1, 0.4),
                y3=rbinom(10, 1, 0.5),
                y4=rbinom(10, 1, 0.6))
out1
   y1 y2 y3 y4
1   0  1  1  0
2   1  0  1  0
3   0  1  1  0
4   1  0  1  0
5   1  0  1  1
6   0  1  1  1
7   0  0  1  0
8   1  0  1  1
9   0  0  0  1
10  0  1  0  1

如何通过跳过column2和column4轻松找到a的匹配行,这样的结果如下:

   y1 y2 y3 y4
1   0  1  1  0
3   0  1  1  0
6   0  1  1  1
7   0  0  1  0

6 个答案:

答案 0 :(得分:1)

这可能不是最漂亮的,但应该有效

idx<-apply(
    out1[, which(!is.na(a)), drop=F] == 
    matrix(na.omit(a), byrow=T, nrow=nrow(out1),  ncol=sum(!is.na(a))),
 1, all)

out1[idx,]

#   y1 y2 y3 y4
# 1  0  1  1  0
# 3  0  1  1  0
# 6  0  1  1  1
# 7  0  0  1  0

我们基本上只从我们想要匹配的列的out1中提取矩阵,然后我们将a的非NA值转换为相同大小的矩阵。然后我们进行矩阵比较,并使用apply查找所有值都为TRUE的行(它们都匹配)。然后我们可以将该逻辑向量用于子集out1

答案 1 :(得分:1)

您可以使用以下内容:

> out1[apply(out1[, c("y1", "y2")], 1, function(x)  all(x==na.omit(a))), ]
   y1 y2 y3 y4
1   0  1  1  0
3   0  1  1  0
6   0  1  1  1
10  0  1  0  1

答案 2 :(得分:1)

您可以使用lapply查找每列的相关匹配项,然后通过intersect获取这些匹配项的Reduce

(m <- Reduce(intersect,lapply(seq_along(a), function(i) if(!is.na(a[i])) which(out1[i]==a[i]) else seq(nrow(out1)))))
[1] 1 3 6 7

out1[m,]
  y1 y2 y3 y4
1  0  1  1  0
3  0  1  1  0
6  0  1  1  1
7  0  0  1  0

答案 3 :(得分:1)

这是另一种方法,使用正则表达式:

a[is.na(a)] <- '.'
out1[grepl(paste(a, collapse='-'), apply(out1, 1, paste, collapse='-')), ]
#   y1 y2 y3 y4
# 1  0  1  1  0
# 3  0  1  1  0
# 6  0  1  1  1
# 7  0  0  1  0

答案 4 :(得分:0)

library(data.table)
a = data.table(y1 = 0, y3 = 1)
out1<-data.table(y1=rbinom(10, 1, 0.3),
             y2=rbinom(10, 1, 0.4),
             y3=rbinom(10, 1, 0.5),
             y4=rbinom(10, 1, 0.6))


setkey(a, y1, y3)
setkey(out1, y1, y3)
x = out1[a]
setcolorder(x, c("y1","y2","y3","y4"))

答案 5 :(得分:0)

作为单行:

out1[c(-2, -4),, drop=FALSE][apply(X=out1[c(-2, -4), !is.na(a)], MARGIN=1, FUN = function(x) all(x==a[!is.na(a)])), , drop=FALSE]