交叉产品滚动值

时间:2019-01-11 17:32:55

标签: r rollup cross-product slam

我正在尝试找到一种基于数据向量计算滚动总和值的方法。以下是示例数据帧以及我正在尝试计算的答案,但找不到正确的解决方案。本质上,我试图将每个x列值乘以y向量,并根据周期求和。

period= c(1,2,3)
x=c(1,1,1)
y= c(2,3,4)

df=data.frame(period,x,y)

This is how I solved the answer.

2+0+0
3+2+0
4+3+2
0+4+3
0+0+4

answer= c(2,5,9,7,4)

我看过slam包以及crossprod函数都没有用。

谢谢!

3 个答案:

答案 0 :(得分:2)

我们可能会使用

c(cumsum(df$y), rev(cumsum(rev(df$y)))[-1])
# [1] 2 5 9 7 4

cumsum(df$y)从一个端点开始给出一个累加的总和,然后rev(cumsum(rev(df$y))从另一端点开始给出一个累加的总和,我们得到[-1],因为总和重合:

cumsum(df$y)
# [1] 2 5 9
rev(cumsum(rev(df$y)))
# [1] 9 7 4

答案 1 :(得分:2)

如果目标是计算3个值的滚动总和,以便隐式添加0,以确保即使输入有3个元素,输出也有5个元素,请尝试以下操作:

1)滚动应用xy乘以0,取决于是否使用了右对齐,居中对齐或左对齐以及是否使用了partial=align="center"rollapply的默认值,而align = "right"rollapplyr的默认值。

library(zoo)

rollapply(c(0, x*y, 0), 3, sum, partial = TRUE)
## [1] 2 5 9 7 4

rollapplyr(c(x*y, 0, 0), 3, sum, partial = TRUE)
## [1] 2 5 9 7 4

rollapplyr(c(0, 0, x*y), 3, sum, align = "left", partial = TRUE)
## [1] 2 5 9 7 4

rollapply(c(0, 0, x*y, 0, 0), 3, sum)
## [1] 2 5 9 7 4

rollsum(c(0, 0, x*y, 0, 0), 3) #  this solution has the lowest character count
## [1] 2 5 9 7 4

2)Base R 可以使用embed编写基本解决方案:

rowSums(embed(c(0, 0, x*y, 0, 0), 3))
## [1] 2 5 9 7 4

2a)或取累计总和减去累计总和3:

cumsum(c(x*y,0,0)) - cumsum(c(0, 0, 0, (x*y)[-3]))
## [1] 2 5 9 7 4

2b)如果要进行循环计算,则:

c(filter(c(0, x*y, 0), c(1,1,1), circular = TRUE))
## [1] 2 5 9 7 4

答案 2 :(得分:0)

如果有人想按组进行类似的计算,则下面的代码应该起作用。

df_nest<-df%>% group_by(variable)%>%nest()

df_nest%>%
  mutate(NewColumn = map(data, ~rollapplyr(c(.$x*.$y, 0, 0), 3, sum, partial = TRUE)))%>%
  unnest()