2014-10-20 88 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), ]