Как обновить строку по группе в последовательности - PullRequest
2 голосов
/ 31 января 2020

У меня есть dt:

library(data.table)

DT <- data.table(a = c(1,2,3,4,5), b = c(4,5,6,7,8), c = c("X","X","X","Y","Y") ) 

Я хочу добавить один столбец d, в каждой группе столбцов C:

  • значение первой строки должно быть то же самое, что и b[i],
  • вторая-последняя строка в каждой группе должна быть d[i-1] + 2*b[i]

Ожидаемые результаты:

   a b c d
1: 1 4 X 4
2: 2 5 X 14
3: 3 6 X 26
4: 4 7 Y 7
5: 5 8 Y 23

Я пытался использовать такие функции, как shift, но я изо всех сил пытаюсь обновить строки динамически (так сказать) здесь, интересно, есть ли какое-нибудь элегантное решение в стиле data.table?

Ответы [ 2 ]

6 голосов
/ 31 января 2020

Мы можем использовать cumsum и вычесть первый ряд, используя [1]:

DT[, d := cumsum(2 * b) - b[1], .(c)][]

#>    a b c  d
#> 1: 1 4 X  4
#> 2: 2 5 X 14
#> 3: 3 6 X 26
#> 4: 4 7 Y  7
#> 5: 5 8 Y 23
3 голосов
/ 31 января 2020

Здесь мы можем использовать accumulate

library(purrr)
library(data.table)
DT[, d := accumulate(b, ~ .x + 2 *.y), by = c]

Или с Reduce и accumulate = TRUE из base R

DT[, d := Reduce(function(x, y) x + 2 * y, b, accumulate = TRUE), by = c]
...