根据具有两个属性的列子集数据框

时间:2017-04-11 18:59:10

标签: r data.table dplyr

说我有数据框

ds <- read.table(header = TRUE, text ="
                 g1 color
                 A red
                 A yellow
                 B red
                 C red
                 C yellow
                 ")

所以我希望子集一个新的数据帧,它只包含g1中具有列颜色“红色”和“黄色”的组。使用上面示例的新表将不包含任何包含B的行。我不知道如何处理此问题,因为使用红色或黄色的子设置仍将包含仅具有红色的“B”。

ds[ds$color=="red" | ds$color=="yellow", ] 

感谢。

3 个答案:

答案 0 :(得分:2)

使用dplyr,您可以使用简单的group_by()filter()

ds %>% group_by(g1) %>% filter(all(c("red","yellow") %in% color))

这将允许您想要匹配的任意数量的值。

答案 1 :(得分:1)

你可以这样做:

ds$col.count <- ave(as.integer(ds$color), ds$g1, FUN=function(x) length(unique(x)))
ds[ds$col.count==2,]

一个简短的变体是:

ds[as.logical(ave(as.integer(ds$color), ds$g1, FUN=function(x) 2==length(unique(x)))), ]

需要as.integer(),因为ave()适用于数字向量,因为as.logical()的结果是数字向量,所以需要ave()

以下是data.table的解决方案:

library(data.table)
ds <- fread(header = TRUE, 
"g1 color
 A red
 A yellow
 B red
 C red
 C yellow")
ds[, col.count:=length(unique(color)), by=g1][col.count==2]

如果很清楚,在每个组中每种颜色不能两次,那么您可以简单地执行:

ds[, col.count := .N, by = g1][col.count == 2]

答案 2 :(得分:0)

这是一个带有ave

的冗长的基本R方法
ds[as.logical(ave(as.character(ds$color), ds$g1, 
                  FUN=function(i) "red" %in% i & "yellow" %in% i)), ]
  g1  color
1  A    red
2  A yellow
4  C    red
5  C yellow