消除具有不同值的组

时间:2014-01-29 02:41:35

标签: r dataframe

我有一个如下数据框

sample <- data.frame(ID=1:9, Group=c('AA','AA','AA','BB','BB','CC','CC','BB','CC'), Value = c(1,1,1,2,2,2,3,2,3))

每组应该具有相同的值。

ID       Group    Value
1        AA       1
2        AA       1
3        AA       1
4        BB       2
5        BB       2
6        CC       2
7        CC       3
8        BB       2
9        CC       3

如果查看CC组,它的值不同。它变化为2和3。

我需要消除没有唯一价值的群体。

在上述情况下,必须删除CC组。 结果应如下所示

ID       Group    Value
1        AA       1
2        AA       1
3        AA       1
4        BB       2
5        BB       2
8        BB       2

你能告诉我R中简单快速的代码可以解决问题吗?

4 个答案:

答案 0 :(得分:6)

这是使用dplyr的解决方案:

library(dplyr)

sample <- data.frame(
  ID = 1:9,  
  Group= c('AA', 'AA', 'AA', 'BB', 'BB', 'CC', 'CC', 'BB', 'CC'),  
  Value = c(1, 1, 1, 2, 2, 2, 3, 2, 3)
)

sample %>%
  group_by(Group) %>%
  filter(n_distinct(Value) == 1)

我们按Group对数据进行分组,然后仅选择Value的不同值数为1的组。

答案 1 :(得分:5)

data.table版本:

library(data.table)
sample <- as.data.table(sample)
sample[,if(length(unique(Value))==1) .SD ,by=Group]

#   Group ID Value
#1:    AA  1     1
#2:    AA  2     1
#3:    AA  3     1
#4:    BB  4     2
#5:    BB  5     2
#6:    BB  8     2

如果数据是数字,则使用ave的替代方法是检查方差是否为0:

sample[with(sample, ave(Value, Group, FUN=var ))==0,]

可以更快地处理大数据的替代解决方案是:

setkey(sample, Group, Value)
ans <- sample[unique(sample)[, .N, by=Group][N==1, Group]]

重点是,当有更多组时,计算每个组的unique值可能会非常耗时。相反,我们可以在data.table上设置密钥,然后按密钥(非常快)获取unique值,然后计算每个组的总值。然后我们只需要那些1.然后我们可以执行join(再次非常快)。这是大数据的基准:

require(data.table)
set.seed(1L)
sample <- data.table(ID=1:1e7, 
        Group = sample(rep(paste0("id", 1:1e5), each=100)), 
        Value = sample(2, 1e7, replace=TRUE, prob=c(0.9, 0.1)))

system.time (
    ans1 <- sample[,if(length(unique(Value))==1) .SD ,by=Group]
)
# minimum of three runs
#   user  system elapsed 
# 14.328   0.066  14.382 

system.time ({
    setkey(sample, Group, Value)
    ans2 <- sample[unique(sample)[, .N, by=Group][N==1, Group]]
})
# minimum of three runs
#   user  system elapsed 
#  5.661   0.219   5.877 

setkey(ans1, Group, ID)
setkey(ans2, Group, ID)
identical(ans1, ans2) # [1] TRUE

答案 2 :(得分:4)

您可以使用sample许多不同的方式为ave制作选择器。

sample[ ave( sample$Value, sample$Group, FUN = function(x) length(unique(x)) ) == 1,]

sample[ ave( sample$Value, sample$Group, FUN = function(x) sum(x - x[1]) ) == 0,]

sample[ ave( sample$Value, sample$Group, FUN = function(x) diff(range(x)) ) == 0,]

答案 3 :(得分:2)

这是一种方法

> ind <- aggregate(Value~Group, FUN=function(x) length(unique(x))==1, data=sample)[,2]
> sample[sample[,"Group"] %in% levels(sample[,"Group"])[ind], ]
  ID Group Value
1  1    AA     1
2  2    AA     1
3  3    AA     1
4  4    BB     2
5  5    BB     2
8  8    BB     2