【问题标题】:Conditionally remove rows from dataframe (more than one conditions)有条件地从数据框中删除行(多个条件)
【发布时间】:2013-01-10 08:58:04
【问题描述】:

我已经搜索过 SO,虽然有很多关于有条件地删除行的 QA,但没有一个 QA 适合我的问题。

我有一个data.frame,其中包含变量xy 等的纵向测量值,在不同的时间点time,在几个主题id。一些对象经历了一个事件ev(表示为1,否则在某些time处表示为0)。我想将最初的data.frame 减少为:

  • 1) 包含未经历事件的主题的所有行(好的,这很容易),但也包括
  • 2) 对于经历过事件的受试者,事件之前的所有行(即所有行的时间都小于该个体的事件时间)。

这样,

testdf<-data.frame(id=c(rep("A",4),rep("B",4),rep("C",4) ),
                   x=c(NA, NA, 1,2, 3, NA, NA, 1, 2, NA,NA, 5), 
                   y=rev(c(NA, NA, 1,2, 3, NA, NA, 1, 2, NA,NA, 5)),
                   time=c(1,2,3,4,0.1,0.5,10,20,3,2,1,0.5),
                   ev=c(0,0,0,0,0,1,0,0,0,0,0,1))

会减少到

   id  x  y time ev
1   A NA  5  1.0  0
2   A NA NA  2.0  0
3   A  1 NA  3.0  0
4   A  2  2  4.0  0
5   B  3  1  0.1  0
6   C  2  2  3.0  0
7   C NA  1  2.0  0
8   C NA NA  1.0  0

【问题讨论】:

  • 请注意,条件 2 意味着条件 1,如果条件 2 写为“事件之前的所有行”。

标签: r conditional dataframe


【解决方案1】:

这是subsetave 的解决方案:

subset(testdf, !ave(ev, id, FUN = cumsum))

【讨论】:

    【解决方案2】:

    base 中的一个解决方案:

    > do.call(rbind, by(testdf, testdf$id, function(x) x[cumsum(x$ev) == 0,]))
         id  x  y time ev
    A.1   A NA  5  1.0  0
    A.2   A NA NA  2.0  0
    A.3   A  1 NA  3.0  0
    A.4   A  2  2  4.0  0
    B     B  3  1  0.1  0
    C.9   C  2  2  3.0  0
    C.10  C NA  1  2.0  0
    C.11  C NA NA  1.0  0
    

    【讨论】:

    • 或者,testdf[with(testdf, ave(ev, id, FUN = cumsum)) == 0, ]
    【解决方案3】:

    这是一个例子:

    > ddply(testdf, .(id), function(z) z[cumsum(z$ev) == 0, ])
      id  x  y time ev
    1  A NA  5  1.0  0
    2  A NA NA  2.0  0
    3  A  1 NA  3.0  0
    4  A  2  2  4.0  0
    5  B  3  1  0.1  0
    6  C  2  2  3.0  0
    7  C NA  1  2.0  0
    8  C NA NA  1.0  0
    

    【讨论】:

      【解决方案4】:

      这个使用data.table 的解决方案似乎适用于您的testdf。这个想法是使用cumsum 来跟踪第一个事件开始后的位置。

      require(data.table)
      dt <- data.table(testdf, key=c("id"))
      dt.out <- dt[, .SD[cumsum(ev) == 0], by=id]
      > dt.out
      
      #    id  x  y time ev
      # 1:  A NA  5  1.0  0
      # 2:  A NA NA  2.0  0
      # 3:  A  1 NA  3.0  0
      # 4:  A  2  2  4.0  0
      # 5:  B  3  1  0.1  0
      # 6:  C  2  2  3.0  0
      # 7:  C NA  1  2.0  0
      # 8:  C NA NA  1.0  0
      

      【讨论】:

        猜你喜欢
        • 2015-05-16
        • 1970-01-01
        • 2020-10-29
        • 1970-01-01
        • 2022-11-21
        • 1970-01-01
        • 2018-06-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多