使用 %in% 对数据 Table 进行子集化

Subsetting a Data Table using %in%

我的 data.table 的程式化版本是

outmat <- data.table(merge(merge(1:5, 1:5, all=TRUE), 1:5, all=TRUE))

我想要做的是 select 根据第一列中的值是否在任何其他列中找到的 select 来自此 data.table 的行子集(它将处理未知维度的矩阵,所以我不能只使用某种 "row1 == row2 | row1 == row3"

我想用

来做到这一点
output[row1 %in% names(output)[-1], ]

但如果在 row2 或 row3 的任何行中找到 row1 中的值,这将最终返回 TRUE,这不是预期的行为。是否有某种矢量化版本的 %in% 可以达到我想要的结果?

具体来说,我想得到的是集合 1:5 中的三元组的枚举,通过替换绘制,使得第一个值与第二个或第三个值相同,有些东西喜欢:

1 1 1
1 1 2
1 1 3
1 1 4
1 1 5
...
2 1 2
2 2 1
...
5 5 5

我的代码给我的是 3 元组的每个枚举,因为它正在检查第一个数字(比如 5)是否曾经出现在第二或第三列的任何地方,而不仅仅是在同一行中。

一种选择是构造表达式并对其求值:

dt = data.table(a = 1:5, b = c(1,2,4,3,1), c = c(4,2,3,2,2), d = 5:1)
#   a b c d
#1: 1 1 4 5
#2: 2 2 2 4
#3: 3 4 3 3
#4: 4 3 2 2
#5: 5 1 2 1

expr = paste(paste(names(dt)[-1], collapse = paste0(" == ", names(dt)[1], " | ")),
             "==", names(dt)[1])
#[1] "b == a | c == a | d == a"

dt[eval(parse(text = expr))]
#   a b c d
#1: 1 1 4 5
#2: 2 2 2 4
#3: 3 4 3 3

另一种选择是循环遍历并比较列:

dt[rowSums(sapply(dt, '==', dt[[1]])) > 1]
#   a b c d
#1: 1 1 4 5
#2: 2 2 2 4
#3: 3 4 3 3
library(dplyr)
library(tidyr)

dt %>%
  mutate(ID = 1:n() )
  gather(variable, value, -first_column, -ID) %>%
  filter(first_column == value) %>%
  select(ID) %>%
  distinct %>%
  left_join(dt)