R 运行长度上的累积总和。这个循环可以矢量化吗?

R 运行长度上的累积总和。这个循环可以矢量化吗?,r,vectorization,plyr,data.table,R,Vectorization,Plyr,Data.table,我有一个数据帧,在该数据帧上计算特定列的运行长度编码。列dir的值为-1、0或1 dir.rle这可以分解为两步问题。首先,如果我们基于rle创建一个索引列,那么我们可以使用它来分组并运行cumsum。然后,可以通过任何数量的聚合技术来执行分组。我将显示两个选项,一个使用data.table,另一个使用plyr library(data.table) library(plyr) #data.table is the same thing as a data.frame for most purp

我有一个数据帧,在该数据帧上计算特定列的运行长度编码。列
dir
的值为-1、0或1


dir.rle这可以分解为两步问题。首先,如果我们基于
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))
库(data.table)
图书馆(plyr)
#在大多数情况下,data.table与data.frame是一样的
#假数据

dat在数据框中添加“组”列。比如:

df=data.frame(z=rnorm(100)) # dummy data
df$dir = sign(df$z) # dummy +/- 1
rl = rle(df$dir)
df$group = rep(1:length(rl$lengths),times=rl$lengths)
然后使用tapply在组内求和:

tapply(df$z,df$group,sum)

Spacedman和Chase都强调了一个关键点,即分组变量简化了一切(Chase给出了两种很好的方法,可以从中着手)

我将引入另一种形成分组变量的方法。它不使用
rle
,至少对我来说,感觉更直观。基本上,在
diff()
检测到值变化的每个点上,将构成分组变量的
cumsum
都会递增一:

df$group <- c(0, cumsum(!(diff(df$dir)==0)))

# Or, equivalently
df$group <- c(0, cumsum(as.logical(diff(df$dir))))

df$group您能提供一些示例数据吗?那会有帮助的。如果我误解了你的数据框的结构,请告诉我。您可以使用
dput(yourDataHere)
的输出更新您的问题。如果太大,使用
subset()
head()
将示例设置为适当的大小。很好,但我认为OP希望在每个组内重新开始累积总和(而不是分组总和)。这就是为什么我们喜欢问题中重复的示例:)事实上,他非常接近。哈利路亚,兄弟!我还希望有一个功能可以通过StackOverflow的搜索引擎运行
粘贴([r],title\u of\u question)
,并在提供“提交”按钮之前返回结果。这对于细化涉及
“数字”
“四舍五入”
、和
“NA”
)的问题非常有用(这不是对当前问题的抱怨,这是一个有趣的问题,在发布前经过深思熟虑)在我的博客上,我发布了一篇比较ave、ddply和data.table的文章:@paul-我的直觉似乎证实了你的博客文章。在大多数情况下,当N变大时,data.table以许多数量级的速度最快。我对plyr比较满意,但是最近一直在重构瓶颈。Hadley Wickham(plyr作者)回应我文章中的代码示例时说,plyr的新版本将使用data.table之类的速度增强功能。因此,也许不久之后,速度差异将得到解决:)。
df$group <- c(0, cumsum(!(diff(df$dir)==0)))

# Or, equivalently
df$group <- c(0, cumsum(as.logical(diff(df$dir))))