1
votes

Comment créer une somme cumulée de chaque colonne d'un dataframe

J'ai rencontré des difficultés pour essayer de résoudre ce problème. J'ai un dataframe 4 variables:

df <- df1 %>% select(starts_with("cc"))

rows <- nrow(df) 

for(i in 2:rows) {
  df$cc_1[i] <- df$cc_1[i-1] + df$cc_1[i]
}

Mes variables cc ont une valeur de 1 à chaque fois que les variables rr correspondantes ont une valeur supérieure à 0. Ce que j'essaie d'accomplir est de créer un série cummulative pour les variables cc de telle sorte que le résultat final devrait ressembler à ceci:

df <- df1 %>% select(starts_with("cc"))
rows <- nrow(df) 

cc_cum <- function(x) {
             for(i in 2:rows) {
                 df$x[i] <- df$x[i-1] + df$x[i]
             }
          }

apply(df, 2, cc_cum)

J'ai essayé plusieurs choses pour résoudre ce problème.

(1 ) J'ai créé une fonction telle que:

df <- df1 %>% select(starts_with("cc"))

cc_cum <- function(x) {
          x <- as.vector(df$x)
          x <- cumsum(x)
          df$x <- x
}

apply(df, 2, cc_cum )

(2) J'ai créé des vecteurs:

df <- df1 %>% select(starts_with("cc"))
rows <- nrow(df) 

cc_cum <- function(x) {
        for(i in 2:rows) {
          df$x[i] <- df$x[i-1] + df$x[i]
        }

apply(df, 2, cc_cum)

(3) J'ai aussi essayé:

rr_1 rr_2 cc_1 cc_2
 100    0     1    0
 200  100     2    1
 300  300     3    2
 400  500     4    3
   0    0     4    3

La chose étrange est que toutes les solutions que j'ai essayées ci-dessus fonctionnent pour chaque colonne si je les supprime de la fonction et applique. Par exemple, ce code fonctionne

rr_1 rr_2 cc_1 cc_2
 100    0     1    0
 200  100     1    1
 300  300     1    1
 400  500     1    1
   0    0     0    0

Cependant, ce code doit être utilisé pour un ensemble de données plus grand qui aura plusieurs niveaux de cc et donc je ne peux pas prédire combien il y en aura. Je ne peux pas vraiment coder toutes les possibilités de cc.

Tout commentaire à ce sujet sera extrêmement utile.


0 commentaires

3 Réponses :


3
votes

Utilisez la fonction intégrée cumsum pour plusieurs colonnes avec lapply

library(dplyr)
df %>%  mutate_at(vars(starts_with("cc")), cumsum)

Ou avec dplyr , nous pouvons utiliser mutate_at pour sélectionner des colonnes spécifiques

cols <- grep("^cc", names(df))
df[cols] <- lapply(df[cols], cumsum)

df
#   rr_1 rr_2 cc_1 cc_2
#1  100    0    1    0
#2  200  100    2    1
#3  300  300    3    2
#4  400  500    4    3
#5    0    0    4    3


1 commentaires

Cela a très bien fonctionné. Merci. C'était si simple et je pense que je compliquais trop. Merci encore :)



0
votes
df <-data.frame("rr_1" = c(100,200,300,400,0), "rr_2" = c(0,100,300,500,0), "cc_1" = c(1,1,1,1,0),"cc_2"=c(0,1,1,1,0))

> df
  rr_1 rr_2 cc_1 cc_2
1  100    0    1    0
2  200  100    1    1
3  300  300    1    1
4  400  500    1    1
5    0    0    0    0

csum <- function(x) cumsum(x)

new_data <- data.frame(df[c("rr_1","rr_2")],sapply(df[c("cc_1","cc_2")],csum))

> new_data
  rr_1 rr_2 cc_1 cc_2
1  100    0    1    0
2  200  100    2    1
3  300  300    3    2
4  400  500    4    3
5    0    0    4    3


0 commentaires

1
votes

Une option avec data.table . Convertissez le 'data.frame' en 'data.table' ( setDT (df1) ), obtenez les noms du data.frame qui démarreQWith 'cc', spécifiez le .SDcols , parcourez le .SD , récupérez le cumsum et attribuez (: = ) la sortie à les colonnes d'intérêt

df1 <- structure(list(rr_1 = c(100L, 200L, 300L, 400L, 0L), rr_2 = c(0L, 
100L, 300L, 500L, 0L), cc_1 = c(1L, 1L, 1L, 1L, 0L), cc_2 = c(0L, 
1L, 1L, 1L, 0L)), class = "data.frame", row.names = c(NA, -5L
))

data

library(data.table)
nm1 <- names(df1)[startsWith(names(df1), "cc")]
setDT(df1)[, (nm1) := lapply(.SD, cumsum), .SDcols = nm1]
df1
#   rr_1 rr_2 cc_1 cc_2
#1:  100    0    1    0
#2:  200  100    2    1
#3:  300  300    3    2
#4:  400  500    4    3
#5:    0    0    4    3


0 commentaires