我有一个如下数据框
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中的简单快速代码能解决问题吗?
这是使用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的组.
您可以制作一个选择器以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)
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)