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 :

Somme sur une variable avec des conditions


Sujet :

SAS Base

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2017
    Messages : 48
    Points : 31
    Points
    31
    Par défaut Somme sur une variable avec des conditions
    Bonjour à tous,

    Etant novice en SAS je solicite votre aide. Merci d'avance pour le temps que vous me consacré.

    Voici mes données:
    contrat date Mois Montant
    1 01/05/2017 5 300
    2 09/04/2016 4 500
    2 15/05/2016 5 150
    2 19/12/2017 12 30
    5 30/02/2005 2 100
    5 30/01/2005 1 100
    10 23/07/2007 7 10
    10 23/08/2007 8 50
    2 23/12/2007 12 200

    J'aimerais obtenir le tableau suivant avec ces conditions:
    IF Mois <= 3 THEN Q1 = sum(Montant); ELSE Q1 = 0
    IF Mois > 3 and Mois <=6 THEN Q2 = sum(Montant) ; ELSE Q2 = 0
    IF Mois > 6 and Mois <=9 THEN Q3 = sum(Montant); ELSE Q3 = 0
    IF Mois > 9 THEN Q4 = sum(Montant); ELSE Q4 = 0
    contrat Q1 Q2 Q3 Q4
    1 0 300 0 0
    2 0 650 0 0
    2 0 0 0 230
    5 200 0 0 0
    10 0 0 60 0

    Encore une fois merci pour votre aide.

  2. #2
    Membre confirmé
    Homme Profil pro
    Consultant Finance/Assurance
    Inscrit en
    Décembre 2013
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant Finance/Assurance

    Informations forums :
    Inscription : Décembre 2013
    Messages : 198
    Points : 638
    Points
    638
    Par défaut
    Bonjour,

    Une solution possible pour réaliser cette tâche :

    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
    Data r;
    input cnt date :ddmmyy10. mois montant;
    format date ddmmyy10.;
    cards;
    1 01/05/2017 5 300 
    2 09/04/2016 4 500 
    2 15/05/2016 5 150 
    2 19/12/2017 12 30 
    5 27/02/2005 2 100 
    5 30/01/2005 1 100 
    10 23/07/2007 7 10 
    10 23/08/2007 8 50 
    2 23/12/2007 12 200 
    ;run;
     
    Proc format;
    invalue QT 1,2,3 = 1
    		   4,5,6 = 2
    		   7,8,9 = 3
    		   10,11,12 = 4;
    Run;
     
    Proc sort data=r;
    By cnt;
    Run;
     
    Data rr (keep = cnt Q:);
    Set r;
    by cnt;
    Array Q{4};
    If first.cnt then call missing(of Q{*});
    Q{input(mois,QT.)} + montant;
    If last.cnt;
    Run;
    Flo00154

  3. #3
    Membre expérimenté
    Homme Profil pro
    Développeur en SAS/ Statisticien
    Inscrit en
    Janvier 2013
    Messages
    482
    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 : 482
    Points : 1 547
    Points
    1 547
    Par défaut
    Bonjour,
    Une 2ème possibilité en utilisant la fonction QTR qui retourne le quart d'une année d'une date de format SAS.

    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
    data Table ;
    set Table ;  
    Qtr=Qtr(date) ;
    run ;    			 
     
    proc sort data=Table out=Table_tri ; 
    by contrat Qtr ;
    run ;   				 
     
    data Finale (keep=contrat Q:) ;
    set Table_tri ;  
    by contrat Qtr ;
    retain S_Montant ;
     
    if first.Qtr then S_Montant=0 ;
    S_Montant+Montant ;
     
    array Q(4) ; 
    do i=1 to dim(Q) ; Q(i)=0 ; end ;	
    Q(Qtr)=S_Montant ;
     
    if last.Qtr then output ;
    run  ;
    Cdt Ward

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2017
    Messages : 48
    Points : 31
    Points
    31
    Par défaut
    Merci à tous d'avoir pris le temps de me répondre.

    Dans un premier temps j'utilise la méthode flo00154 qui marche très bien. Encore merci. J'ai juste besoin de comprendre comment le code fonctionne si possible. Car en réalité ce je veux obtenir c'est ça:

    contrat Q1 Q2 Q3 Q4 VL VR
    1 0 300 0 0 10 20
    2 0 650 0 0 100 50
    2 0 0 0 230 60 400
    5 200 0 0 0 500 300
    10 0 0 60 0 1000 250

    Avec VL et VR des variables de la table initial mais agrégés. Du coup je ne sais pas trop comment rajouté VL et VR dans votre code.

  5. #5
    Membre confirmé
    Homme Profil pro
    Consultant Finance/Assurance
    Inscrit en
    Décembre 2013
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant Finance/Assurance

    Informations forums :
    Inscription : Décembre 2013
    Messages : 198
    Points : 638
    Points
    638
    Par défaut
    Bonjour,

    Mon code fonctionne mais il agrège trop et ne conserve qu'une seule ligne par contrat, or tu souhaites conserver une ligne par trimestre à priori.
    Je te conseille d'utiliser la méthode de Ward du coup dont voici une modification :

    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
     
    Data r;
    input cnt date :ddmmyy10. mois montant;
    format date ddmmyy10.;
    cards;
    1 01/05/2017 5 300 
    2 09/04/2016 4 500 
    2 15/05/2016 5 150 
    2 19/12/2017 12 30 
    5 27/02/2005 2 100 
    5 30/01/2005 1 100 
    10 23/07/2007 7 10 
    10 23/08/2007 8 50 
    2 23/12/2007 12 200 
    ;run;
     
    Proc SQL;
    Create table r_s as
    Select *, QTR(Date) as Tr
    from r
    Order by cnt, Tr;
    Quit;
     
    Data rr (keep = cnt Q:);
    Set r_s;
    by cnt Tr;
    Array Q{4};
    If first.Tr then call missing(of Q{*});
    Q{Tr} + montant;
    If last.Tr;
    Run;
    La proc SQL calcul le quarter avec la fonction QTR que Ward avait utilisé, elle fait le même travail que mon format de mon code précédent. Ensuite je trie directement ma table en sortie, la proc SQL permet de faire en une étape la création de variable + le sort.

    Pour l'étape data, on travaille en utilisant le tri effectué par contrat et QTR (via l'instruction "by").
    Ensuite tu crée un array qui est un groupement de variable. Ici j'appelle mon tableau "Q" qui contiendra 4 variables, comme je ne donne pas plus d'infos SAS va créer automatiquement 4 variables qui seront Q1, Q2, Q3, Q4 qui seront stockées dans le tableau "Q".
    Si je suis à la première observation du trimestre j'incrémente la variable "Q" correspondante. Par exemple en mettant Q{1} on va chercher la première variable du tableau qui sera ici Q1.
    Pas besoin de retain ici car l'array a un retain automatique.
    Enfin si on est à la dernière observation du trimestre alors j'output.

    Pour VL et VR il faut nous en dire plus sur ces variables. Comment sont elles agrégées ? Tu souhaites faire une fusion ou faire une agrégation en même temps que le calcul du montant par trimestre ?

    Flo00154

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2017
    Messages : 48
    Points : 31
    Points
    31
    Par défaut
    Boujour,

    Désolé mais je me suis mal expliquer dans mon message précédent. Au fait je veux bien un contrat par ligne, du coup votre code précédent était parfait je voulais juste rajouter les variables VL et VR aggréger par contrat. Mais comme je n'ai pas compris votre précédent code je n'y arrivais pas.

  7. #7
    Membre confirmé
    Homme Profil pro
    Consultant Finance/Assurance
    Inscrit en
    Décembre 2013
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant Finance/Assurance

    Informations forums :
    Inscription : Décembre 2013
    Messages : 198
    Points : 638
    Points
    638
    Par défaut
    D'accord dans ce cas je reprend ma logique précédente mais en conservant les modifications de mon dernier code.
    Pour VL et VR je suis parti de l'hypothèse que ces données sont présentes dans ta table qui contient tes autres informations sur les contrats (si ce n'est pas le cas il faudra passer par une fusion de table).

    Ainsi j'ai ajouté des données factices dans ma table de test et j'ai ajouté des compteurs dans mon étape data qui permettent de faire la somme de VL et VR.

    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
    Data r;
    input cnt date :ddmmyy10. mois montant VL VR;
    format date ddmmyy10.;
    cards;
    1 01/05/2017 5 300 10 10
    2 09/04/2016 4 500 20 30
    2 15/05/2016 5 150  40 40
    2 19/12/2017 12 30 50 50
    5 27/02/2005 2 100 50 50
    5 30/01/2005 1 100 60 60
    10 23/07/2007 7 10 70 70
    10 23/08/2007 8 50 80 80
    2 23/12/2007 12 200 90 90
    ;run;
     
    Proc SQL;
    Create table r_s as
    Select *, QTR(Date) as Tr
    from r
    Order by cnt;
    Quit;
     
    Data rr (keep = cnt Q: tot:);
    Set r_s;
    by cnt;
    Array Q{4};
    If first.cnt then do;
    	call missing(of Q{*});
    	Tot_VL = 0;
    	Tot_VR = 0;
    End;
    Q{Tr} + montant;
    Tot_VL + VL;
    Tot_VR + VR;
    If last.cnt;
    Run;
    Si ce n'est pas ce que tu souhaites le mieux est de nous donner un morceau de ta table qui contient les variables VL et VR pour qu'on analyse mieux ta demande.

    Flo00154

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 01/12/2008, 15h18
  2. Cadrer une variable avec des zéros à gauche
    Par saysay dans le forum Scripts/Batch
    Réponses: 2
    Dernier message: 07/08/2008, 12h05
  3. concatener une variable avec des guillemets
    Par 461219 dans le forum VBScript
    Réponses: 3
    Dernier message: 25/02/2008, 17h29
  4. Faire suivre une variable avec des espaces
    Par jonathan34 dans le forum Shell et commandes GNU
    Réponses: 3
    Dernier message: 14/02/2008, 21h57
  5. Erreur sur une fonction avec des paramètres
    Par Elois dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 05/05/2004, 22h00

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