如何将dplyr筛选全逻辑列TRUE的代码转换为data.table实现?
用data.table筛选所有逻辑列全为TRUE的行
背景场景
先看初始数据:通过以下R代码创建data.table对象dt:
library(data.table) library(dplyr) dt <- data.table( A = c(TRUE, TRUE, TRUE), B = c(TRUE, FALSE, TRUE), C = c(FALSE, TRUE, TRUE) )
dt的输出为:
A B C 1: TRUE TRUE FALSE 2: TRUE FALSE TRUE 3: TRUE TRUE TRUE
用dplyr可以通过if_all快速筛选出所有逻辑列值均为TRUE的行,代码及结果如下:
dt |> dplyr::filter(if_all(where(is.logical)))
输出:
A B C 1: TRUE TRUE TRUE
下面介绍用data.table实现相同筛选逻辑的几种方式。
data.table实现方案
方式一:利用.SD和all()函数
借助data.table的.SD(Subset of Data)特性,结合.SDcols自动筛选逻辑列,直接判断每行是否所有逻辑列值都为TRUE:
dt[, .SD[all(.SD), .SDcols = is.logical]]
这里.SDcols = is.logical会自动识别所有逻辑类型的列,all(.SD)检查当前行的所有逻辑列值是否全为TRUE,满足条件的行将被保留。
方式二:通过rowSums统计判断
用数值统计的思路,计算每行逻辑列中TRUE的数量,当数量等于逻辑列总数时,说明该行全为TRUE:
# 先获取所有逻辑列的名称 logical_cols <- names(dt)[sapply(dt, is.logical)] # 筛选符合条件的行 dt[dt[, rowSums(.SD) == length(.SD), .SDcols = logical_cols]]
方式三:用Reduce做逐行逻辑与运算
通过Reduce把所有逻辑列的向量逐行做逻辑与(&)运算,最终得到的布尔向量就是筛选条件:
# 标记哪些列是逻辑类型 is_logical_col <- sapply(dt, is.logical) # 筛选满足所有逻辑列都是TRUE的行 dt[Reduce(`&`, dt[, ..is_logical_col])]
..is_logical_col用于引用外部定义的列索引,Reduce(&, ...)会把每一行的所有逻辑列值做“且”运算,只有全为TRUE时结果才为TRUE。
以上三种方式的最终输出结果均与dplyr实现的一致:
A B C 1: TRUE TRUE TRUE
内容的提问来源于stack exchange,提问作者Rodrigo Tanco
相关产品推荐
相关产品推荐

