Я пытаюсь вычислить суммарную сумму для каждой строки, используя следующий код:
df <- data.frame(count=1:10)
for (loop in (1:nrow(df)))
{df[loop,"acc_sum"] <- sum(df[1:loop,"count"])}
Но мне не нравится явный цикл здесь, как его изменить?
Я пытаюсь вычислить суммарную сумму для каждой строки, используя следующий код:
df <- data.frame(count=1:10)
for (loop in (1:nrow(df)))
{df[loop,"acc_sum"] <- sum(df[1:loop,"count"])}
Но мне не нравится явный цикл здесь, как его изменить?
Вы хотите cumsum()
df <- within(df, acc_sum <- cumsum(count))
Вы также можете попробовать mySum = t(apply(df, 1, cumsum))
.
Транспортировка там, потому что результаты выходят транспонированными, по какой-то причине я еще не определился.
Я уверен, что есть прекрасные решения с plyr
, такие как ddply
и многоядерные методы.
Чтобы реплицировать результат 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)))
}
Это действительно взломать. Не делайте этого.
С помощью data.table
вы также можете использовать
dt <- as.data.table(df)
dt[, acc_sum := cumsum(count)]
Альтернативой 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