2017-07-04 74 views
1

我有一個數據幀與汽車修復數據。它還告訴我一輛車是否發生故障(並得到修理)。汽車發生故障後,我想擺脫修理事件的所有行。刪除某些沒有循環的行

Car <- c('A','A','B') 
Damage <-c("Wheels","Motor","Motor") 
date <-c('01-01-2015','01-01-2016','01-01-2016') 
Broke_down <-c(1,0,1) 

df <- as.data.frame(cbind(Car,date,Damage,Broke_down)) 

基本上,我想刪除了車後的虛擬爲1

因此,在這種情況下,輸出將不得不發生的所有行:

"Car"  "date"   "Damage"  "Broke_down" 
A   01-01-2015  Wheels   1 
B   01-01-2016  Motor   1 

最佳, 菲利克斯

+0

你的例子選擇不好,因爲它很容易用一種更簡單的方法解決,雖然這對其他情況是不正確的。示例數據的更好選擇將防止太簡單的解決方案 –

回答

2

下面是使用splitlapply的解決方案,數據準備與問題中的相同:

df2 <- do.call(
    rbind, 
    lapply(
    split(df, df$Car), 
    function(x){ 
     x[1:which.min(x$Broke_down==1), ] 
    }) 
) 

說明:
split給出data.frames
lapply清單適用於它的第二個參數的函數,並返回結果的
終於do.call電話rbind與給你造成的data.frames列表中的一個長data.frame列表再次。

使用data.tabledplyr有類似但更快的解決方案。

+1

也許'which.min'而不是'min(which(...))'? (+1) –

+0

感謝您的建議,我相應地改變了答案。 – snaut

1

基於在OP的帖子更新

library(data.table) 
setDT(df)[, .SD[cummin(Broke_down) > 0], Car] 
# Car  date Damage Broke_down 
#1: A 01-01-2015 Wheels   1 
#2: B 01-01-2016 Motor   1 

或者與avebase R

df[with(df, ave(Broke_down, Car, FUN = cummin) > 0),] 
# Car  date Damage Broke_down 
#1 A 01-01-2015 Wheels   1 
#3 B 01-01-2016 Motor   1 
0

有可能是一個更優雅的方式,但lapplydo.call做的伎倆:

df_out <- do.call(rbind,lapply(unique(df$Car),function(x){ 

    df_sub <- df[df$Car==x,] 
    df_sub[1:which(df_sub$Broke_down == 1)[1],] 

})) 

> df_out 
    Car  date Damage Broke_down 
1 A 01-01-2015 Wheels   1 
3 B 01-01-2016 Motor   1