我有一个数据框,用于计算特定列的运行长度编码。列的值,dir
, 是 -1、0 或 1。dir.rle <- rle(df$dir)
然后,我获取运行长度并计算数据框中另一列的分段累积总和。我正在使用 for 循环,但我觉得应该有一种更智能的方法。
ndx <- 1
for(i in 1:length(dir.rle$lengths)) {
l <- dir.rle$lengths[i] - 1
s <- ndx
e <- ndx+l
tmp[s:e,]$cumval <- cumsum(df[s:e,]$val)
ndx <- e + 1
}
dir
的运行长度定义开始,s
,并结束,e
,每次运行。上面的代码有效,但感觉不像惯用的 R 代码。我觉得好像应该有另一种方法可以在没有循环的情况下做到这一点。
最佳答案
这可以分解为两步问题。首先,如果我们基于 rle
创建一个索引列,然后我们可以使用它来分组并运行 cumsum
.然后可以通过任意数量的聚合技术执行分组依据。我将展示两个选项,一个使用 data.table
另一个使用 plyr
.
library(data.table)
library(plyr)
#data.table is the same thing as a data.frame for most purposes
#Fake data
dat <- data.table(dir = sample(-1:1, 20, TRUE), value = rnorm(20))
dir.rle <- rle(dat$dir)
#Compute an indexing column to group by
dat <- transform(dat, indexer = rep(1:length(dir.rle$lengths), dir.rle$lengths))
#What does the indexer column look like?
> head(dat)
dir value indexer
[1,] 1 0.5045807 1
[2,] 0 0.2660617 2
[3,] 1 1.0369641 3
[4,] 1 -0.4514342 3
[5,] -1 -0.3968631 4
[6,] -1 -2.1517093 4
#data.table approach
dat[, cumsum(value), by = indexer]
#plyr approach
ddply(dat, "indexer", summarize, V1 = cumsum(value))
关于r - 运行长度的累积和。这个循环可以矢量化吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8171203/