如果至少一个组成员符合条件,则从data.frame中删除组 [英] Remove group from data.frame if at least one group member meets condition

查看:76
本文介绍了如果至少一个组成员符合条件,则从data.frame中删除组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个data.frame,如果其中的任何成员都满足条件,我想删除整个组.

在第一个示例中,如果值是数字且条件为NA,则下面的代码有效.

df <- structure(list(world = c(1, 2, 3, 3, 2, NA, 1, 2, 3, 2), place = c(1, 
1, 2, 2, 3, 3, 1, 2, 3, 1), group = c(1, 1, 1, 2, 2, 2, 3, 
3, 3, 3)), .Names = c("world", "place", "group"), row.names = c(NA, 
-10L), class = "data.frame")

ans <- ddply(df, . (group), summarize, code=mean(world))
ans$code[is.na(ans$code)] <- 0
ans2 <- merge(df,ans)
final.ans <- ans2[ans2$code !=0,]

但是,如果条件不是"NA",或者该值不是数字,则使用NA值进行的ddply操作将不起作用.

例如,如果我要删除具有 world 值为AF的成员的任何组(如下面的data.frame中所示),此ddply技巧将不起作用.

df2 <-structure(list(world = structure(c(1L, 2L, 3L, 3L, 3L, 5L, 1L, 
4L, 2L, 4L), .Label = c("AB", "AC", "AD", "AE", "AF"), class = "factor"), 
    place = c(1, 1, 2, 2, 3, 3, 1, 2, 3, 1), group = c(1, 
    1, 1, 2, 2, 2, 3, 3, 3, 3)), .Names = c("world", "place", 
"group"), row.names = c(NA, -10L), class = "data.frame")

我可以设想一个for循环,其中检查每个组的每个成员的值,如果满足条件,则可以填充code列,然后可以根据该代码创建一个子集. /p>

但是,也许有矢量化的r方法可以做到这一点?

解决方案

尝试

library(dplyr)
df2 %>%
  group_by(group) %>%
  filter(!any(world == "AF"))

或按照@akrun的建议:

setDT(df2)[, if(!any(world == "AF")) .SD, group]

setDT(df2)[, if(all(world != "AF")) .SD, group]

哪个给:

#Source: local data frame [7 x 3]
#Groups: group
#
#  world place group
#1    AB     1     1
#2    AC     1     1
#3    AD     2     1
#4    AB     1     3
#5    AE     2     3
#6    AC     3     3
#7    AE     1     3

I have a data.frame where I'd like to remove entire groups if any of their members meets a condition.

In this first example, if the values are numbers and the condition is NA the code below works.

df <- structure(list(world = c(1, 2, 3, 3, 2, NA, 1, 2, 3, 2), place = c(1, 
1, 2, 2, 3, 3, 1, 2, 3, 1), group = c(1, 1, 1, 2, 2, 2, 3, 
3, 3, 3)), .Names = c("world", "place", "group"), row.names = c(NA, 
-10L), class = "data.frame")

ans <- ddply(df, . (group), summarize, code=mean(world))
ans$code[is.na(ans$code)] <- 0
ans2 <- merge(df,ans)
final.ans <- ans2[ans2$code !=0,]

However, this ddply maneuver with the NA values will not work if the condition is something other than "NA", or if the value are non-numeric.

For example, if I wanted to remove any groups which had a member with a world value of AF (as in the data.frame below) this ddply trick would not work.

df2 <-structure(list(world = structure(c(1L, 2L, 3L, 3L, 3L, 5L, 1L, 
4L, 2L, 4L), .Label = c("AB", "AC", "AD", "AE", "AF"), class = "factor"), 
    place = c(1, 1, 2, 2, 3, 3, 1, 2, 3, 1), group = c(1, 
    1, 1, 2, 2, 2, 3, 3, 3, 3)), .Names = c("world", "place", 
"group"), row.names = c(NA, -10L), class = "data.frame")

I can envision a for-loop where for each group the value of each member is checked, and if the condition is met a code column could be populated, and then a subset could me made based on that code.

But, perhaps there is a vectorized, r way to do this?

解决方案

Try

library(dplyr)
df2 %>%
  group_by(group) %>%
  filter(!any(world == "AF"))

Or as per metionned by @akrun:

setDT(df2)[, if(!any(world == "AF")) .SD, group]

Or

setDT(df2)[, if(all(world != "AF")) .SD, group]

Which gives:

#Source: local data frame [7 x 3]
#Groups: group
#
#  world place group
#1    AB     1     1
#2    AC     1     1
#3    AD     2     1
#4    AB     1     3
#5    AE     2     3
#6    AC     3     3
#7    AE     1     3

这篇关于如果至少一个组成员符合条件,则从data.frame中删除组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆