2014-01-29 28 views
6

我有像下面消除其具有不同的值

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组,它不具有相同的值。它varys与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中解决该问题简单而快速的代码?

+1

你做了什么来尝试解决这个问题? – John

+0

我使用了我检查的答案。 –

+0

我翻译此文与韩国开发者分享[ctrlaltdel](http://ctrlaltdel.co。kr) –

回答

3

您可以选择使用sampleave许多不同的方式进行。

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,] 
1

这里有一个方法

> 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 
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如果数据是数字的替代,是检查我F中的方差为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 
+0

@RicardoSaporta - 我记得与mnel [here](http://stackoverflow.com/a/18304851/496803)讨论使用'if'会稍快或更有效。我不记得为什么。 – thelatemail

+0

我没有想过这件事,而且这很有道理!使用'if'将呼叫保存到'.SD' –

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。