消除具有不同值的组

Kei*_*ark 7 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))
Run Code Online (Sandbox Code Playgroud)

每组应该具有相同的值.

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
Run Code Online (Sandbox Code Playgroud)

如果您查看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
Run Code Online (Sandbox Code Playgroud)

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

had*_*ley 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)
Run Code Online (Sandbox Code Playgroud)

我们将数据分组Group,然后仅选择其中不同值的数量Value为1的组.


Joh*_*ohn 5

您可以制作一个选择器以sample使用ave多种不同的方式。

sample[ ave( sample$Value, sample$Group, FUN = function(x) length(unique(x)) ) == 1,]
Run Code Online (Sandbox Code Playgroud)

或者

sample[ ave( sample$Value, sample$Group, FUN = function(x) sum(x - x[1]) ) == 0,]
Run Code Online (Sandbox Code Playgroud)

或者

sample[ ave( sample$Value, sample$Group, FUN = function(x) diff(range(x)) ) == 0,]
Run Code Online (Sandbox Code Playgroud)


the*_*ail 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
Run Code Online (Sandbox Code Playgroud)

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

sample[with(sample, ave(Value, Group, FUN=var ))==0,]
Run Code Online (Sandbox Code Playgroud)

对大数据更快的替代解决方案是:

setkey(sample, Group, Value)
ans <- sample[unique(sample)[, .N, by=Group][N==1, Group]]
Run Code Online (Sandbox Code Playgroud)

关键是unique当有更多组时,计算每个组的值可能是耗时的.相反,我们可以设置密钥data.table,然后unique按键获取值(速度非常快),然后计算每个组的总值.然后我们只需要那些它是1.然后我们可以执行a 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
Run Code Online (Sandbox Code Playgroud)