首页 > 解决方案 > 删除行 if 语句

问题描述

我有一个看起来像这样的数据框:

Status  ID 
  A     1
  B     1
  B     1
  A     1
  B     1
  A     1
  A     2
  A     2
  A     2
  A     2
  B     3
  B     3
  B     3

为了说明我想要的输出,请看下面:

Status  ID 
  B     1
  B     1
  B     1
  A     2
  A     2
  A     2
  A     2
  B     3
  B     3
  B     3

如您所见,唯一改变的是组 ID = 1。如果一个组同时包含“A”和“B”状态,我想删除“A”状态。

但是,组 ID 2 和 3 没有改变(即没有删除行),因为:如果每个组 ID 只包含一个“A”,那么它将保持不变。同样,如果每个组 ID 只包含一个“B”,它也将保持不变。因此两者保持不变。

使用 dplyr,这是我的尝试:

library(dplyr)

df1_clean <- df1 %>% group_by(ID, Status)
                 %>% filter(ifelse((Status == A | Status == B), Status == B,
                     ifelse((Status == A), Status == A,
                     ifelse((Status == B), Status == B))))

但是,此过滤器将不起作用。任何帮助,将不胜感激!

标签: rfiltergroup-bydplyr

解决方案


我们可以使用filter分组ID

library(dplyr)
df %>%
  group_by(ID) %>%
  filter(all(Status == "A") | all(Status == "B") | Status == "B")

#   Status    ID
#   <fct>  <int>
# 1 B          1
# 2 B          1
# 3 B          1
# 4 A          2
# 5 A          2
# 6 A          2
# 7 A          2
# 8 B          3
# 9 B          3
#10 B          3

我们也可以使用n_distinct

df %>%
  group_by(ID) %>%
  filter(n_distinct(Status) == 1 | Status == "B")

等效的基本 Rave版本将是

df[as.logical(with(df, ave(Status, ID, FUN = function(x) 
          all(x == "A") | all(x == "B") | x == "B"))), ]

df[as.logical(with(df, ave(Status, ID, FUN = function(x) 
         length(unique(x)) == 1 | x == "B"))), ]

推荐阅读