superponer - Cálculo de la suma acumulada para cada fila.
superponer graficas en r (4)
Con data.table
también puedes usar
dt <- as.data.table(df)
dt[, acc_sum := cumsum(count)]
Estoy tratando de calcular la suma acumulada para cada fila usando el siguiente código:
df <- data.frame(count=1:10)
for (loop in (1:nrow(df)))
{df[loop,"acc_sum"] <- sum(df[1:loop,"count"])}
Pero no me gusta el bucle explícito aquí, ¿cómo puedo modificarlo?
Para replicar el resultado del OP, la función de cumsum
es todo lo que se necesita, como muestra la respuesta de Chase. Sin embargo, la redacción del OP "para cada fila" posiblemente indique interés en las sumas acumuladas de una matriz o marco de datos.
Para las columnas de un data.frame, curiosamente, ¡ cumsum
es de nuevo todo lo que uno necesita! cumsum
es una primitiva que forma parte del grupo Math
de funciones genéricas, que se define para los marcos de datos que aplican la función a cada columna; dentro del código, simplemente hace esto: 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
Curiosamente, la sum
no es parte de Math
, sino parte del grupo Summary
de funciones genéricas; para marcos de datos, este grupo primero convierte el marco de datos en una matriz y luego llama al genérico, por lo que la sum
devuelve no sumas por columnas, sino la suma general:
> sum(df)
[1] 21
Esta discrepancia es (en mi opinión) más probable porque el cumsum
devuelve una matriz del mismo tamaño que el original, pero la sum
no lo haría.
Para las sumas acumuladas por filas, no hay una sola función que replique este comportamiento que yo sepa; La solución de Iterator es probablemente una de las más directas.
Si la velocidad es un problema, es casi seguro que sería más rápido y más infalible escribirlo en C; sin embargo, se acelera un poco (¿2x?) para bucles largos utilizando un bucle simple para.
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
}
Esto se puede acelerar más usando la cumsum
simple y restando la suma hasta el momento en que se llega al final de una columna. Para las sumas acumuladas de filas, se necesita transponer dos veces.
colCumSums2 <- function(x) {
matrix(cumsum(rbind(x,-colSums(x))), ncol=ncol(x))[1:nrow(x),]
}
rowCumSums2 <- function(x) {
t(colCumSums2(t(x)))
}
Eso es realmente un hack sin embargo. No lo hagas
Quieres cumsum()
df <- within(df, acc_sum <- cumsum(count))
También puede probar mySum = t(apply(df, 1, cumsum))
.
La transposición está ahí porque los resultados se transponen, por una razón que aún no he determinado.
Estoy seguro de que hay buenas soluciones con plyr
, como los métodos ddply
y multinúcleo.