我有一个df:
df <- data.frame(x = c(1,2,3,4,5,6,7,8,9,10,11,12,13),
y = c(0,0,2,0,1,0,0,0,0,3,0,4,0))
Run Code Online (Sandbox Code Playgroud)
我正在寻找精确时刻每4行的总和(在第4时刻之后)这应该是输出:
x y z
1 0 0
2 0 0
3 2 0
4 0 2
5 1 0
6 0 0
7 0 0
8 0 1
9 0 0
10 3 0
11 0 0
12 4 7
13 0 0
Run Code Online (Sandbox Code Playgroud)
使用dplyr,我能够使用以下结果创建以下代码.
a <- df %>%
dplyr::mutate(b = gl(ceiling(nrow(x)/4), 4, nrow(x))) %>%
dplyr::group_by(b) %>%
dplyr::mutate(sum = sum(amount))
x y z
1 0 2
2 0 2
3 2 2
4 0 2
5 1 1
6 0 1
7 0 1
8 0 1
9 0 7
10 3 7
11 0 7
12 4 7
13 0 0
Run Code Online (Sandbox Code Playgroud)
但我无法删除数字并将其替换为0除了第4行,但问题是如果我有一段时间0,它会重复.
这可以容易地实现rollapply从zoo包,即
library(zoo)
rollapply(df$y, 4, by = 4, sum, fill = 0, align = 'right')
#[1] 0 0 0 2 0 0 0 1 0 0 0 7 0
Run Code Online (Sandbox Code Playgroud)
在使用'b'创建分组之后gl,我们通过获取sum'y'并乘以逻辑向量(row_number()==n())来创建'z'列,这样除了最后一行之外,所有其他元素都变为0
library(dplyr)
df %>%
group_by(b = gl(ceiling(n()/4), 4, n())) %>%
mutate(z = sum(y) * (row_number()== n())) %>%
ungroup() %>%
select(-b)
# A tibble: 13 x 3
# x y z
# <dbl> <dbl> <dbl>
# 1 1 0 0
# 2 2 0 0
# 3 3 2 0
# 4 4 0 2
# 5 5 1 0
# 6 6 0 0
# 7 7 0 0
# 8 8 0 1
# 9 9 0 0
#10 10 3 0
#11 11 0 0
#12 12 4 7
#13 13 0 0
Run Code Online (Sandbox Code Playgroud)
如果我们需要外部封装,RcppRoll可以使用高效率并且也可以轻松实现输出
library(RcppRoll)
with(df, round(roll_sumr(y, n = 4, by=4, fill = 0)))
#[1] 0 0 0 2 0 0 0 1 0 0 0 7 0
Run Code Online (Sandbox Code Playgroud)