如何在data.table中实现dplyr的ifelse(any(startsWith)逻辑?
解决dplyr转data.table的行级条件判断问题
问题分析
原dplyr代码核心是按行检查所有Tag列,完成三个操作:
- 优先标记Position为"Goalkeeper"(若有Tag为"goalkeeper"),其次为"Striker"(若有Tag为"striker")
- 标记Favorite为TRUE(若有Tag为"favorite")
- 清除Tag列中指定的关键词,替换为NA
你的尝试中主要问题:
- 直接引用
Tag列名(不存在该列),未正确指定所有Tag列集合 any()默认对整列而非行判断,需要用行级统计逻辑grepl("striker", "^Tag")用法错误,未针对列值判断
完整正确的data.table代码
library(data.table) # 构造示例数据 df <- data.table( Name = c("A", "B"), Tag1 = c("goalkeeper", NA), Tag2 = c(NA, "striker"), Tag3 = c(NA, "favorite") ) # 获取所有Tag列名 tag_cols <- grep("^Tag", names(df), value = TRUE) # 1. 生成Position列:优先匹配goalkeeper,其次striker df[, Position := fcase( rowSums(.SD == "goalkeeper", na.rm = TRUE) > 0, "Goalkeeper", rowSums(.SD == "striker", na.rm = TRUE) > 0, "Striker", default = NA_character_ ), .SDcols = tag_cols] # 2. 生成Favorite列:判断是否有favorite标签 df[, Favorite := rowSums(.SD == "favorite", na.rm = TRUE) > 0, .SDcols = tag_cols] # 3. 清理Tag列中的指定关键词 df[, (tag_cols) := lapply(.SD, function(x) fifelse(x %in% c("goalkeeper", "striker", "favorite"), NA_character_, x)), .SDcols = tag_cols] # 查看结果(可选,保留Name/Position/Favorite列) df[, .(Name, Position, Favorite)]
代码说明
tag_cols:通过正则匹配获取所有以Tag开头的列,避免硬编码列名rowSums(.SD == "xxx", na.rm = TRUE) > 0:高效实现行级判断,统计每行中匹配关键词的数量(忽略NA),大于0即表示该行存在该关键词fcase:data.table的多条件判断函数,比嵌套ifelse更简洁高效fifelse:data.table版的ifelse,性能优于基础包的ifelse
输出结果
Name Position Favorite 1: A Goalkeeper FALSE 2: B Striker TRUE
内容的提问来源于stack exchange,提问作者user165426
相关产品推荐
相关产品推荐

