1
votes

Comment ajouter deux colonnes à partir de deux dataframes différentes dans R où une colonne a juste un sous-ensemble de valeurs uniques de l'autre

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.


0 commentaires

5 Réponses :


1
votes

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


0 commentaires

2
votes

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)]
]


0 commentaires

1
votes

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))


0 commentaires

2
votes

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.


0 commentaires

0
votes

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)


0 commentaires