Рассчитать кумулятивные суммы определенных значений - PullRequest
5 голосов
/ 19 октября 2011

Предположим, у вас есть фрейм данных, подобный этому:

df <- data.frame(Nums = c(1,2,3,4,5,6,7,8,9,10), Cum.sums = NA)
> df
   Nums Cum.sums
1     1       NA
2     2       NA
3     3       NA
4     4       NA
5     5       NA
6     6       NA
7     7       NA
8     8       NA
9     9       NA
10   10       NA

, и вы хотите вывод, подобный этому:

   Nums Cum.sums
1     1        0
2     2        0
3     3        0
4     4        3
5     5        5
6     6        7
7     7        9
8     8       11
9     9       13
10   10       15

Элемент 4. столбца Cum.sum -сумма 1 и 2, элемент 5. столбца Cum.sum - это сумма 2 и 3 и т. д. Это означает, что я хотел бы построить накопительную сумму в первом ряду и сохранить ее во второмстрока.Однако мне не нужна обычная кумулятивная сумма, а сумма элементов 2 строки над текущей строкой плюс 3 элемента строки над текущей строкой.

Я уже попытался немного поиграть с суммойи cumsum, но у меня не получилось.

Есть идеи?

Спасибо!

Ответы [ 3 ]

3 голосов
/ 19 октября 2011

Вы можете использовать функцию embed для создания соответствующих лагов, rowSums для суммирования, а затем подходящим лагом (я использовал head).

df$Cum.sums[-(1:3)] <- head(rowSums(embed(df$Nums,2)),-2)
0 голосов
/ 19 октября 2011

Другое решение, элегантное и общее, с использованием умножения матриц - и поэтому очень неэффективное для больших данных.Так что это не очень практично, хотя хорошее упражнение:

len <- nrow(df)
sr <- 2 # number of rows to sum
lag <- 3 
mat <- matrix(
           head(c(
                 rep(0, lag * len), 
                 rep(rep(1:0, c(sr, len - sr + 1)), len)
               ), len * len), 
           nrow = 10, byrow = TRUE
       )
mat %*% df$Nums
0 голосов
/ 19 октября 2011

Вам не нужны никакие специальные функции, просто используйте обычные векторные операции (все эти решения эквивалентны):

df$Cum.sums[-(1:3)] <- head(df$Nums, -3) + head(df$Nums[-1], -2)

или

with(df, Cum.sums[-(1:3)] <- head(Nums, -3) + head(Nums[-1], -2))

или

df$Cum.sums[-(1:3)] <- df$Nums[1:(nrow(df)-3)] + df$Nums[2:(nrow(df)-2)]

Я считаю, что первые 3 суммы ДОЛЖНЫ быть NA, а не 0, но если вы предпочитаете нули, вы можете сначала инициализировать суммы:

df$Cum.sums <- 0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...