r类似于cumsum的函数用于拆分数据帧

sob*_*ber 4 r dataframe

给出以下数据帧:

mydf <- data.frame(x=c(1:10,10:1),y=c(10:1,1:10))
Run Code Online (Sandbox Code Playgroud)

如何split使每个子数据帧具有一列的连续值大于另一列?

例如mydf,我希望的结果是将split其分为三个数据帧:

  1. (y> x;应该包含前5行mydf)
  2. (x> y;应包含第6至15行mydf)
  3. (y> x再次;应包含最后5行mydf)

我尝试使用以下代码,但它产生了错误的结果,其中每个y> x将被单独拆分; 此外,x> y的数据帧在第一行中包含ay> x:

split(mydf, cumsum(mydf$x > mydf$y))
Run Code Online (Sandbox Code Playgroud)

我尝试做的另一个不那么优雅的方法是在函数内部sapply使用单独的ifs split,但由于性能问题,我不想走这条路.

akr*_*run 5

尝试

rl <- with(mydf, rle(x >y))
grp <- inverse.rle(within.list(rl , values <- seq_along(values)))
split(mydf, grp)  
#$`1`
#  x  y
#1 1 10
#2 2  9
#3 3  8
#4 4  7
#5 5  6

#$`2`
#    x y
#6   6 5
#7   7 4
#8   8 3
#9   9 2
#10 10 1
#11 10 1
#12  9 2
#13  8 3
#14  7 4
#15  6 5

#$`3`
#   x  y
#16 5  6
#17 4  7
#18 3  8
#19 2  9
#20 1 10
Run Code Online (Sandbox Code Playgroud)

要么

group <-  with(mydf, cumsum(c(1,abs(diff(x >y)))))
split(mydf, group)
Run Code Online (Sandbox Code Playgroud)

或者您可以使用rleiddevel版本data.table(来自@David Arenburg的评论),即v1.9.5.安装它的说明是here

 library(data.table)
 split(mydf, rleid(with(mydf, y > x)))
Run Code Online (Sandbox Code Playgroud)

  • 或者更简单的`library(data.table); split(mydf,rleid(with(mydf,y> x)))` (4认同)