从数据框中心开始的累积和 - R

时间:2014-07-03 22:20:25

标签: r dataframe cumulative-sum

我将此data.frame称为dum

   dummy <- data.frame(label = "a", x = c(1,1,1,1,0,1,1,1,1,1,1,1,1))
   dummy1 <- data.frame(label = "b", x = c(1,1,1,1,1,1,1,1,0,1,1,1,1))

   dum <- rbind(dummy,dummy1)

我要做的是从x的{​​{1}}列中取0的累计和。汇总将按dum列进行分组,该列可以在labeldplyr中实施。我正在努力的部分是如何从plyr中的0位开始累积和并向外走。

生成的x应如下所示:

data.frame

这需要在数百万行数据上重复数千次。

像往常一样,感谢任何和所有帮助

3 个答案:

答案 0 :(得分:4)

似乎更像是你只想找到一个零的距离,而不是任何一种累积总和。如果是这样,那么

#find zeros for each group
zeros <- tapply(seq.int(nrow(dum)) * as.numeric(dum$x==0), dum$label, max)

#calculate distance from zero for each point
dist <- abs(zeros[dum$label]-seq.int(nrow(dum)))

这就是

cbind(dum, dist)

#    label x dist
# 1      a 1    4
# 2      a 1    3
# 3      a 1    2
# 4      a 1    1
# 5      a 0    0
# 6      a 1    1
# 7      a 1    2
# 8      a 1    3
# 9      a 1    4
# 10     a 1    5
# 11     a 1    6
# 12     a 1    7
# 13     a 1    8
# 14     b 1    8
# 15     b 1    7
# 16     b 1    6
# 17     b 1    5
# 18     b 1    4
# 19     b 1    3
# 20     b 1    2
# 21     b 1    1
# 22     b 0    0
# 23     b 1    1
# 24     b 1    2
# 25     b 1    3
# 26     b 1    4

甚至ave都可以让您一步到位

dist <- with(dum, ave(x,label,FUN=function(x) abs(seq_along(x)-which.min(x))))
cbind(dum, dist)

答案 1 :(得分:2)

您可以使用by以及plyrdata.table等来执行此操作。每个子集使用的函数是

f <- function(d) {
  x <- d$x
  i <- match(0, x)
  v1 <- rev(cumsum(rev(x[1:i])))
  v2 <- cumsum(x[(i+1):length(x)])
  transform(d, output = c(v1, v2))
}

在每个子集上调用它,例如与by

res <- by(dum, list(dum$label), f)
do.call(rbind, res)

如果您想使用ddply

library(plyr)
ddply(dum, .(label), f)

data.table

可能会更快
library(data.table)
dumdt <- as.data.table(dum)
setkey(dumdt, label)
dumdt[, f(.SD), by = key(dumdt)]

答案 2 :(得分:1)

使用dplyr

library(dplyr)
dum%>% 
group_by(label)%>% 
mutate(dist=abs(row_number()-which.min(x)))