2014-01-29 31 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。