我有一个看起来像这样的数据框:
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))))
但是,此过滤器将不起作用。任何帮助将不胜感激!
答案 0 :(得分: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
我们也可以使用n_distinct
df %>%
group_by(ID) %>%
filter(n_distinct(Status) == 1 | Status == "B")
等效的基本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"))), ]
答案 1 :(得分:5)
首先,始终建议使用dput(df1)
以易于复制的格式给出示例,以便其他人可以轻松地重新生成数据。
此任务可以通过创建一个标志列来完成,该标志列指示ID
是否具有多个Status
,然后过滤不具有多个status
或具有{{1 }}。如下:
status == "B"