Сброс накопленной суммы после 10 значений - PullRequest
3 голосов
/ 20 марта 2020

У меня есть данные в h, которые я хочу суммировать в bw, и после 10 шагов я хочу сбросить сумму. Как мне это получить?

   h bw
1  0  0
2  0  0
3  1  1
4  0  1
5  1  2
6  0  2
7  0  2
8  1  3
9  1  4
10 1  5
11 0  0
12 0  0
13 0  0
14 0  0
15 1  1
16 1  2
17 1  3
18 0  3
19 0  3
20 1  4
21 1  1
22 0  1

В данный момент я работаю с этим:

ff = function(x)
{
  cs = cumsum(x)
  cs - cummax((x == 0) * cs)
}

, но он сбрасывается, когда h равно 0, а не после 10 значений.

Большое спасибо!

Ответы [ 4 ]

1 голос
/ 20 марта 2020

Вы можете разделить вектор по позиции каждого элемента по модулю 10, чтобы сделать это как одну строку.

as.numeric(unlist(sapply(split(df$bw, (seq_along(df$bw)-1) %/% 10), cumsum)))
# [1]  0  0  1  2  4  6  8 11 15 20  0  0  0  0  1  3  6  9 12 16  1  2
0 голосов
/ 20 марта 2020

Используя ave вы можете сделать

bw <- ave(h, rep(1:ceiling(length(h)/10), each=10)[seq(h)], FUN=cumsum)
bw
# [1] 0 0 1 1 2 2 2 3 4 5 0 0 0 0 1 2 3 3 3 4 1 1

Данные

h <- c(0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0)
0 голосов
/ 20 марта 2020

другой вариант с использованием dplyr

library(tidyverse)
df %>% 
  mutate(id = (row_number()-1)%/%10) %>% 
  group_by(id) %>% 
  mutate(cs = cumsum(bw)) %>% 
  select(-id)
0 голосов
/ 20 марта 2020
df <- structure(list(h = c(0L, 0L, 1L, 0L, 1L, 0L, 0L, 1L, 1L, 1L, 
0L, 0L, 0L, 0L, 1L, 1L, 1L, 0L, 0L, 1L, 1L, 0L), bw = c(0L, 0L, 
1L, 1L, 2L, 2L, 2L, 3L, 4L, 5L, 0L, 0L, 0L, 0L, 1L, 2L, 3L, 3L, 
3L, 4L, 1L, 1L), cs = c(0L, 0L, 1L, 1L, 2L, 2L, 2L, 3L, 4L, 5L, 
0L, 0L, 0L, 0L, 1L, 2L, 3L, 3L, 3L, 4L, 1L, 1L)), row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", 
"14", "15", "16", "17", "18", "19", "20", "21", "22"), class = "data.frame")

cumsum10 <- function(x){
  idx <- seq(x)%%10
  starts <- c(1, which(idx == 0)+1)
  stops <- c(which(idx == 0), length(x))

  res <- vector("list", length(starts))
  for(i in seq(res)){
    res[[i]] <- cumsum(x[starts[i]:stops[i]])
  }
  res <- do.call("c", res)
  return(res)
}


df$cs <- cumsum10(df$bw)
df


#    h bw cs
# 1  0  0  0
# 2  0  0  0
# 3  1  1  1
# 4  0  1  2
# 5  1  2  4
# 6  0  2  6
# 7  0  2  8
# 8  1  3 11
# 9  1  4 15
# 10 1  5 20
# 11 0  0  0
# 12 0  0  0
# 13 0  0  0
# 14 0  0  0
# 15 1  1  1
# 16 1  2  3
# 17 1  3  6
# 18 0  3  9
# 19 0  3 12
# 20 1  4 16
# 21 1  1  1
# 22 0  1  2
...