使用R的data.table逐行判断列值是否存在于同行其他列
正确实现data.table逐行检查列值是否存在于当前行其他列中
问题分析
你需要的是逐行检查当前行的col1值是否存在于同一行的指定列(col2、col3)中,现有代码的问题在于:
get("col1") %in% .SD是将col1的值与整个.SD(所有行的col2、col3数据)做匹配,而非仅当前行的对应列值- 另一种错误结果是跨行匹配,只要其他行存在目标值就标记为1,不符合逐行检查的需求
正确实现方法
方法1:使用rowSums逐行判断
利用rowSums统计当前行col1与col2、col3的匹配次数,只要次数大于0就标记为1:
library(data.table) dt <- data.table( id = c(1, 2, 3, 4), col1 = c("A", "B", "C", "D"), col2 = c("E", "F", "G", "H"), col3 = c("A", "J", "A", "B") ) cols_to_search <- c("col2", "col3") dt[, check := as.integer(rowSums(.SD == col1) > 0), .SDcols = cols_to_search]
运行结果:
> dt id col1 col2 col3 check 1: 1 A E A 1 2: 2 B F J 0 3: 3 C G A 0 4: 4 D H B 0
方法2:使用Reduce逐行合并逻辑
通过Reduce将每行的多列匹配结果合并,实现逻辑判断:
library(data.table) dt <- data.table( id = c(1, 2, 3, 4), col1 = c("A", "B", "C", "D"), col2 = c("E", "F", "G", "H"), col3 = c("A", "J", "A", "B") ) cols_to_search <- c("col2", "col3") dt[, check := as.integer(Reduce(`|`, lapply(.SD, function(x) x == col1))), .SDcols = cols_to_search]
方法3:使用pmap逐行处理(灵活扩展场景)
如果需要处理空值、多条件等复杂场景,可结合purrr::pmap实现逐行遍历:
library(data.table) library(purrr) dt <- data.table( id = c(1, 2, 3, 4), col1 = c("A", "B", "C", "D"), col2 = c("E", "F", "G", "H"), col3 = c("A", "J", "A", "B") ) cols_to_search <- c("col2", "col3") dt[, check := as.integer(pmap_lgl(.SD, ~ col1 %in% c(..1, ..2))), .SDcols = cols_to_search]
原理说明
上述方法均针对当前行的列值进行比较,而非整个数据集的列:
rowSums(.SD == col1)逐行计算col1与目标列的匹配数量,大于0则说明当前行存在匹配Reduce通过逻辑或运算,合并每行多列的匹配结果pmap则直接逐行传入目标列的值,进行行内的存在性判断
内容的提问来源于stack exchange,提问作者Ren
相关产品推荐
相关产品推荐

