根据条件求和相邻行

mar*_*llt 5 conditional r sum

我有一个类似于此的data.frame

id <- c(1,1,1,2,2,3,3,3,3,3)
action <- c("for","l","for","f","l","l","for","for","for","f")
time <- c(45,35,24,56,100,121,30,10,35,143)
dframe <- data.frame(id,action,time)
Run Code Online (Sandbox Code Playgroud)

只有动作"for"在每个唯一id中的连续行中重复.我想将这些行折叠成一行,将行动时间总计为"for".我想只在每个唯一ID内和它们彼此跟随时这样做(如id == 3,而不是id == 1)

我尝试了下面的代码,但是这并没有区分一个接一个跟随的动作,而是将唯一id中所有出现的"for"相加.

aggregate(action_time ~ id + act, data=mean.event, FUN=sum)
Run Code Online (Sandbox Code Playgroud)

谢谢你的时间.

Jos*_*ien 2

使用rle()inverse.rle()data.table包:

## Reproduce example data, naming it df and setting stringsAsFactors=FALSE    
id <- c(1,1,1,2,2,3,3,3,3,3)
action <- c("for","l","for","f","l","l","for","for","for","f")
time <- c(45,35,24,56,100,121,30,10,35,143)
df <- data.frame(id,action,time, stringsAsFactors=FALSE)

## Use rle() and inverse.rle() to give each run of "for"s a distinct name
r <- rle(df$action)
r$values <- paste0(r$values, seq_along(r$values))
(r <- inverse.rle(r))
#  [1] "for1" "l2"   "for3" "f4"   "l5"   "l5"   "for6" "for6" "for6" "f7"  

## Use data.table to subset by run of "for"s *and* by id, collapsing only
## sub-data.tables consisting of consecutive "for"s within an id.
library(data.table)
dt <- data.table(df)

dt[ , if(action[1]=="for") {
          X <- .SD[1,]       
          X$time <- sum(time) 
          X
      } else {.SD}, 
   by=list(r, id)][,-1,with=FALSE]
#    id action time
# 1:  1    for   45
# 2:  1      l   35
# 3:  1    for   24
# 4:  2      f   56
# 5:  2      l  100
# 6:  3      l  121
# 7:  3    for   75
# 8:  3      f  143
Run Code Online (Sandbox Code Playgroud)