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