1
假設我們有一個數據集,如:[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
哦,沒錯。它測試了他們的數據並得到了正確的結果,但不知何故錯過了。它仍然有效,因爲將使用字母順序。 – Axeman
是的,非常好。謝謝。我傾向於忘記which.min'取第一個值。 – Axeman
請參閱我的更新。 – John