[R如何获得所需使用data.table聚集行和dplyr

问题描述:

假设我们有一个数据集,如:[R如何获得所需使用data.table聚集行和dplyr

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标志,只需取 组中的第一行。

所以,我将得到以下一组:

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 

由于我们只希望过每个DRIVE_NUM第一行:FLAG组合,我们只选择使用group_byslice的第一行开始。然后我们确保我们安排了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)) 
+0

哦,没错。它测试了他们的数据并得到了正确的结果,但不知何故错过了。它仍然有效,因为将使用字母顺序。 – Axeman

+1

是的,非常好。谢谢。我倾向于忘记which.min'取第一个值。 – Axeman

+0

请参阅我的更新。 – John