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 :

Condition sur un sous-ensemble d'observations


Sujet :

SAS Base

  1. #1
    Futur Membre du Club
    Femme Profil pro
    Stat
    Inscrit en
    janvier 2020
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 24
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Stat
    Secteur : Santé

    Informations forums :
    Inscription : janvier 2020
    Messages : 11
    Points : 8
    Points
    8
    Par défaut Condition sur un sous-ensemble d'observations
    Bonjour,
    Je souhaiterais travailler sur un sous-ensemble d'observations, c'est-à-dire par identifiant. Je m'explique:

    ID BLOC STATUT
    1 1 1
    1 2 3
    1 3 2
    2 1 1
    3 1 1
    3 2 1

    Mon code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    DATA matable;
    SET matable;
    IF BLOC = 1 and STATUT = 1 then STATUT2 = "en cours";
    run;
    Je souhaiterais obtenir :

    ID BLOC STATUT STATUT2
    1 1 1 "en cours"
    1 2 3 "en cours"
    1 3 2 "en cours"
    2 1 1
    3 1 1
    3 2 1

    Or pour l'instant, "en cours" ne s'affiche que sur la première ligne.

    Merci,
    Garpe

  2. #2
    Membre expérimenté
    Inscrit en
    novembre 2009
    Messages
    698
    Détails du profil
    Informations forums :
    Inscription : novembre 2009
    Messages : 698
    Points : 1 300
    Points
    1 300
    Par défaut Etape data
    Bonjour,

    Votre code fonctionne correctement :

    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
    data matable;
      input id bloc statut;
      cards;
    1 	1 	1
    1 	2 	3
    1 	3 	2
    2 	1 	1
    3 	1 	1
    3 	2 	1
    ;
    run;
     
    data matable;
      set matable;
      if bloc=1 and statut=1 then statut2="en cours";
    run;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    id    bloc    statut    statut2
     1      1        1      en cours
     1      2        3
     1      3        2
     2      1        1      en cours
     3      1        1      en cours
     3      2        1
    Cordialement,

  3. #3
    Futur Membre du Club
    Femme Profil pro
    Stat
    Inscrit en
    janvier 2020
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 24
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Stat
    Secteur : Santé

    Informations forums :
    Inscription : janvier 2020
    Messages : 11
    Points : 8
    Points
    8
    Par défaut
    Bonjour, merci pour votre réponse. Je me suis peut-être mal exprimée, en fait je souhaiterais que "en cours" s'affiche pour toutes les lignes de l'individu 1 : c'est-à-dire que si l'individu 1 a le statut 1 pour le bloc 1 alors statut2 vaut "en cours" pour tous ses blocs (1, 2 et 3). Ce qui n'est pas le cas actuellement...

    Bien à vous,
    Garpe

  4. #4
    Membre expérimenté
    Inscrit en
    novembre 2009
    Messages
    698
    Détails du profil
    Informations forums :
    Inscription : novembre 2009
    Messages : 698
    Points : 1 300
    Points
    1 300
    Par défaut merge
    Pardon, j'ai lu trop vite.

    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 matable;
      input id bloc statut;
      cards;
    1 1 1
    1 2 3
    1 3 2
    2 1 1
    3 1 1
    3 2 1
    ;
    run;
     
    data statut2(keep=id statut2);
      set matable;
      if id=1 and bloc=1 and statut=1;
      statut2="en cours";
    run;
     
    data matable;
      merge matable statut2;
      by ID;
    run;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    id    bloc    statut    statut2
     1      1        1      en cours
     1      2        3      en cours
     1      3        2      en cours
     2      1        1
     3      1        1
     3      2        1
    Cordialement,

  5. #5
    Futur Membre du Club
    Femme Profil pro
    Stat
    Inscrit en
    janvier 2020
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 24
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Stat
    Secteur : Santé

    Informations forums :
    Inscription : janvier 2020
    Messages : 11
    Points : 8
    Points
    8
    Par défaut
    Merci pour votre rapidité! Désolée, ça ne fonctionne pas sur mes données car j'avais simplifié le problème. Je ne l'ai pas précisé mais cette condition fait partie d'une sous-condition: voici mon "vrai" code:

    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
    data matable;
      input ID BLOC STATUT;
      cards;
    1 	1 	1
    1 	2 	2
    1 	3 	4
    2 	1 	1
    2      2       4
    2      3       1
    3 	1 	1
    3 	2 	1
    3      3       2
    ;
    run;
     
    PROC SORT data = matable;
    By ID descending BLOC;
    run;
     
    DATA matable;
    SET matable;
    by ID;
    IF BLOC= 1 and Statut= 4  then statut_prov = "A FAIRE"; 
    IF BLOC= 1 and Statut^= 4 then statut_prov = "EN COURS";
    IF first.ID and BLOC= 3 and Statut= 1 then statut2= "EN COURS";
    IF first.ID and BLOC= 3 and Statut= 2 then statut2= "A VALIDER";
    IF first.ID and BLOC= 3 and Statut= 4 then statut2 = statut_prov;
    RUN;
    (en français cela donne: pour un individu i, si bloc = 3 et statut = 4 et si bloc = 1 et statut = 4 alors statut2 = "à faire", sinon statut2 = "en cours")

    Avec votre proposition, d'après ce que j'ai testé, "en cours" écrase tous les statut2 déjà attribués (càd par exemple les personnes qui auraient bloc = 3 et statut = 2 mais bloc = 1 et statut = 1: normalement elles devraient avoir statut2 = "à valider" et non "en cours")

  6. #6
    Membre expérimenté
    Inscrit en
    novembre 2009
    Messages
    698
    Détails du profil
    Informations forums :
    Inscription : novembre 2009
    Messages : 698
    Points : 1 300
    Points
    1 300
    Par défaut étape data
    Ce qui ce conçoit bien s'énonce clairement... c'est la première étape pour programmer quoi que ce soit...

    si (bloc = 3 et statut = 4) OU si (bloc = 1 et statut = 4) alors statut2 = "à faire", sinon statut2 = "en cours"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (bloc=1 or bloc=3) and statut=4 then statut2="à faire";    /* ou bloc in (1,3) */
    else statut2 = "en cours";
    Si vous ne voulez pas écraser une valeur déjà remplie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    data matable;
      set matable;
      length statut_prov statut2 $10.;
      by id;
      if first.id and bloc=3 and statut=2 then statut2="à valider";
      else if (bloc=1 or bloc=3) and statut=4 then statut2 = "à faire";   /* ou bloc in (1,3) */
      else statut2="en cours";
    run;
    Cordialement,

  7. #7
    Futur Membre du Club
    Femme Profil pro
    Stat
    Inscrit en
    janvier 2020
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 24
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Stat
    Secteur : Santé

    Informations forums :
    Inscription : janvier 2020
    Messages : 11
    Points : 8
    Points
    8
    Par défaut
    Vous avez raison. C'est clair dans ma tête mais dur à exprimer à l'écrit.

    Pour la condition, c'est bien un "ET" et non un "ou".

    Il y a un petit décalage entre le code proposé et ce que je souhaite obtenir : le fait d'avoir BLOC=3 et STATUT=4 n'implique pas forcément le statut "à faire", c'est le fait d'avoir BLOC=1 et STATUT=4 et BLOC=3 et STATUT= 4. Toutefois, si je modifie simplement le code en mettant "and" à la place de "or", je ne travaille pas pour un individu ID mais pour toutes les lignes confondues...

  8. #8
    Membre expérimenté
    Inscrit en
    novembre 2009
    Messages
    698
    Détails du profil
    Informations forums :
    Inscription : novembre 2009
    Messages : 698
    Points : 1 300
    Points
    1 300
    Par défaut étape data
    Les instructions s'exécutent en parallèle sur chaque ligne. Si vous remplacez or par and, vous ne travaillez pas pour toutes les lignes confondues, vous demandez à ce qu'une ligne remplisse les conditions bloc=1 et bloc=3 simultanément ce qui est impossible.

    Si ce que je crois comprendre est exact, il n'existe pas d'id pour lequel il y a une ligne bloc=1 et statut=4 et une autre bloc=3 et statut= 4 dans votre table test. Il serait bien de modifier l'étape data pour pouvoir tester les différents cas. Pensez aussi à afficher la table résultat attendu.

    Cordialement,

  9. #9
    Futur Membre du Club
    Femme Profil pro
    Stat
    Inscrit en
    janvier 2020
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 24
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Stat
    Secteur : Santé

    Informations forums :
    Inscription : janvier 2020
    Messages : 11
    Points : 8
    Points
    8
    Par défaut
    Oui bien sûr, plutôt un IF imbriqué pardon.

    Voici un exemple de données:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    data matable;
    input ID BLOC STATUT;
    cards;
    1 	1 	1
    1 	2 	3
    1 	3 	4
    2 	1 	1
    2      2       2
    2      3       3
    3 	1 	1
    3 	2 	1
    3 	3 	3
    ;
    run;
    Ci-dessous les résultats attendus :

    ID BLOC STATUT STATUT2
    1 1 1 EN COURS
    1 2 1 EN COURS
    1 3 4 EN COURS
    2 1 4 A FAIRE
    2 2 2 A FAIRE
    2 3 4 A FAIRE
    3 1 1 A VALIDER
    3 2 1 A VALIDER
    3 3 2 A VALIDER

  10. #10
    Membre expérimenté
    Inscrit en
    novembre 2009
    Messages
    698
    Détails du profil
    Informations forums :
    Inscription : novembre 2009
    Messages : 698
    Points : 1 300
    Points
    1 300
    Par défaut manipulation de données
    Un if imbriqué ne change rien... vous travaillez toujours au niveau de l'observation...

    Je ne vois toujours pas d'id avec bloc=1 et statut=4 et bloc=3 et statut=4 dans votre table de départ... et pas non plus d'id avec bloc=3 et statut=2...

    En modifiant votre table de départ :

    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
    data matable;
      input id bloc statut;
      cards;
    1 1 4
    1 2 3
    1 3 4
    2 1 1
    2 2 2
    2 3 3
    3 1 1
    3 2 1
    3 3 2
    ;
    run;
     
    data matable;
      set matable;
      if bloc in (1,3) and statut=4 then temp=1;
      else if bloc=3 and statut=2 then temp=3;
      else temp=0;
    run;
     
    proc univariate data=matable noprint;
      by id;
      var temp;
      output out=temp sum=temp2;
    run;
     
    data matable;
      merge matable temp;
      by id;
      if temp2=3 then statut2="à valider";
      else if temp2=2 then statut2="en cours";
      else statut2="à faire";
    run;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    id    bloc    statut    temp    temp2     statut2
     1      1        4        1       2      en cours
     1      2        3        0       2      en cours
     1      3        4        1       2      en cours
     2      1        1        0       0      à faire
     2      2        2        0       0      à faire
     2      3        3        0       0      à faire
     3      1        1        0       3      à valider
     3      2        1        0       3      à valider
     3      3        2        3       3      à valider
    Cordialement,

  11. #11
    Futur Membre du Club
    Femme Profil pro
    Stat
    Inscrit en
    janvier 2020
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 24
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Stat
    Secteur : Santé

    Informations forums :
    Inscription : janvier 2020
    Messages : 11
    Points : 8
    Points
    8
    Par défaut
    Désolée, ça ne fonctionne toujours pas comme attendu (les 3 premières lignes devraient être "à faire") et je n'ai pas réussi à l'adapter. Tant pis, et merci beaucoup pour le temps accordé à mon problème!

    Cordialement,
    Garpe

  12. #12
    Membre expérimenté
    Inscrit en
    novembre 2009
    Messages
    698
    Détails du profil
    Informations forums :
    Inscription : novembre 2009
    Messages : 698
    Points : 1 300
    Points
    1 300
    Par défaut manipulation de données
    Oui pardon, je suis partie de votre tableau de résultat et non de la définition des statuts :

    si (bloc = 3 et statut = 2) alors statut2 = "à valider",
    sinon si (bloc = 3 et statut = 4) et si (bloc = 1 et statut = 4) alors statut2 = "à faire",
    sinon statut2 = "en cours"
    Il faut inverser les statuts "à faire" et "en cours" dans mon précédent programme :

    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
    data matable;
     input id bloc statut;
     cards;
    1 1 4
    1 2 3
    1 3 4
    2 1 1
    2 2 2
    2 3 3
    3 1 1
    3 2 1
    3 3 2
    ;
    run;
     
    data matable;
      set matable;
      if bloc in (1,3) and statut=4 then temp=1;
      else if bloc=3 and statut=2 then temp=3;
      else temp=0;
    run;
     
    proc univariate data=matable noprint;
      by id;
      var temp;
      output out=temp sum=temp2;
    run;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    id    bloc    statut    temp    temp2     statut2
     1      1        4        1       2      à faire
     1      2        3        0       2      à faire
     1      3        4        1       2      à faire
     2      1        1        0       0      en cours
     2      2        2        0       0      en cours
     2      3        3        0       0      en cours
     3      1        1        0       3      à valider
     3      2        1        0       3      à valider
     3      3        2        3       3      à valider
    Cordialement,

Discussions similaires

  1. [9.2] postgis update sur un sous-ensemble
    Par Leehan dans le forum PostgreSQL
    Réponses: 7
    Dernier message: 22/07/2015, 13h15
  2. Réponses: 2
    Dernier message: 29/06/2015, 16h01
  3. Tri sur un sous ensemble dans une requête
    Par Mister Nono dans le forum Doctrine2
    Réponses: 3
    Dernier message: 12/05/2014, 16h47
  4. Exprimer une condition sur des sous-formulaires.
    Par Julieta dans le forum VBA Access
    Réponses: 2
    Dernier message: 08/12/2007, 15h11
  5. [XSLT]Trouver un noeud avec une condition sur ses sous-noeuds
    Par enguerran dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 23/02/2007, 11h00

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