对于具有大于零的值的所有ID,删除ID等于零的行。

时间:2016-11-11 17:41:11

标签: r dataframe

我有一个像这样的数据框

ID <- c("A","A","A","B","B","C","D")
Value <- c(0,1,2,0,2,0,0)
df <- data.frame(ID,Value)
df

我正在尝试应用逻辑,如果任何ID的值大于0,那么我需要用0删除该ID的那一行。

我想要的输出是

  ID Value
   A     1
   A     2
   B     2
   C     0
   D     0

我试过这样做

df <- subset(df,df$Value !=0)

我知道这是错误的,因为它删除了任何带有0的ID。请帮助解决一些如何解决此问题的输入

3 个答案:

答案 0 :(得分:3)

您可以使用ave(),首先将Value列强制转换为逻辑,以便out out结果将用于子集化。我们使用if()语句来确定要保留的值。

df[with(df, ave(as.logical(Value), ID, FUN = function(x) if(any(x)) x else !x)), ]
#   ID Value
# 2  A     1
# 3  A     2
# 5  B     2
# 6  C     0
# 7  D     0

或与subset()相同。

subset(df, ave(as.logical(Value), ID, FUN = function(x) if(any(x)) x else !x))
#   ID Value
# 2  A     1
# 3  A     2
# 5  B     2
# 6  C     0
# 7  D     0

答案 1 :(得分:2)

香草的方式:

# get ids with values greater than 0
delete_zero = unique(subset(df, Value > 0)$ID)

# delete the rows where the ID is in delete_zero AND the value is 0
df2 = subset(df, !(ID %in% delete_zero & Value == 0))

df2
#   ID Value
# 2  A     1
# 3  A     2
# 5  B     2
# 6  C     0
# 7  D     0

新奇的方式:相同的逻辑,但我们用dplyr“按组”

进行
library(dplyr)
df %>% group_by(ID) %>%
    filter(!(any(Value > 0) & Value == 0))

# Source: local data frame [5 x 2]
# Groups: ID [4]
# 
#       ID Value
#   <fctr> <dbl>
# 1      A     1
# 2      A     2
# 3      B     2
# 4      C     0
# 5      D     0

答案 2 :(得分:2)

dplyr方法:

library(dplyr)
df %>% group_by(ID) %>% filter(if (all(Value==0)) TRUE else Value > 0)
Source: local data frame [5 x 2]
Groups: ID [4]

      ID Value
  <fctr> <dbl>
1      A     1
2      A     2
3      B     2
4      C     0
5      D     0