【问题标题】:Delete rows with zero value under condition在条件下删除零值的行
【发布时间】:2018-09-20 19:54:07
【问题描述】:

我有一个数据框:

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")

【问题讨论】:

    标签: r dataframe


    【解决方案1】:
    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
    

    编辑:

    现在data.table::shift 接受带有一些负元素和一些正元素的向量,您可以改用下面的代码

    dt[Reduce('|', shift(V2 != 0, -1:1))]
    

    【讨论】:

      【解决方案2】:

      使用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
      

      【讨论】:

        【解决方案3】:

        使用base R比较向上和向下位移向量的简单解决方案

        dt[ !(c(dt$V2[-1],0) == 0 & c(0,dt$V2[-length(dt$V2)]) == 0 & dt$V2 == 0), ]
        

        【讨论】:

          【解决方案4】:

          与其他回答相比,这并不是什么新鲜事,但我发现这个问题很有趣,所以我提出了自己的解决方案 - 瞧:

          ## 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, ]
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-09-19
            • 2021-02-28
            • 2016-10-19
            • 2019-12-13
            • 2022-01-26
            • 2012-04-16
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多