【问题标题】:Remove data.frame rows containing zero, where adjacent rows contain zero删除包含零的 data.frame 行,其中相邻行包含零
【发布时间】:2014-10-20 07:48:36
【问题描述】:

我想删除所有包含零的行,但前提是(它下面的行为零并且它上面的行也为零)或(它是零并且它是第一个观察值并且下面的数字它也是一个零)。

例如:

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 行,因为这些是唯一等于 0 的行,它们下面有一个零,或者为零或没有(在 rowNumb 1 的情况下)在它们之上,这样我得到以下信息:

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

有人知道不使用循环的方法吗?

【问题讨论】:

  • 或更简单的说法,也许是:“相邻行的值也为零”。

标签: r


【解决方案1】:

您可以使用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)

【讨论】:

  • 谢谢,完美运行!您能否更详细地解释一下它是如何工作的?刚刚查了一下过滤功能,还是没看懂。谢谢!
  • 使用过滤器c(1, 1, 1) 和sides = 2,函数将每个值与相邻值相加。我需要用前导和尾随零填充输入,以便您对第一行/最后一行进行特殊处理。
【解决方案2】:

这是使用lag 和lead 函数的dplyr 方法:

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

【讨论】:

    【解决方案3】:

    1) rollapply 这使用 zoo 包中的 rollapply 来检查连续三个中的任何一个(并且因为 partial=TRUE 每端连续两个)是否不为零:

    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 x 3 矩阵,其行包含连续的三元组(一行中的两个,末尾的行为零)并从中计算逻辑矩阵并将any 应用于每一行:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-21
      • 1970-01-01
      • 2022-06-17
      • 1970-01-01
      • 1970-01-01
      • 2014-02-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多