背景问题:
假设我们有一个类似于以下数据集的数据:
ID DRIVE_NUM FLAG
1 A PASS
2 A FAIL
3 A PASS
-----------------
4 B PASS
5 B PASS
6 B PASS
-----------------
7 C PASS
8 C FAIL
9 C FAIL
我希望按照以下规则通过DRIVE_NUM对数据集进行聚合:
对于特定的DRIVE_NUM组,
如果DRIVE_NUM组中存在FAIL标志,则取第一行带有FAIL标志的数据。
如果DRIVE_NUM组中不存在FAIL标志,则取该组中的第一行数据。
因此,我将得到以下数据集:
ID DRIVE_NUM FLAG
2 A FAIL
4 B PASS
8 C FAIL
更新:
看起来dplyr的解决方案甚至比plyr还要慢。我是否在使用中有什么不当之处?
#Simulate Data
X = data.frame(
group = rep(paste0("NO",1:10000),each=2),
flag = sample(c("F","P"),20000,replace = TRUE),
var = rnorm(20000)
)
library(plyr)
library(dplyr)
#plyr
START = proc.time()
X2 = ddply(X,.(flag),function(df) {
if( sum(df$flag=="F")> 0){
R = df[df$flag=="F",]
if(nrow(R)>1) {R = R[1,]} else {R = R}
} else{
R = df[1,]
}
R
})
proc.time() - START
#user system elapsed
#0.03 0.00 0.03
#dplyr method 1
START = proc.time()
X %>%
group_by(group) %>%
slice(which.min(flag))
proc.time() - START
#user system elapsed
#0.22 0.02 0.23
#dplyr method 2
START = proc.time()
X %>%
group_by(group, flag) %>%
slice(1) %>%
group_by(group) %>%
slice(which.min(flag))
proc.time() - START
#user system elapsed
#0.28 0.00 0.28
有没有比plyr更快的data.table版本?
slice
比较慢,是吗?我记得有人评论过这个。 - akrunsystem.time({Z = X[order(X$flag),]; res = with(Z, Z[tapply(seq(nrow(X)), group, head, 1), ])})
。与 .SD[1L] 的方法类似。 - Frank