J'ai deux dataframes, je dois ajouter deux colonnes de ces deux et stocker le résultat dans le dataframe original plus grand, mais le dataframe le plus grand a beaucoup plus de colonne "branche" que le plus petit. J'ai essayé d'utiliser match mais les branches non correspondantes la somme est NA
Exemple de code:
> left_join(df1, df2, by = 'branch') branch rev Amt 1 a 10 NA 2 b 20 10 3 c 30 NA 4 d 40 10 5 e 50 NA > df1 <- left_join(df1, df2, by = 'branch') > df1[is.na(df1)] <- 0 > df1 branch rev Amt 1 a 10 0 2 b 20 10 3 c 30 0 4 d 40 10 5 e 50 0 > df1$rev <- df1$rev + df1$Amt > df1 branch rev Amt 1 a 10 0 2 b 30 10 3 c 30 0 4 d 50 10 5 e 50 0 > df1$Amt <- NULL > df1 branch rev 1 a 10 2 b 30 3 c 30 4 d 50 5 e 50 >
Résultat attendu
> df1 branch rev 1 a 10 2 b 30 3 c 30 4 d 50 5 e 50 >
J'ai essayé d'utiliser la jointure gauche comme ci-dessous:
> df1 <- data.frame(branch = letters[seq(1,5)], + rev = seq(10,50,10), + stringsAsFactors = 0) > df1 branch rev 1 a 10 2 b 20 3 c 30 4 d 40 5 e 50 > > df2 <- data.frame(branch = c('b','d'), + Amt = c(10,10), + stringsAsFactors = 0) > df2 branch Amt 1 b 10 2 d 10 > > df1$rev + df2[match(df1$branch,df2$branch),2,drop = 1] [1] NA 30 NA 50 NA >
Quelqu'un pourrait-il me faire savoir s'il existe une solution plus simple pour cela.
5 Réponses :
En utilisant dplyr
, vous pouvez agréger les deux dataframes en utilisant bind_rows
(et renommer Amt par rev afin de faire correspondre les noms de colonne), grouper par "branche" et calculer la somme:
library(dplyr) df1 %>% bind_rows(., rename(df2, rev = Amt)) %>% group_by(branch) %>% summarise(rev = sum(rev)) # A tibble: 5 x 2 branch rev <chr> <dbl> 1 a 10 2 b 30 3 c 30 4 d 50 5 e 50
Une option utilisant data.table
:
branch rev 1: a 10 2: b 30 3: c 30 4: d 50 5: e 50
output:
library(data.table) setDT(df1)[, rev := setDT(df2)[.SD, on=.(branch), rev + nafill(Amt, fill=0)] ]
Une façon serait de stocker la sortie de match
dans une variable, de remplacer
NA
par 0, puis d'ajouter des valeurs
library(dplyr) df1 %>% left_join(df2, by = 'branch') %>% mutate(Amt = replace(Amt, is.na(Amt), 0), rev = rev + Amt) %>% select(names(df1))
Que diriez-vous de cela, aucune bibliothèque requise:
df1 <- df1[order(df1$branch),] #sort based on branch df2 <- df2[order(df2$branch),] #sort also so next step works df1$branch[df1$branch %in% df2$branch] #just to check we are on correct path #do the task df1$rev[df1$branch %in% df2$branch] <- df1$rev[df1$branch %in% df2$branch] + df2$Amt[df2$branch %in% df1$branch]
Attention - s'il y a des valeurs de "branche" répétées dans df2 ... par exemple. deux "b", vous devrez les accumuler avant de les ajouter à df1.
Utilisez aggregate
pour obtenir la somme des rév dans différents groupes de branches.
library(magrittr) colnames(df2)[2] <- "rev" df1 <- rbind(df1, df2) %>% aggregate(rev ~ branch, ., FUN = sum)