假设我们有一个类似的数据集:
X = data.frame(
ID = 1:9,
DRIVE_NUM = c("A","A","A","B","B","B","C","C","C"),
FLAG =c("PASS","FAIL","PASS","PASS","PASS","PASS","PASS","FAIL","FAIL")
)
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标志,只需取出第一行 基。
所以,我将得到以下内容:
wanted = data.frame(
ID = c(2,4,8),
DRIVE_NUM = c("A","B","C"),
FLAG = c("FAIL","PASS","FAIL")
)
ID DRIVE_NUM FLAG
2 A FAIL
4 B PASS
8 C FAIL
现在我可以使用ddply来完成它,但由于我的数据集通常很大,所以它非常慢。
有没有办法使用data.table或dplyr。
更新
似乎dplyr甚至比plyr慢。有没有办法比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
答案 0 :(得分:2)
由于我们只想要每个DRIVE_NUM
:FLAG
组合的第一行,我们首先选择使用group_by
和slice
的第一行。然后我们确保按FLAG
进行排列,如果有FAIL
它将是DRIVE_NUM
的顶行,但如果只有PASS
,那么没有什么变化。然后我们再次slice
选择该第一行。
library(dplyr)
X %>%
group_by(DRIVE_NUM, FLAG) %>%
slice(1) %>%
group_by(DRIVE_NUM) %>%
slice(which.min(FLAG))
@Frank基本上解决了这个问题,依赖which.min
取第一个值(第一行)。
X %>%
group_by(DRIVE_NUM) %>%
slice(which.min(FLAG))