【问题标题】:Delete rows in dataframe that are all previous to value in row删除数据框中所有在行中的值之前的行
【发布时间】:2017-09-19 12:30:23
【问题描述】:

考虑df1

df <- data.frame(time = c(1,2,3,4,5,6,7,8,9,10), marker = c(NA,NA,NA,"stop",NA,NA,NA,"start",NA,NA), behaviour = c("Rest","Rest","Rest","Rest","Awake","Awake","Awake","Awake","Awake","Rest"))

   time marker behaviour
1     1   <NA>      Rest
2     2   <NA>      Rest
3     3   <NA>      Rest
4     4   stop      Rest
5     5   <NA>     Awake
6     6   <NA>     Awake
7     7   <NA>     Awake
8     8  start     Awake
9     9   <NA>     Awake
10   10   <NA>      Rest

我想根据列 markers 对数据进行子集化,并且不包括元素“stop”和“start”之间的数据,以便 df 看起来像这样:

time marker behaviour
   1   <NA>      Rest
   2   <NA>      Rest
   3   <NA>      Rest
   4   stop      Rest
   8   start     Awake
   9   <NA>     Awake
   10  <NA>      Rest

【问题讨论】:

  • 试试i1 &lt;- with(df, which(marker %in% c("stop", "start")));df[-((i1[1]+1):(i1[2]-1)),]
  • 是的,这是一种享受,谢谢 akrun!

标签: r dataframe row subset


【解决方案1】:

我们可以使用数字索引来对行进行子集化

i1 <- with(df, which(marker %in% c("stop", "start")))
df[-((i1[1]+1):(i1[2]-1)),]

如果有多个'start','stop',那么,我们可以做

grp <- with(df, c(0, head(cumsum(marker == "stop" & !is.na(marker)),-1)))
df[with(df, ave(marker == "start" & !is.na(marker),
             grp, FUN = function(x) !any(x)|cumsum(x)>0)),]
#   time marker behaviour
#1     1   <NA>      Rest
#2     2   <NA>      Rest
#3     3   <NA>      Rest
#4     4   stop      Rest
#8     8  start     Awake
#9     9   <NA>     Awake
#10   10   <NA>      Rest

【讨论】:

    【解决方案2】:
    df <- data.frame(time = c(1,2,3,4,5,6,7,8,9,10), marker = c("NA","NA","NA","stop","NA","NA","NA","start","NA","NA"), behaviour = c("Rest","Rest","Rest","Rest","Awake","Awake","Awake","Awake","Awake","Rest"))
    
    df1 <- as.integer(row.names(df[df$marker=="stop",]))+1
    df2 <- as.integer(row.names(df[df$marker=="start",]))-1
    ans <- df[-(df1:df2),]
    

    【讨论】:

      【解决方案3】:

      一个cumsum 解决方案(我也使用data.table,但您不必这样做)泛化为多个stop/start 值将是:

      library(data.table)
      dt <- as.data.table(df)
      
      dt[, drop := list(cumsum(marker=="stop" & !is.na(marker)) - 
                          cumsum(marker=="start" & !is.na(marker)))][drop==0 | marker == "stop"]
      
         #    time marker behaviour drop
         # 1:    1     NA      Rest    0
         # 2:    2     NA      Rest    0
         # 3:    3     NA      Rest    0
         # 4:    4   stop      Rest    1
         # 5:    8  start     Awake    0
         # 6:    9     NA     Awake    0
         # 7:   10     NA      Rest    0
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-01
        • 1970-01-01
        • 2023-03-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多