排除R中特定行下面的所有记录

时间:2017-08-14 21:45:54

标签: r

我的数据包含三个变量,其中包含三个唯一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)

4 个答案:

答案 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