2014-10-20 70 views
2

我想删除所有包含零的行,但仅当该行(它下面的行为零且上面的行也为零)或(它是一个零,这是第一次观察,下面的数字也是零)。删除包含零的data.frame行,其中相邻的行包含零

例如:

RowNumb Column2 
    1   0 
    2   0 
    3   0 
    4   1 
    5   0 
    6   1  
    7   1 
    8   0 
    9   0 
    10   0 

我想删除行1,2,图9和10,因为这些是有等于零的唯一的行,具有低于他们零以及一个零或没有(在rowNumb 1的情况下)在他们之上,这样我得到如下:

RowNumb Column2 
    3   0 
    4   1 
    5   0 
    6   1  
    7   1 
    8   0 

有谁知道这样做不使用循环的方式吗?

+1

或用简单的话来说,也许是:“相邻行的值也是零”。 – jbaums 2014-10-20 07:56:23

回答

4

您可以使用filter总结各绝对值与前面和后面的绝对值和比较,和以0:

DF <- read.table(text="RowNumb Column2 
    1   0 
    2   0 
    3   0 
    4   1 
    5   0 
    6   1  
    7   1 
    8   0 
    9   0 
    10   0", header=TRUE) 

rem <- na.omit(filter(abs(c(0, DF$Column2, 0)), rep(1, 3)) != 0L) 

DF[rem,] 
# RowNumb Column2 
#3  3  0 
#4  4  1 
#5  5  0 
#6  6  1 
#7  7  1 
#8  8  0 

这是假设没有NA值。如果这些可能会出现你需要修改这个有点:

x <- c(0, DF$Column2, 0)   
rem <- na.omit(filter(x != 0L | is.na(x) , rep(1, 3)) != 0L) 
+0

谢谢,完美无缺!你能否更详细地解释它究竟是如何工作的?我只是查了过滤器功能,但我仍然不明白。谢谢! – Mike 2014-10-20 08:09:27

+0

使用过滤器'c(1,1,1)'和'sides = 2',函数将每个值与相邻值相加。我需要为输入的第一行/最后一行填充前导和尾随零。 – Roland 2014-10-20 08:19:24

3

这里有一个dplyr方式使用laglead功能:

require(dplyr) 
df %>% filter(!(Column2 == 0 & lag(Column2, default = 0) == 0 & lead(Column2,default = 0) == 0)) 
# RowNumb Column2 
#1  3  0 
#2  4  1 
#3  5  0 
#4  6  1 
#5  7  1 
#6  8  0 
2

1)rollapply这使用rollapply从动物园包检查连续三个中的任何一个(并且因为每个末端的两个连续两个)不为零:

library(zoo) 

DF[ rollapply(DF$Column2 != 0, 3, any, partial = TRUE), ] 

捐赠:

RowNumb Column2 
3  3  0 
4  4  1 
5  5  0 
6  6  1 
7  7  1 
8  8  0 

1A)这样的变化同样适用:

DF[ rollapply(c(0, DF$Column2, 0) != 0, 3, any), ] 

2)嵌入此解决方案不使用任何软件包。对于这个例子embed形成10×3矩阵,它的行包含连续的三元组(两连胜和在端部处为行的零),并从该计算的逻辑矩阵并应用any各行:

DF[apply(embed(c(0, DF$Column2, 0) != 0, 3), 1, any), ]