3

这可能是重复的,但我使用了各种不同的关键字试图找到答案,但都失败了。我想要做的是从数据框中删除跨多个列的所有不匹配实例:

id = c(1,1,1,2,2,3,3,4,5,5)
type = c("a", "a", "b", "b", "b", "a", "b", "b", "a", "a")
df = data.frame(id,type)


   id type

1   1    a
2   1    a
3   1    b
4   2    b
5   2    b
6   3    a
7   3    b
8   4    b
9   5    a
10  5    a

在这种情况下,我只想保留每个 ID 中完全匹配的行,所以我的输出应该是

    id type
4   2    b
5   2    b
8   4    b 
9   5    a
10  5    a   

提前感谢任何可以帮助我的人!

4

3 回答 3

4

假设你ids是完整的和连续的,这应该只使用基本 R 很好地工作:

ids = which(tapply(df$type, df$id, function(x) length(unique(x))==1)
subset(df, id %in% ids)

如果不是,这应该可以代替它:

ids = unique(df$id)[which(tapply(df$type, df$id, function(x) length(unique(x))==1)]

我倾向于更喜欢data.table这些情况:

dt = data.table(df)
dt[,if(length(unique(type))==1) .SD, by=id]
于 2013-10-04T21:46:27.373 回答
3

另一种ave选择:

df[ave(as.numeric(df$type), df$id, FUN = function(x) length(unique(x))) == 1, ]
于 2013-10-04T22:16:46.747 回答
1

这是另一个plyr,但data.table解决方案肯定更优雅:

ddply(df, "id", function(d) {
    if (identical(levels(factor(d$type)),levels(df$type))) NULL else d
})
于 2013-10-04T21:52:45.083 回答