首页 > 解决方案 > R:使用 dplyr 删除 data.frame 中的某些行

问题描述

dat <- data.frame(ID = c(1, 2, 2, 2), Gender = c("Both", "Both", "Male", "Female"))
> dat
  ID Gender
1  1   Both
2  2   Both
3  2   Male
4  2 Female

对于每个 ID,如果 Gender 是BothMaleFemale,我想删除带有 的行Both。也就是说,我想要的数据是这样的:

  ID Gender
1  1   Both
2  2   Male
3  2 Female

我试图通过使用下面的代码来做到这一点:

library(dplyr)
> dat %>% 
  group_by(ID) %>% 
  mutate(A = ifelse(length(unique(Gender)) >= 3 & Gender == 'Both', F, T)) %>% 
  filter(A) %>% 
  select(-A)

# A tibble: 2 x 2
# Groups:   ID [1]
     ID Gender
  <dbl> <fctr>
1     2   Male
2     2 Female

我声明了一个名为 的虚拟变量AA = F如果对于给定的ID,所有 3 个元素Gender都存在(“Both”、“Male”和“Female”;这些是Gender可以采用的不同值,不可能有其他值)并且对应的行有Gender == Both。然后我将删除该行。

但是,似乎我正在分配A = F第一行,即使它Gender只是“Both”,而不是“Both”、“Male”和“Female”?

标签: rdataframedplyr

解决方案


按'ID'分组后,创建一个逻辑条件,其中'Gender'不是'Both'并且distinct'Gender'中元素的长度为3,即'Male','Female','Both'(如OP所述没有其他值)或 ( |) 如果元素的数量只有 1

dat %>% 
  group_by(ID) %>% 
  filter((Gender != "Both" & n_distinct(Gender)==3)| n() ==1 )
# A tibble: 3 x 2
# Groups:   ID [2]
#    ID Gender
#  <dbl> <fct> 
#1     1 Both  
#2     2 Male  
#3     2 Female

或者另一种选择是

dat %>%
   group_by(ID) %>% 
   filter(Gender %in% c("Male", "Female")| n() == 1)
# A tibble: 3 x 2
# Groups:   ID [2]
#     ID Gender
#  <dbl> <fct> 
#1     1 Both  
#2     2 Male  
#3     2 Female

推荐阅读