我有一个包含汽车修理数据的数据框。它还告诉我汽车是否发生故障(并得到修复)。我想在汽车发生故障后摆脱所有带修理事件的行。
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)
以下是使用split
和lapply
的解决方案,数据准备与问题中的相同:
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.table
和dplyr
有类似但更快的解决方案。
答案 1 :(得分: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
或ave
base 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
答案 2 :(得分:0)
可能有更优雅的方式,但lapply
和do.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