如何获取Data.table中不符合双列非空条件的Name列取值?
获取不符合筛选条件的Name分组取值解决方案
嘿,我明白你的需求了:你不想筛选掉行,而是要找出所有Name分组——要么组里至少有一行不满足Value和Value1同时为非NA,要么整个组里完全没有满足这个条件的行。在你的示例里,就是要得到A和B这两个值对吧?
先梳理下你的原始场景:
原始数据与原有代码
首先是你的原始数据框(我把它整理成可直接运行的代码了):
df <- data.frame( Name = c("A", "A", "A", "A", "A", "B", "B", "B", "B", "C", "C"), Value = c(1, NA, 1, 1, 1, NA, NA, 1, 1, 1, 1), Value1 = c(2, 2, 2, 2, 2, 1, 2, NA, NA, 5, 5), C1 = rep(NA, 11), C2 = c(NA, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), C3 = rep(NA, 11) ) library(data.table) dt <- as.data.table(df)
你之前用这段代码筛选出了Value和Value1均为非NA的行:
new <- dt[is.na(`Value`) == FALSE & is.na(`Value1`) == FALSE,]
得到的结果是:
Name Value Value1 C1 C2 C3 1: A 1 2 NA NA NA 2: A 1 2 NA 2 NA 3: A 1 2 NA 2 NA 4: A 1 2 NA 2 NA 5: C 1 5 NA 2 NA 6: C 1 5 NA 2 NA
实现需求的代码
要拿到你想要的Name列表,我们可以按Name分组,逐个检查每个分组的情况,用data.table可以这样写:
# 按Name分组,计算两个关键指标 target_names <- dt[, .( # 分组内是否存在至少一行不满足Value和Value1均非NA has_bad_rows = any(is.na(Value) | is.na(Value1)), # 分组内所有行都不满足Value和Value1均非NA all_bad_rows = all(is.na(Value) | is.na(Value1)) ), by = Name][has_bad_rows | all_bad_rows, Name] # 查看结果 target_names
运行这段代码后,输出就是你想要的:
[1] "A" "B"
代码逻辑解释
any(is.na(Value) | is.na(Value1)):判断当前Name分组里,有没有至少一行是Value为NA 或者Value1为NA的(也就是不符合筛选条件的行),对应示例里的A分组all(is.na(Value) | is.na(Value1)):判断当前Name分组里,所有行都不符合筛选条件,对应示例里的B分组- 最后我们筛选出满足
has_bad_rows | all_bad_rows的Name值,就是目标结果啦
内容的提问来源于stack exchange,提问作者bli12blu12
相关产品推荐
相关产品推荐

