Подтвердить что ты не робот

Вычисление суммарной суммы для каждой строки

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

df <- data.frame(count=1:10)

for (loop in (1:nrow(df)))
    {df[loop,"acc_sum"] <- sum(df[1:loop,"count"])}

Но мне не нравится явный цикл здесь, как его изменить?

4b9b3361

Ответ 1

Вы хотите cumsum()

df <- within(df, acc_sum <- cumsum(count))

Ответ 2

Вы также можете попробовать mySum = t(apply(df, 1, cumsum)).

Транспортировка там, потому что результаты выходят транспонированными, по какой-то причине я еще не определился.

Я уверен, что есть прекрасные решения с plyr, такие как ddply и многоядерные методы.

Ответ 3

Чтобы реплицировать результат OP, функция cumsum - это все, что необходимо, как показывает ответ Chase. Тем не менее, формулировка OP "для каждой строки", возможно, указывает на интерес к совокупным суммам матрицы или кадра данных.

Для столбчатых совпадений data.frame, интересно, cumsum снова все нужно! cumsum - это примитив, который является частью группы Math общих функций, которая определяется для фреймов данных как применение функции к каждому столбцу; внутри кода он просто делает это: x[] <- lapply(x, .Generic, ...).

> foo <- matrix(1:6, ncol=3)
> df <- data.frame(foo)
> df
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
> cumsum(df)
  X1 X2 X3
1  1  3  5
2  3  7 11

Интересно, что sum не является частью Math, а является частью группы Summary общих функций; для кадров данных эта группа сначала преобразует кадр данных в матрицу, а затем вызывает общий тип, поэтому sum возвращает не столбцы, а общую сумму:

> sum(df)
[1] 21

Это несоответствие (на мой взгляд), скорее всего, потому что cumsum возвращает матрицу того же размера, что и оригинал, но sum не будет.

Для кумулятивных сумм по строкам не существует ни одной функции, которая реплицирует это поведение, о котором я знаю; Решение Iterator, вероятно, является одним из самых простых.

Если скорость является проблемой, она почти наверняка будет самой быстрой и надежной для записи на C; Тем не менее, он немного ускоряется (~ 2x?) для длинных циклов, используя простой цикл.

rowCumSums <- function(x) {
  for(i in seq_len(dim(x)[1])) { x[i,] <- cumsum(x[i,]) }; x
}
colCumSums <- function(x) {
  for(i in seq_len(dim(x)[2])) { x[,i] <- cumsum(x[,i]) }; x
}

Это можно ускорить, используя простой cumsum и вычитая сумму до тех пор, пока вы дойдете до конца столбца. Для суммарной суммы строк необходимо дважды транспонировать.

colCumSums2 <- function(x) {
  matrix(cumsum(rbind(x,-colSums(x))), ncol=ncol(x))[1:nrow(x),]
}
rowCumSums2 <- function(x) {
  t(colCumSums2(t(x)))
}

Это действительно взломать. Не делайте этого.

Ответ 4

С помощью data.table вы также можете использовать

dt <- as.data.table(df)
dt[, acc_sum := cumsum(count)]

Ответ 5

Альтернативой cumsum() может быть:

within(df, acc_sum <- Reduce("+", count, accumulate = TRUE))

   count acc_sum
1      1       1
2      2       3
3      3       6
4      4      10
5      5      15
6      6      21
7      7      28
8      8      36
9      9      45
10    10      55