如果语句删除行

yni*_*Sed 4 group-by r filter dplyr

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

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
Run Code Online (Sandbox Code Playgroud)

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

Status  ID 
  B     1
  B     1
  B     1
  A     2
  A     2
  A     2
  A     2
  B     3
  B     3
  B     3
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,唯一改变的是组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))))
Run Code Online (Sandbox Code Playgroud)

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

Ron*_*hah 5

我们可以使用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
Run Code Online (Sandbox Code Playgroud)

我们也可以使用 n_distinct

df %>%
  group_by(ID) %>%
  filter(n_distinct(Status) == 1 | Status == "B")
Run Code Online (Sandbox Code Playgroud)

等价的基础R ave版本将是

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"))), ]
Run Code Online (Sandbox Code Playgroud)


小智 5

首先,始终建议以复制友好格式提供示例,dput(df1)以便其他人可以轻松地重新生成数据.

这个任务可以通过创建一个标志列来实现,该标志列指示a ID是否有多个Status,然后过滤那些没有多个status或有多个的那个status == "B".如下:

clean_df1 <- df1 %>%
  group_by(ID) %>%
  mutate(multiple = if_else(n_distinct(Status) > 1, TRUE, FALSE)) %>%
  filter(!multiple | Status == "B") %>%
  ungroup() %>% select(- multiple)
# A tibble: 10 x 2
   Status    ID
   <fct>  <dbl>
 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
Run Code Online (Sandbox Code Playgroud)