накопленная сумма по идентификатору с задержкой - PullRequest
3 голосов
/ 27 мая 2019

Я хочу создать кумулятивную сумму по идентификатору. Но он не должен суммировать значение, принадлежащее строке, в которой производится расчет.

Я уже пробовал с cumsum. Тем не менее, я не знаю, как добавить заявление, которое указывает, чтобы не добавлять сумму строки, в которой производится сумма. Столбец результатов, который я ищу, - это третий столбец, который называется «сумма».

Например, для идентификатора 1 первой строкой является сумма = 0, поскольку не следует добавлять эту строку. Но для идентификатора 1 и строки 2 сумма = 100, поскольку количество идентификатора 1, предшествующего строке 2, было 100 и т. Д.

   id amount sum
1:  1    100   0
2:  1     20 100
3:  1    150 120
4:  2     60   0
5:  2    100  60
6:  1     30 270
7:  2     40 160 

Вот что я пробовал:

  df[,sum:=cumsum(amount),
      by ="id"] 

  data: df <- data.table(id = c(1, 1, 1, 2, 2,1,2), amount = c(100, 20, 
  150,60,100,30,40),sum=c(0,100,120,0,60,270,160) ,stringsAsFactors = 
  FALSE)

Ответы [ 4 ]

5 голосов
/ 27 мая 2019

Вы можете сделать это без использования lag:

> df %>%
      group_by(id) %>%
      mutate(sum = cumsum(amount) - amount)
# A tibble: 7 x 3
# Groups:   id [2]
     id amount   sum
  <dbl>  <dbl> <dbl>
#1    1    100     0
#2    1     20   100
#3    1    150   120
#4    2     60     0
#5    2    100    60
#6    1     30   270
#7    2     40   160
2 голосов
/ 27 мая 2019

С dplyr -

df %>% 
  group_by(id) %>% 
  mutate(sum = lag(cumsum(amount), default = 0)) %>% 
  ungroup()

# A tibble: 7 x 3
     id amount   sum
  <dbl>  <dbl> <dbl>
1     1    100     0
2     1     20   100
3     1    150   120
4     2     60     0
5     2    100    60
6     1     30   270
7     2     40   160

Благодаря @thelatemail вот версия data.table -

df[, sum := cumsum(shift(amount, fill=0)), by=id]
1 голос
/ 27 мая 2019

Вот вариант в base R

df$Sum <- with(df, ave(amount, id, FUN = cumsum) - amount)
df$Sum
#[1]   0 100 120   0  60 270 160

Или, удалив последнее наблюдение, возьмите cumsum

with(df, ave(amount, id, FUN  = function(x) c(0, cumsum(x[-length(x)]))))
0 голосов
/ 27 мая 2019

Вы можете сдвинуть суммируемые значения с помощью функции lag.

library(tidyverse)

df <- data.frame(id = c(1, 1, 1, 2, 2,1,2), amount = c(100, 20, 
150,60,100,30,40),sum=c(0,100,120,0,60,270,160) ,stringsAsFactors = 
FALSE)

df %>% 
    group_by(id) %>% 
    mutate(sum = cumsum(lag(amount, 1, default=0)))

# A tibble: 7 x 3
# Groups:   id [2]
     id amount   sum
  <dbl>  <dbl> <dbl>
1     1    100     0
2     1     20   100
3     1    150   120
4     2     60     0
5     2    100    60
6     1     30   270
7     2     40   160
...