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

SAS Base Discussion :

Suppression doublons en fonction des observations en colonne et non des observations en ligne


Sujet :

SAS Base

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 71
    Points : 67
    Points
    67
    Par défaut Suppression doublons en fonction des observations en colonne et non des observations en ligne
    Bonjour,

    Je voudrais supprimer des observations selon qu'ils aient des colonnes de valeurs identiques. Est-ce-possible ?

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    data test; 
    input var $ id1 id2 id3;
    cards;
    a 1 2 3
    b 1 2 2
    c 1 3 3
    d 1 1 2
    e 2 3 4
    f 3 4 5
    g 3 3 4
    ;
    run;
    Je souhaiterais simplement conserver les lignes : {a 1 2 3} ; {e 2 3 4} et {f 3 4 5}

    Merci par avance.

  2. #2
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    Bonjour,

    que cherche tu exactement à faire ?

    Je te pose cette question, car si l'élimination de b,c et d, de même que g, peut se concevoir, l'élimination de e est moins évidente.

    Peux tu expliciter les règles appliquées pour arriver à la sélection de a et f et à la suppression de b,c,d,e et g.

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 71
    Points : 67
    Points
    67
    Par défaut
    Exact, je m'étais trompé dans mon exemple. Je conserve bien la ligne {e 2 3 4}. J'ai corrigé le message original.
    Ainsi, on converse a, e et f car pour chacun d'entre eux, id1, id2 et id3 sont différents. Alors qu'on supprime b,c,d et g car pour chacun d'entre eux, ils ont au moins id1=id2 ou id1=id3 ou id2=id3.

  4. #4
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    Ce qui veut dire également que la sélection se fait dans l'ordre de lecture du fichier.

    Le problème mérite réflexion...

    Bon, j'aurais quand même fait avancer le schmilblick en te faisant préciser ton problème !


    Edit :

    Il y a bien une solution pas trop compliquée à base de table hash (désolé je suis en plein dedans en ce moment... ) mais il faut la coder.

    Tu défini une table hash Ref avec une options multidata.
    En identifiant tu prend une variable caractère id et ta variable Var en donnée (que je ne présuppose pas comme étant de longueur 1, a b c etc.. c'est juste pour l'exemple que tu as proposé ces identifiants sur 1 caractères).

    Par exemple en initialisation avec ta première observation le tableau associatif Ref va contenir

    Id Var
    1 a
    2 a
    3 a

    Ensuite tu passe à l'observation suivante.
    Tu défini un tableau associatif Compare avec Var en identifiant et Sum en données.

    Pour chaque Id1 Id2 Id3 de ton observation tu va chercher les correspondant dans la table Ref. A chaque correspondant trouvé tu met Sum=1 si c'est la première fois et Sum=Sum+1 sinon via un replace dans Compare.

    Ce qui te fait successivement

    Id1=1
    Tableau association compare

    Var Sum
    a 1

    Id2=2
    Tableau association compare

    Var Sum
    a 2

    Id3=2
    Tableau association compare

    Var Sum
    a 3

    A la fin tu regarde si le tableau Compare contient un élément avec Sum=3.

    Si oui alors l'observation lue est un doublon.
    Si non l'observation est à conserver et dans ce cas on met à jour également REF avec les données de l'observation.

    Et on passe à la ligne suivante.

    Etc...


    Il y a peut-être plus simple, alors je laisse les autres te répondre si ils ont une idée plus lumineuse...

  5. #5
    Membre actif
    Homme Profil pro
    KEYRUS - Chef de projet
    Inscrit en
    Avril 2014
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : KEYRUS - Chef de projet

    Informations forums :
    Inscription : Avril 2014
    Messages : 45
    Points : 277
    Points
    277
    Par défaut
    Bonjour,

    Je n'ai pas bien compris ta réponse jerome.

    La suppression des lignes ne se fait pas uniquement ligne à ligne à partir du moment où on a l'égalité ?

    D'après ma compréhension, il faut simplement tester Si ID1=ID2 ou ID2=ID3 ou ID1=ID3 mais je n'ai peut être rien compris.

  6. #6
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    A ce que j'ai compris

    Cas 1
    a 1 2 3
    b 1 2 2
    c 1 3 3
    d 1 1 2
    e 2 3 4
    f 3 4 5
    g 3 3 4

    ou cas 2

    a 1 2 3
    c 1 3 3
    d 1 1 2
    e 2 3 4
    f 3 4 5
    g 3 3 4
    b 1 2 2

    devraient être équivalents (faut voir si effectivement c'est ce que cherche Aleksik en fait)

    car dans les deux cas on ne conserve que a, e et f.

    Sauf que dans le cas 2 il faut aller chercher la première observation pour se rendre contre que la dernière est en doublon (à confirmer par Aleksik). Donc si on compare ligne à ligne (c'est à dire pour moi ligne N vs ligne N-1 on ne va pas y arriver aussi simplement, sauf si il y a de bonnes raisons pour qu'on arrive... à voir).

    Après y a peut-être des choses que je n'ai pas vue...

  7. #7
    Membre actif
    Homme Profil pro
    KEYRUS - Chef de projet
    Inscrit en
    Avril 2014
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : KEYRUS - Chef de projet

    Informations forums :
    Inscription : Avril 2014
    Messages : 45
    Points : 277
    Points
    277
    Par défaut
    Désolé toujours pas plus clair pour moi.

    Dans ton cas 2, la dernière ligne est supprimée car ID2=ID3 (sans lien avec la première ligne)

  8. #8
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    Non ce n'est pas cette règle là,

    c'est b 1 2 2 éliminée par ce que les éléments {1,2} de b sont inclus dans les éléments {1,2,3} de a

    moi c'est ce que j'ai compris...

    A la relecture c'est peut-être aussi simple que ce que tu as compris toi

    Aleksik nous dira.

  9. #9
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    @cmy_keyrus


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    id1=id2 ou id1=id3 ou id2=id3.
    (sic) aleksik...

    Tu semble avoir raison, autant pour moi...

    Bah...bizarre de poser une question aussi basique...

    @Aleksik où est la difficulté à faire les delete nécessaires ?

  10. #10
    Membre expérimenté
    Homme Profil pro
    Développeur en SAS/ Statisticien
    Inscrit en
    Janvier 2013
    Messages
    483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur en SAS/ Statisticien
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2013
    Messages : 483
    Points : 1 552
    Points
    1 552
    Par défaut
    Bonjour,
    Avec un array on peut faire la section souhaitée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    data test; 
    input var $ id1 id2 id3;
    cards;
    a 1 2 3
    b 1 2 2
    c 1 3 3
    d 1 1 2
    e 2 3 4
    f 3 4 5
    g 3 3 4
    ;
    run;
    data test1 (drop=cnt i j );
    set test ;
    array mat(3) id1-id3 ;	cnt=0 ;
    do i=1 to dim(mat)-1 ;
      do j=2 to dim(mat) ;
      if i ne j then do ; if mat(i)=mat(j) then cnt+1 ;	 end ;
    end ; end ;
    if cnt=0 then output ;
    run ;
    Ward

  11. #11
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 71
    Points : 67
    Points
    67
    Par défaut
    Oui ce n'est pas compliqué comme ça, mais je travaille sur des dataset dont le nombre de colonne fluctue. Et plus mon nombre de colonne augmentent plus il revient difficile de vérifier si id1=id2 ; si id1=id3 etc. Car cela revient à des combinaisons.

    Pour 5 colonnes je dois tester :
    Choix de 2 parmi 5 = 10
    id1=id2
    id1=id3
    id1=id4
    id1=id5
    id2=id3
    id2=id4
    id2=id5
    id3=id4
    id3=id4
    id3=id5

    Ça reste possible à faire en macro mais je me disais que peut être il y avait une option comme nodupkey mais en regardant les colonnes.

  12. #12
    Membre actif
    Homme Profil pro
    KEYRUS - Chef de projet
    Inscrit en
    Avril 2014
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : KEYRUS - Chef de projet

    Informations forums :
    Inscription : Avril 2014
    Messages : 45
    Points : 277
    Points
    277
    Par défaut
    Un peu compléiqué comme solution hossward.

    Un simple if suffira je pense

  13. #13
    Membre actif
    Homme Profil pro
    KEYRUS - Chef de projet
    Inscrit en
    Avril 2014
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : KEYRUS - Chef de projet

    Informations forums :
    Inscription : Avril 2014
    Messages : 45
    Points : 277
    Points
    277
    Par défaut
    Si ton nombre de colonnes varie, tu peux effectivement passer par le macro langage pour rendre dynamique ta clé.

    Nodupkey sur ta clé fonctionne parfaitement

  14. #14
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    ok, il existe une borne supérieure pour le nombre de variables à comparer ?

  15. #15
    Membre expérimenté
    Homme Profil pro
    Développeur en SAS/ Statisticien
    Inscrit en
    Janvier 2013
    Messages
    483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur en SAS/ Statisticien
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2013
    Messages : 483
    Points : 1 552
    Points
    1 552
    Par défaut
    Avec un simple if id2 sera comparé deux fois avec lui même !

  16. #16
    Membre actif
    Homme Profil pro
    KEYRUS - Chef de projet
    Inscrit en
    Avril 2014
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : KEYRUS - Chef de projet

    Informations forums :
    Inscription : Avril 2014
    Messages : 45
    Points : 277
    Points
    277
    Par défaut
    Je vois pas bien pourquoi.
    Cela dépend de ce que tu mets dans ton if.


    Néanmoins, ta solution avec l'array présente l'avantage de fonctionner simplement en indiquant le nombre de champ IDx

  17. #17
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 71
    Points : 67
    Points
    67
    Par défaut
    Merci jerome_pdv2, cmy_keyrus et hossward pour cet échange.

    La solution de hossward me convient, modifiée légèrement afin de simplement prendre en compte mon nombre de variable.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    data test; 
    input var $ id1 id2 id3 id4;
    cards;
    a 1 2 3 3
    b 1 2 2 3
    c 1 3 3 4
    d 1 1 2 4
    e 2 3 4 5
    f 3 4 5 6
    g 3 3 4 7
    ;
    run;
     
    data test2 (drop=cnt i j );
    set test ;
    array mat id: ;	cnt=0 ;
    do i=1 to dim(mat)-1 ;
      do j=2 to dim(mat) ;
      if i ne j then do ; if mat(i)=mat(j) then cnt+1 ;	 end ;
    end ; end ;
    if cnt=0 then output ;
    run ;

  18. #18
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 71
    Points : 67
    Points
    67
    Par défaut
    Citation Envoyé par jerome_pdv2 Voir le message
    ok, il existe une borne supérieure pour le nombre de variables à comparer ?
    Pas vraiment Jérôme, mais je ne pense pas aller à plus de 10 variables.

  19. #19
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    Ok,

    je te posais la question car si tu avais beaucoup de variables à comparer, il y a un problème de performance à comparer toutes les variables 2 à 2 (c'est un problème en N^2).

    Pour N=10 N^2=100 ça va encore
    pour N=200 N^2=40 000 ça devient plus compliqué.

    Si ton but était d'avoir un problème en temps de résolution polynomial en N et non en N^2 voici une solution

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
    data test; 
    input var $ id1 id2 id3;
    cards;
    a 1 2 3
    b 1 2 2
    c 1 3 3
    d 1 1 2
    e 2 3 4
    f 3 4 5
    g 3 3 4
    ;
    run;
     
    %LET NbValeur=3 ;
     
     
    DATA SS_DOUBLONS;
    LENGTH Val 8. ;
    ARRAY T{3} id1-id&NbValeur ;
    IF _N_=1 THEN 	DO;
    DECLARE HASH VALEUR();
    VALEUR.DefineKey('Val');
    VALEUR.DefineDone();
    				END;
     
    SET test;
    Ctrle="  ";
    NObj=VALEUR.Num_Items;IF NObj^=0 THEN RC=VALEUR.Clear();
     
    DO I=1 TO &NbValeur;
    	Val=T[I];
    	RC=VALEUR.Find();
    	IF RC^=0 	THEN RC=VALEUR.ADD();
    				ELSE DO;Ctrle='OK';PUT Ctrle= ;LEAVE;END;
    PUT _n_= I= Ctrle= ;
    END;
     
    IF Ctrle^="OK" THEN OUTPUT;
    DROP RC I VAL NObj Ctrle ;
    RUN;

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

Discussions similaires

  1. Fonction qui retourne un tableau et non des lignes
    Par siro1 dans le forum Débuter
    Réponses: 9
    Dernier message: 24/03/2014, 15h26
  2. enregistrer en fonction des noms de colonnes
    Par jeff6868 dans le forum R
    Réponses: 2
    Dernier message: 26/04/2012, 17h28
  3. Réponses: 3
    Dernier message: 12/01/2012, 17h07
  4. Doublon des titres de colonne suite à une rupture
    Par Alexis33 dans le forum Webi
    Réponses: 5
    Dernier message: 02/11/2011, 14h17
  5. rajouter des doublons avec une macro dans une colonne
    Par Banel dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 07/08/2008, 23h58

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