如何 select 行比较具有相同值的多个列?

How to select rows comparing multiple columns with the same value?

假设我有以下数据和一个列名向量

dt <- data.table(id = letters[1:10], amount = 1:10, id2 = c(rep('a',5),rep('b',5)),test=rep('a',10))
cols <- c('id','id2','test')

我想要做的是 select 行,其中向量中的所有列都具有相同的特定值,例如

dt[id=='a' & id2=='a' & test == 'a']

但使用矢量 cols。有办法吗?

注意: 我需要找到一种使用 data.tablebase R 的方法,而无需在

等列之间进行比较
dt[id==id2 & id==test & id2==test]

使用 dplyrpurrr,您可以:

dt %>%
    filter(reduce(.x = across(all_of(cols), ~ . == "a"), .f = `&`))

   id amount id2 test
1:  a      1   a    a

或使用 data.table 的相同想法:

dt[dt[, Reduce(`&`, lapply(.SD, function(x) x == "a")), .SDcols = cols]]

你可以求助于.SDcols -

library(data.table)

dt[dt[, rowSums(.SD == 'a') == length(cols), .SDcols = cols]]

#   id amount id2 test
#1:  a      1   a    a

这也可以写成-

dt[rowSums(dt[, ..cols] == 'a') == length(cols), ]

使用if_all

library(dplyr)
dt %>%
    filter(if_all(all_of(cols), ~ . == 'a'))
   id amount id2 test
1:  a      1   a    a

这是一个 data.table 友好的解决方案,它不寻找文字 "a":

此辅助函数仅采用其参数的 table,如果不同元素的数量不是“1”,则采用 returns TRUE。 (我测试 2L 因为我使用 useNA="always",它总是会附加一个 NA 计数,即使是 0。)

allsame <- function(x) do.call(mapply, c(list(FUN = function(...) length(table(unlist(list(...)), useNA = "always")) == 2L), x))

从这里开始,您可以在外部或内部使用它:

dt[allsame(dt[,..cols]),]
#        id amount    id2   test
#    <char>  <int> <char> <char>
# 1:      a      1      a      a

它实际上不是 data.table 特定的,它可以处理任何东西,只要它的参数是一个 data.frame 类对象,包含您需要比较的所有评论。

mtcars[1:3,10:11]
#               gear carb
# Mazda RX4        4    4
# Mazda RX4 Wag    4    4
# Datsun 710       4    1

allsame(mtcars[1:3,10:11])
# [1]  TRUE  TRUE FALSE

另一个选项是使用连接:

dt[as.list(rep('a', length(cols))), on=cols]