我的数据包含三个变量,其中包含三个唯一ID,每个变量都有多个记录。见下文
ID <- c(rep(1,7), rep(2,6), rep(3,5), rep(4,6))
t <- c(seq(1,7), seq(1,6), seq(1,5), rep(2,6))
y <- c(rep(6,7), rep(1,6), rep(6,5), rep(0.2,6))
z <- c(5,0,0,0,1,0,0,0,0,-1,0,0,0,4,2,NaN,0,1,0,0,1,Inf,Inf, Inf)
dat1 <- data.frame(ID, t, y, z)
对于每个ID,如果z的值低于0(负数),NaN,Inf或-Inf,我需要排除该记录及其下面的所有记录。
对于此数据,新处理的数据如下所示:
ID <- c(rep(1,7), rep(2,2), rep(3,2), rep(4,3))
t <- c(seq(1,7), seq(1,2), seq(1,2), rep(2,3))
y <- c(rep(6,7), rep(1,2), rep(6,2), rep(0.2,3))
z <- c(5,0,0,0,1,0,0,0,0,4,2,0,0,1)
dat2 <- data.frame(ID, t, y, z)
答案 0 :(得分:6)
cumsum
,作为分组代替。使用dat1[with(dat1, ave(z < 0 | (!is.finite(z)), ID, FUN=cumsum) == 0),]
计数器然后标识要删除的任何后续行:
all.equal(
dat2,
dat1[with(dat1, ave(z < 0 | (!is.finite(z)), ID, FUN=cumsum) == 0),],
check.attributes=FALSE
)
#[1] TRUE
快速检查以查看它们是否匹配,但rownames除非排队:
Connection Refused
答案 1 :(得分:2)
如果您的ID
列按升序排序,则可以使用
dat2 <- dat1[unlist(tapply(dat1$z, dat1$ID, function(x)
cumsum(x<0 | x %in% c(NaN, -Inf, Inf))==0)),]
dat2
ID t y z
1 1 1 6.0 5
2 1 2 6.0 0
3 1 3 6.0 0
4 1 4 6.0 0
5 1 5 6.0 1
6 1 6 6.0 0
7 1 7 6.0 0
8 2 1 1.0 0
9 2 2 1.0 0
14 3 1 6.0 4
15 3 2 6.0 2
19 4 2 0.2 0
20 4 2 0.2 0
21 4 2 0.2 1
答案 2 :(得分:0)
这适用于您的示例数据。可能不是最快的解决方案。
mutate(dat1, rownumber = 1:nrow(dat1)) -> dat1
for(i in unique(dat1$ID)) {
firstMiss = min(filter(dat1, ID==i &
(z %in% c(NaN, Inf, -Inf) |
z < 0))$rownumber,
max(filter(dat1, ID==i)$rownumber)+1,
na.rm=TRUE)
dat1 <- filter(dat1, !(ID==i & rownumber >= firstMiss))
}
dat2 <- select(dat1, -rownumber)
答案 3 :(得分:0)
只是为了laffs:
library(dplyr)
dat1 %>% group_by(ID) %>%
mutate(non_positive = min(which(lead(z,1) < 0 |
!is.finite(lead(z,1)) | row_number() == n()))) %>%
filter(row_number() <= non_positive) %>%
select(-non_positive)
# # A tibble: 14 x 4
# # Groups: ID [4]
# ID t y z
# <dbl> <dbl> <dbl> <dbl>
# 1 1 1 6.0 5
# 2 1 2 6.0 0
# 3 1 3 6.0 0
# 4 1 4 6.0 0
# 5 1 5 6.0 1
# 6 1 6 6.0 0
# 7 1 7 6.0 0
# 8 2 1 1.0 0
# 9 2 2 1.0 0
# 10 3 1 6.0 4
# 11 3 2 6.0 2
# 12 4 2 0.2 0
# 13 4 2 0.2 0
# 14 4 2 0.2 1