IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

R Discussion :

Comment merger deux data frame avec des conditions spécifiques ?


Sujet :

R

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Epitech
    Inscrit en
    Mai 2019
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Epitech

    Informations forums :
    Inscription : Mai 2019
    Messages : 33
    Par défaut Comment merger deux data frame avec des conditions spécifiques ?
    Bonjour,

    J'aimerais merger deux data frame selon le schéma suivant :

    voici le data frame df1 :

    Numéro - Nom - Quantité

    001 - Azer - 2
    001 - Azer - 5
    004 - Zert - 10
    008 - Erty - 4

    Et un autre df2 :

    Numéro - Nom - Prix

    001 - Azer - 34
    004 - Abc - 35
    006 - Erty - 36
    007 - Yopy - 37

    Et mon résultat attendu est le suivant :

    001 - Azer - 2 - 34
    001 - Azer - 5 - 34
    004 - Zert - 10 - 35
    008 - Erty - 4 - 36

    Il faut en fait que soit au moins le Numéro ou le Nom du data frame df1 correspondent à celui de df2 et ainsi rajouter la colonne prix.

    J'ai déjà essaye d'utiliser la fonction merge cependant j'obtiens seulement les lignes qui ont à la fois le numéro et le nom en commun pas celles ou seulement soit le numéro soit le nom correspond.

    Merci de votre compréhension,

    Arkning.

  2. #2
    Membre Expert
    Inscrit en
    Novembre 2009
    Messages
    707
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 707
    Par défaut merge update
    Bonjour,

    Voici une proposition :

    • Création des dataframes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    > df1 <- data.frame(Numero=c(001,001,004,008),
    +                   Nom=c("Azer","Azer","Zert","Erty"),
    +                   Quantite=c(2,5,10,4))
    > df1
      Numero  Nom Quantite
    1      1 Azer        2
    2      1 Azer        5
    3      4 Zert       10
    4      8 Erty        4
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    > df2 <- data.frame(Numero=c(001,004,006,007),
    +                   Nom=c("Azer","Abc","Erty","Yopy"),
    +                   Prix=c(34,35,36,36))
    > df2
      Numero  Nom Prix
    1      1 Azer   34
    2      4  Abc   35
    3      6 Erty   36
    4      7 Yopy   36
    • Merge sur le numéro

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    > dfa <- merge(df1,df2[,c("Numero","Prix")],by="Numero")
    > dfa
      Numero  Nom Quantite Prix
    1      1 Azer        2   34
    2      1 Azer        5   34
    3      4 Zert       10   35
    • Merge sur le nom

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    > dfb <- merge(df1,df2[,c("Nom","Prix")],by="Nom")
    > dfb
      Numero  Nom Quantite Prix
    1      1 Azer        2   34
    2      1 Azer        5   34
    3      8 Erty        4   36
    • Merge global

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    > df <- merge(dfa,dfb,by=c("Numero","Nom","Quantite"),all=T, suffixes=c("",".update"))
    > df
      Numero  Nom Quantite Prix Prix.update
    1      1 Azer        2   34          34
    2      1 Azer        5   34          34
    3      4 Zert       10   35          NA
    4      8 Erty        4   NA          36
    • Mise à jour des données

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    > df$Prix <- ifelse(!is.na(df$Prix.update),df$Prix.update,df$Prix)
    > df$Prix.update <- NULL
    > df
      Numero  Nom Quantite Prix
    1      1 Azer        2   34
    2      1 Azer        5   34
    3      4 Zert       10   35
    4      8 Erty        4   36
    Voir aussi cette discussion.

    Cordialement,

  3. #3
    Membre averti
    Homme Profil pro
    Epitech
    Inscrit en
    Mai 2019
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Epitech

    Informations forums :
    Inscription : Mai 2019
    Messages : 33
    Par défaut
    Citation Envoyé par mgdondon Voir le message
    Bonjour,

    Voici une proposition :

    • Création des dataframes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    > df1 <- data.frame(Numero=c(001,001,004,008),
    +                   Nom=c("Azer","Azer","Zert","Erty"),
    +                   Quantite=c(2,5,10,4))
    > df1
      Numero  Nom Quantite
    1      1 Azer        2
    2      1 Azer        5
    3      4 Zert       10
    4      8 Erty        4
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    > df2 <- data.frame(Numero=c(001,004,006,007),
    +                   Nom=c("Azer","Abc","Erty","Yopy"),
    +                   Prix=c(34,35,36,36))
    > df2
      Numero  Nom Prix
    1      1 Azer   34
    2      4  Abc   35
    3      6 Erty   36
    4      7 Yopy   36
    • Merge sur le numéro

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    > dfa <- merge(df1,df2[,c("Numero","Prix")],by="Numero")
    > dfa
      Numero  Nom Quantite Prix
    1      1 Azer        2   34
    2      1 Azer        5   34
    3      4 Zert       10   35
    • Merge sur le nom

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    > dfb <- merge(df1,df2[,c("Nom","Prix")],by="Nom")
    > dfb
      Numero  Nom Quantite Prix
    1      1 Azer        2   34
    2      1 Azer        5   34
    3      8 Erty        4   36
    • Merge global

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    > df <- merge(dfa,dfb,by=c("Numero","Nom","Quantite"),all=T, suffixes=c("",".update"))
    > df
      Numero  Nom Quantite Prix Prix.update
    1      1 Azer        2   34          34
    2      1 Azer        5   34          34
    3      4 Zert       10   35          NA
    4      8 Erty        4   NA          36
    • Mise à jour des données

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    > df$Prix <- ifelse(!is.na(df$Prix.update),df$Prix.update,df$Prix)
    > df$Prix.update <- NULL
    > df
      Numero  Nom Quantite Prix
    1      1 Azer        2   34
    2      1 Azer        5   34
    3      4 Zert       10   35
    4      8 Erty        4   36
    Voir aussi cette discussion.

    Cordialement,
    Bonjour,

    Tout d'abord je vous remercie de votre réponse, j'avais pensé à le faire en deux étapes comme vous mais je pensais que c'était possible en une seule mais cette solution me convient très bien.
    Juste une dernière chose, est-il toujours possible de merger mais j'aimerais maintenant (sans modifier le résultat de fin) comparer les "Numéro" sans les 0 qui pourrait se situer au début et de comparer les "Nom" sans espaces et tout en majuscules.

    Bien à vous,

    Arkning

  4. #4
    Membre Expert
    Inscrit en
    Novembre 2009
    Messages
    707
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 707
    Par défaut Nettoyage de données
    Bonjour,

    Citation Envoyé par Arkning Voir le message
    Juste une dernière chose, est-il toujours possible de merger mais j'aimerais maintenant (sans modifier le résultat de fin) comparer les "Numéro" sans les 0 qui pourrait se situer au début et de comparer les "Nom" sans espaces et tout en majuscules.
    Là c'est du nettoyage de données :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    > Numero <- "01"
    > as.numeric(as.character(Numero))
    [1] 1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    > Nom <- " Az er"
    > stringr:::str_trim(toupper(Nom))
    [1] "AZ ER"
    > stringr:::str_replace_all(toupper(Nom)," ", "")
    [1] "AZER"
    Cordialement,

  5. #5
    Membre averti
    Homme Profil pro
    Epitech
    Inscrit en
    Mai 2019
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Epitech

    Informations forums :
    Inscription : Mai 2019
    Messages : 33
    Par défaut
    Citation Envoyé par mgdondon Voir le message
    Bonjour,



    Là c'est du nettoyage de données :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    > Numero <- "01"
    > as.numeric(as.character(Numero))
    [1] 1
    > 
    > Nom <- " Azer"
    > stringr:::str_trim(toupper(Nom))
    [1] "AZER"
    Cordialement,
    Non justement je ne veux pas nettoyer mes données je veux que cela se passe pendant la comparaison des données mais sans modifier la donnée en elle même. Example

    Numéro - Nom - Quantité
    0102 - Azer - 5

    Numéro - Nom - Prix
    102 - az er - 8

    Résultat :
    0102 - Azer - 5 - 8

  6. #6
    Membre émérite
    Homme Profil pro
    Inscrit en
    Janvier 2006
    Messages
    491
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Corse (Corse)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 491
    Par défaut
    bonsoir

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    library(tydiverse)
     
    df<- df1%>% inner_join(df2, by = c("Numéro",  "Nom"))

  7. #7
    Membre Expert
    Inscrit en
    Novembre 2009
    Messages
    707
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 707
    Par défaut merge inner_join
    Bonjour,

    Vous avez répondu un peu rapidement il me semble.

    Votre code correspond à un merge strict :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    > merge(df1,df2,by=c("Numero","Nom"))
      Numero  Nom Quantite Prix
    1      1 Azer        2   34
    2      1 Azer        5   34
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    > library(tidyverse)
    > df1 %>% inner_join(df2,by=c("Numero","Nom"))
      Numero  Nom Quantite Prix
    1      1 Azer        2   34
    2      1 Azer        5   34
    De plus la demande est de faire un merge sur la variable Numero OU sur la variable Nom.

    Cordialement,

  8. #8
    Membre émérite
    Homme Profil pro
    Inscrit en
    Janvier 2006
    Messages
    491
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Corse (Corse)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 491
    Par défaut
    bonjour , oui j'ai répondu trop rapidement mais surtout j'ai lu trop rapidement et mal lu...
    un autre essai pour me rattraper

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    library(tidyverse)
     df <- df1 %>% inner_join(df2 %>% select(-Nom),by=c("Numero")) %>% 
       bind_rows(df1 %>% inner_join(df2%>% select(-Numero),by=c("Nom"))) %>% 
       distinct()
    juste une petite remarque : je pense qu'il faudrait revoir la structuration des données
    cordialement

  9. #9
    Membre Expert
    Inscrit en
    Novembre 2009
    Messages
    707
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 707
    Par défaut Nettoyage de données
    Remarquez que je n'ai pas modifié les données. Vous pouvez choisir de les modifier ou au contraire de créer des variables temporaires qui vous serviront pour le merge.

    Cordialement,

  10. #10
    Membre averti
    Homme Profil pro
    Epitech
    Inscrit en
    Mai 2019
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Epitech

    Informations forums :
    Inscription : Mai 2019
    Messages : 33
    Par défaut
    Citation Envoyé par mgdondon Voir le message
    Remarquez que je n'ai pas modifié les données. Vous pouvez choisir de les modifier ou au contraire de créer des variables temporaires qui vous serviront pour le merge.

    Cordialement,
    Bonjour,

    Oui je le sais très bien je ne remets pas en cause ce que vous avez fait au contraire je vous remercie de m'avoir aider. Je voulais juste savoir si vous aviez une idée de comment merger avec les contraintes précédemment expliquées. En effet les données avec lesquelles je travail on cette particularité j'ai réussi à le faire mais j'ai du modifier les données or je veux justement obtenir le résultat sans modifier les données si c'est possible.
    Donc d'après votre expertise je devrais créer des variables temporaires pour le merge pourriez-vous me donner un exemple ou m'expliquer un peu plus en détails si vous le voulez bien ?

    Cordialement,

    Arkning

  11. #11
    Membre Expert
    Inscrit en
    Novembre 2009
    Messages
    707
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 707
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    > df1 <- data.frame(Numero=c("001","001","004","008"),
    +                   Nom=c("Azer","Azer","Zert","Erty"),
    +                   Quantite=c(2,5,10,4))
    > df1$Numero_tmp <- as.numeric(as.character(df1$Numero))
    > df2 <- data.frame(Numero=c("1","004","006","007"),
    +                   Nom=c("Azer","Abc","Erty","Yopy"),
    +                   Prix=c(34,35,36,36))
    > df2$Numero_tmp <- as.numeric(as.character(df2$Numero))
    > dfa <- merge(df1,df2[,c("Numero_tmp","Prix")],by="Numero_tmp")
    > dfa
      Numero_tmp Numero  Nom Quantite Prix
    1          1    001 Azer        2   34
    2          1    001 Azer        5   34
    3          4    004 Zert       10   35
    Cordialement,

  12. #12
    Membre averti
    Homme Profil pro
    Epitech
    Inscrit en
    Mai 2019
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Epitech

    Informations forums :
    Inscription : Mai 2019
    Messages : 33
    Par défaut
    Citation Envoyé par mgdondon Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    > df1 <- data.frame(Numero=c("001","001","004","008"),
    +                   Nom=c("Azer","Azer","Zert","Erty"),
    +                   Quantite=c(2,5,10,4))
    > df1$Numero_tmp <- as.numeric(as.character(df1$Numero))
    > df2 <- data.frame(Numero=c("1","004","006","007"),
    +                   Nom=c("Azer","Abc","Erty","Yopy"),
    +                   Prix=c(34,35,36,36))
    > df2$Numero_tmp <- as.numeric(as.character(df2$Numero))
    > dfa <- merge(df1,df2[,c("Numero_tmp","Prix")],by="Numero_tmp")
    > dfa
      Numero_tmp Numero  Nom Quantite Prix
    1          1    001 Azer        2   34
    2          1    001 Azer        5   34
    3          4    004 Zert       10   35
    Cordialement,
    Bonjour,

    Merci de votre retour donc si je veux faire la même chose pour comparer les "Nom" en majuscules et sans espace je devrais faire quelque chose comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    > df1 <- data.frame(Numero=c("001","001","004","008"),
    +                   Nom=c("Azer","Azer","Zert","Erty"),
    +                   Quantite=c(2,5,10,4))
    > df1$Numero_tmp <- toupper(str_replace_all(df1$Numero, " ", ""))
    Bien à vous,

    Arkning

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Supprimer des Lignes d'une Frame avec des conditions
    Par stephane.nguessan dans le forum R
    Réponses: 4
    Dernier message: 13/02/2019, 17h03
  2. Faire un aggrégat en R avec deux data frame
    Par Valarion dans le forum R
    Réponses: 1
    Dernier message: 08/10/2018, 10h11
  3. Concatener deux chaines avec des conditions
    Par adeniss dans le forum C
    Réponses: 8
    Dernier message: 13/04/2018, 06h21
  4. Réponses: 4
    Dernier message: 27/06/2012, 20h40
  5. Réponses: 4
    Dernier message: 07/11/2005, 15h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo