哪些组包含值 - 更优雅的代码?

时间:2015-06-23 20:59:50

标签: r

如果组中的一个成员包含特定值,我正试图找到一种更优雅的方法来提取数据帧的所有行。例如:

id <- c(1,1,2,2,2,3,4,4,5,5)
cat <- c("A", "B", "A", "B", "C", "B", "C", "D", "A", "E")
mydf <- data.frame(id, cat)

id cat
1   A
1   B
2   A
2   B
2   C
3   B
4   C
4   D
5   A
5   E

我想创建一个新的数据框,其中所有行来自包含C的ID,在这种情况下,来自id 2和id 4的所有行,而不仅仅是那些包含C的行。

我已经这样做了,但我认为必须有一种更优雅的方式来做到这一点而不创建2个额外的列:

mydf$isC <- ifelse(cat=="C", TRUE, FALSE) 
library(dplyr)
newdf <- mydf %>%
  group_by(id) %>%
  mutate(
   hasC = ifelse(any(isC), TRUE, FALSE)
  ) %>%
  filter(hasC)

2 个答案:

答案 0 :(得分:3)

这样的东西?

subset(mydf, id %in% id[cat=="C"])
##   id cat
## 3  2   A
## 4  2   B
## 5  2   C
## 7  4   C
## 8  4   D

或非非交互式使用,

mydf[mydf$id %in% mydf$id[mydf$cat == "C"],]

答案 1 :(得分:2)

尝试

library(dplyr)
mydf%>% 
    group_by(id) %>% 
    filter( any(cat=='C'))
#   id cat
#1  2   A
#2  2   B
#3  2   C
#4  4   C
#5  4   D

或者,如果您需要删除&#39; C&#39;在所选的群组中,使用& cat!= 'C'

mydf%>% 
   group_by(id) %>% 
   filter( any(cat=='C')& cat!='C')
#  id cat
#1  2   A
#2  2   B
#3  4   D

或使用data.table

library(data.table)
setDT(mydf)[,.SD[any(cat=='C') & cat!='C'] , id]
#   id cat
#1:  2   A
#2:  2   B
#3:  4   D