【问题标题】:Delete rows in dataframe based on values in multiple previous rows/columns根据多个先前行/列中的值删除数据框中的行
【发布时间】:2017-04-28 15:29:30
【问题描述】:

我有以下数据框:

   x  y  z
1  a  c  0
2  a  c  0
3  a  c  1
4  a  c  0
5  a  c  0
6  b  c  0
7  b  c  0
8  b  c  0
9  b  c  1
10 b  c  0
11 b  c  0
12 b  c  0
13 a  d  0
14 a  d  0
15 a  d  0

我想删除在 z 列的前一行中为 1 且在 x 列和 y 列中具有相同值的行。例如,对于第 10 行,我想在第 1:9 行中搜索 x = "b"、y = "c" 和 z 等于 1 的行。如果在第 1:9 行中存在这样的行,我想删除第 10 行。

因此,生成的数据框将删除第 4、5、10、11 和 12 行:

   x  y  z
1  a  c  0
2  a  c  0
3  a  c  1
4  b  c  0
5  b  c  0
6  b  c  0
7  b  c  1
8  a  d  0
9  a  d  0
10 a  d  0

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    我们可以通过data.table 做到这一点

    library(data.table)
    setDT(df1)[-df1[, .I[cummin(c(0, diff(z==1)))<0], .(x, y)]$V1]
    #    x y z
    # 1: a c 0
    # 2: a c 0
    # 3: a c 1
    # 4: b c 0
    # 5: b c 0
    # 6: b c 0
    # 7: b c 1
    # 8: a d 0
    # 9: a d 0
    #10: a d 0
    

    【讨论】:

      【解决方案2】:

      这是一个基本的 R 方法,ave 用于分组,interaction 用于构造组,并使用匿名函数进行一些逻辑操作。 as.logicalave 的输出,即 1 和 0 转换成逻辑向量,用于代入。

      匿名函数 c(1,head(cummin(i != 1), -1)) 为每个组的第一个元素返回 1,因为它将始终保留。对于余数,我们检查前一个值是否不是 1 并返回累积最小值,因此任何 1 的实例都将为其余元素返回 0。 head 用于删除最终元素,因为它不是考虑的一部分。

      df[as.logical(ave(df$z, interaction(df$x, df$y),
                        FUN=function(i) c(1,head(cummin(i != 1), -1)))), ]
         x y z
      1  a c 0
      2  a c 0
      3  a c 1
      6  b c 0
      7  b c 0
      8  b c 0
      9  b c 1
      13 a d 0
      14 a d 0
      15 a d 0
      

      【讨论】:

        【解决方案3】:

        我不确定我是否明白你的问题,但如果你想删除 z = 1 的所有行,你可以使用

        which(nameofdataframe$z != 1)
        

        如果你想要更多的参数,你可以像这样使用 &:

        which(nameofdataframe$z != 1 & nameofdataframe$x == "b")
        

        希望这会有所帮助!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-11-17
          • 2021-04-11
          • 1970-01-01
          • 1970-01-01
          • 2016-05-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多