基于多列的值,从R中的数据表中删除行

6
我有一个数据表格(data.table)在R中,其中包含多个ID和一个值。对于每个ID组合,都有几行数据。如果这些行中的任何一行在“value”列中包含NA,则我想删除所有具有此ID组合的行。例如,在下面的表中,我想删除所有满足id1 == 2id2 == 1的行。
如果我只有一个ID,我会执行dat[!(id1 %in% dat[is.na(value),id1])]。在示例中,这将删除所有i1 == 2的行。但是,我无法包括多个列。
dat <- data.table(id1 = c(1,1,2,2,2,2),
                  id2 = c(1,2,1,2,3,1),
                  value = c(5,3,NA,6,7,3))

2
尝试使用 dat[!(id1==2 & id2==1)] 或者 setkey(dat, id1, id2)[!J(2,1) ] - akrun
我知道这在上面的简单示例中可以工作。然而,问题的意图更为一般,因为可能有大量带有NAs的行。 - lilaf
1
我认为他正在寻找 dat[, if(all(!is.na(value))) .SD, .(id1, id2)] - David Arenburg
1
@DavidArenburg:这就是我在寻找的,谢谢! - lilaf
@lilaf 好的,刚才看到关于 NA 的那部分。 我的评论是基于“我想删除所有id1 == 2且id2 == 1的行。” - akrun
1
@akrun,无论如何感谢您的回答,下次我会尽量表达更清楚。 - lilaf
1个回答

4

如果您想要检查每个 id1id2 的组合是否有任何一个值为 NA,并且然后删除该整个组合,您可以在每个组中插入一个 if 语句,并且仅当该语句返回 TRUE 时检索结果 (使用 .SD)。

dat[, if(!anyNA(value)) .SD, by = .(id1, id2)]
#    id1 id2 value
# 1:   1   1     5
# 2:   1   2     3
# 3:   2   2     6
# 4:   2   3     7

或类似地,
dat[, if(all(!is.na(value))) .SD, by = .(id1, id2)]

dat 拆分为所有 .SD 并将它们堆叠起来可能是代价高昂的。另一种替代方法(也许通常更快?)是选择要保留的行 dat[dat[,!any(is.na(value)),by="id1,id2"]$V1] - Frank
啊,你说得对。我确实进行了测试,但不知怎么地,我自己说服了自己所看到的是正确答案。我应该提到的另一种选择是:dat[dat[,.I[!any(is.na(value))],by="id1,id2"]$V1] - Frank
1
@Frank,那也是一个不错的选择。 - David Arenburg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接