我有一个如下数据框
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中简单快速的代码可以解决问题吗?
答案 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