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.
3 Réponses :
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
Cela a très bien fonctionné. Merci. C'était si simple et je pense que je compliquais trop. Merci encore :)
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
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 ))
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