我有一个数据框:
dt <- read.table(text = "
350 16
366 11
376 0
380 0
397 0
398 45
400 19
402 0
510 0
525 0
537 0
549 0
569 112
578 99")
我想删除第二列中所有带有零的行,除了非零值之前和之后的行。
结果将是:
dt1 <- read.table(text = "
350 16
366 11
376 0
397 0
398 45
400 19
402 0
549 0
569 112
578 99")
答案 0 :(得分:5)
library(data.table)
setDT(dt)
dt[{n0 <- V2 != 0; n0 | shift(n0) | shift(n0, type = 'lead')}]
#or
dt[(n0 <- V2 != 0) | shift(n0) | shift(n0, type = 'lead')] # thanks @Frank
# V1 V2
# 1: 350 16
# 2: 366 11
# 3: 376 0
# 4: 397 0
# 5: 398 45
# 6: 400 19
# 7: 402 0
# 8: 549 0
# 9: 569 112
# 10: 578 99
答案 1 :(得分:3)
使用dplyr
:
dt %>%
filter(lag(V2, 1) != 0 | lead(V2, 1) != 0 | V2 != 0)
V1 V2
1 350 16
2 366 11
3 376 0
4 397 0
5 398 45
6 400 19
7 402 0
8 549 0
9 569 112
10 578 99
或者:
dt %>%
group_by(cond = lag(V2, 1) != 0 | lead(V2, 1) != 0 | V2 != 0) %>%
filter(cond == TRUE) %>%
ungroup() %>%
select(-cond)
# A tibble: 10 x 2
V1 V2
<int> <int>
1 350 16
2 366 11
3 376 0
4 397 0
5 398 45
6 400 19
7 402 0
8 549 0
9 569 112
10 578 99
答案 2 :(得分:1)
使用base R
比较向上和向下位移向量的简单解决方案
dt[ !(c(dt$V2[-1],0) == 0 & c(0,dt$V2[-length(dt$V2)]) == 0 & dt$V2 == 0), ]
答案 3 :(得分:0)
与其他回答相比,这并不是什么新鲜事物,但是我发现这个问题很有趣,因此我制定了自己的解决方案-贴吧:
## Function to test if both neighbors of a vector element have the value 0
## Returns a logical vector.
neighbors_zero <- function(x) {
## left neighbor is zero?
rn0 <- c(x[2:length(x)], x[1]) == 0
## right neighbor is zero?
ln0 <- c(x[length(x)], x[1:(length(x)-1)]) == 0
return(rn0 & ln0)
}
## Test if a value is itsself zero and between other zeros
zero_between_zeros <- dt$V2 == 0 & neighbors_zero(dt$V2)
dt[!zero_between_zeros, ]