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

ODS et reporting Discussion :

Proc Sgplot - Vbar - Calcul des pourcentages


Sujet :

ODS et reporting

  1. #1
    Membre éclairé
    Proc Sgplot - Vbar - Calcul des pourcentages
    Bonjour,
    j'ai 3 variables numériques discrètes : BEN_SEX_COD (1 ou 2), age_cl (de 0 à 3) et BZD_IND (0 ou 1).

    Je souhaiterais afficher un graphique en barres verticales qui donne le pourcentage du total de BZD_IND avec une barre par valeur de BEN_SEX_COD et tout ça pour toutes les valeurs de age_cl.

    J'exécute :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    proc sgplot data= toto;
    	vbar age_cl/response=bzd_ind group= ben_sex_cod stat=percent
    	groupdisplay=cluster;
    run;


    La forme du graphique est bonne.

    Par contre, pour age_cl=2 par exemple, il y a un effectif total de 12 (12 lignes); on a bzd_ind=1 pour :
    - Ben_sex_cod=1 : 1 cas
    - Ben_sex_cod=2 : 3 cas

    Si je fais stat=sum, je retrouve bien les 1 et 3 cas : Ok.

    Par contre avec stat=percent sas affiche 10% et 30% ; je m’attendais à avoir 1/12=8,3% et 3/12=25%.

    Savez-vous comment son calculés les pourcentages ?

    Merci.

    (\ _ /)
    (='.'=) Voici Lapinou. Aidez le à conquérir le monde
    (")-(") en le reproduisant

  2. #2
    Membre éprouvé
    Proc Sgplot - Vbar - Calcul des pourcentages
    Bonjour,



    Les pourcentages correspondent à ce tableau de fréquence :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    proc freq data=toto;
      table ben_sex_cod*age_cl / nocol norow;
      where bzd_ind=1;
    run;


    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
                Table de BEN_SEX_COD par age_cl
     
    BEN_SEX_COD(BEN_SEX_COD)     age_cl(age_cl)
     
    Fréquence  |
    Pourcentage|       0|       1|       2|       3|  Total
    -----------+--------+--------+--------+--------+
             1 |      0 |      0 |      1 |      0 |      1
               |   0.00 |   0.00 |  10.00 |   0.00 |  10.00
    -----------+--------+--------+--------+--------+
             2 |      3 |      2 |      3 |      1 |      9
               |  30.00 |  20.00 |  30.00 |  10.00 |  90.00
    -----------+--------+--------+--------+--------+
    Total             3        2        4        1       10


    Cordialement,

  3. #3
    Membre éclairé
    Merci mgdondon,
    j'ai finalement recalculé les % à la main.
    Comme je voulais aussi un total que je n'ai pas trouvé en option, je me le suis recalculé aussi :


    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    data toto0;
    	set ph.variable_graphique_ppi;
    		if bzd_ind eq . then bzd_ind=0;
    run;
     
    /* Comptage de l'effectif pour chaque modalité (sexe, âge) */
    proc sql;
    	create table titi1 as
    		select
    			count(*) as nb,
    			ben_sex_cod,
    			age_cl
    				from toto0
    				group by 
    					ben_sex_cod,
    					age_cl
    	;
    quit;
     
    /* Comptage de l'effectif pour chaque modalité (sexe, âge) pour bzd_ind = 1 */
    proc sql;
    	create table titi2 as
    		select
    			count(*) as nb,
    			age_cl,
    			ben_sex_cod
    				from toto0
    				where bzd_ind eq 1
    				group by 
    					ben_sex_cod,
    					age_cl
    	;
    quit;
     
    /* Calcul des % = (2) / (1) */
    proc sql;
    	create table titi3 as
    		select
    			t1.ben_sex_cod,
    			t1.age_cl,
    			case when coalesce(t1.nb,0) ne 0 then 100*t2.nb/t1.nb else 0 end as p
    			from titi1 t1 left outer join titi2 t2 on t1.ben_sex_cod=t2.ben_sex_cod and t1.age_cl=t2.age_cl
    	;
    quit;			
     
    /* On recommence sans le sexe pour avoir le calcul sur hommes + femmes */
    /* Comptage de l'effectif pour chaque modalité (âge) */
    proc sql;
    	create table titi1_ as
    		select
    			count(*) as nb,
    			age_cl
    				from toto0
    				group by 
    					age_cl
    	;
    quit;
     
    /* Comptage de l'effectif pour chaque modalité (âge) pour bzd_ind = 1 */
    proc sql;
    	create table titi2_ as
    		select
    			count(*) as nb,
    			age_cl
    				from toto0
    				where bzd_ind eq 1
    				group by 
    					age_cl
    	;
    quit;
     
    /* Calcul des % = (2) / (1) */
    proc sql;
    	create table titi3_ as
    		select
    			3 as ben_sex_cod, /* code sexe fictif pour total hommes + femmes */
    			t1.age_cl,
    			case when coalesce(t1.nb,0) ne 0 then 100*t2.nb/t1.nb else 0 end as p
    			from titi1_ t1 left outer join titi2_ t2 on t1.age_cl=t2.age_cl
    	;
    quit;			
     
    data finale;
    	set titi3 titi3_;
    run;
     
    proc sgplot data= finale;
    	vbar age_cl/response=p group=ben_sex_cod stat=sum groupdisplay=cluster;
    run;
    (\ _ /)
    (='.'=) Voici Lapinou. Aidez le à conquérir le monde
    (")-(") en le reproduisant

  4. #4
    Membre éprouvé
    calcul des pourcentages
    Bonjour Filippo,

    Merci pour le retour et le partage.

    2 propositions alternatives pour le calcul des pourcentages :

    • Avec la proc univariate :

    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 toto0;
      set toto0;
      if bzd_ind=. then bzd_ind=0;
    run;
     
    proc sort data=toto0;
      by age_cl ben_sex_cod;
    run;
     
    /* Effectif pour chaque modalité (sexe, âge) pour l'ensemble du tableau (n) et pour bzd_ind = 1 (sum) */
     
    proc univariate data=toto0 noprint;
      var bzd_ind;
      by age_cl ben_sex_cod;
      output out=titi_sexe n=bzd_ind_n sum=bzd_ind_sum;
    run;
     
    /* Calcul des totaux pour avoir le résultat sur hommes + femmes */
     
    proc univariate data=titi_sexe noprint;
      var ben_sex_cod bzd_ind_n bzd_ind_sum;
      by age_cl;
      output out=titi_cum sum=ben_sex_cod bzd_ind_n bzd_ind_sum;
    run;
     
    /* Calcul des pourcentages */
     
    data finale2;
      set titi_sexe titi_cum;
      p = bzd_ind_sum / bzd_ind_n * 100;
    run;
     
    proc sort data=finale2;
      by ben_sex_cod age_cl;
    run;


    • Avec la proc tabulate :

    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
    data toto0;
      set toto0;
      if bzd_ind=. then bzd_ind=0;
    run;
     
    proc tabulate data=toto0 out=finale3(drop=_TYPE_ _PAGE_ _TABLE_);
      class age_cl ben_sex_cod;
      var bzd_ind;
      table (age_cl), (ben_sex_cod all) * (bzd_ind * (n sum));
    run;
     
    data finale3;
      set finale3;
      p = bzd_ind_sum / bzd_ind_n * 100;
      if ben_sex_cod=. then ben_sex_cod=3;
    run;
     
    proc sort data=finale3;
      by ben_sex_cod age_cl;
    run;


    Cordialement,

    Lien : La proc tabulate expliquée à ma fille d'Olivier Decourt

  5. #5
    Membre éclairé
    Merci mgdondon,
    c'est vrai que j'aurais pu calculer les pourcentages avec proc univariate, freq etc ... plutôt qu'en sql.

    (\ _ /)
    (='.'=) Voici Lapinou. Aidez le à conquérir le monde
    (")-(") en le reproduisant

  6. #6
    Membre éclairé
    Bonjour à tous,
    la solution avec pourcentages calculés avec proc freq :
    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
    42
    43
    44
     
    /***************************************************************************************/
    /* Solution avec pourcentages calculés avec proc freq */
    /***************************************************************************************/
    data toto0;
    	set toto0 (keep=ben_sex_cod age_cl bzd_ind);
    		if bzd_ind eq . then bzd_ind=0;
    run;
     
    proc sort data=toto0;
    	by ben_sex_cod age_cl;
    run;
     
    /* Pourcentages de bzd_ind par (sexe, age) */
    proc freq data=toto0 noprint;
    	table bzd_ind / out=toto1;
    	by ben_sex_cod age_cl;
    run;
     
    proc sort data=toto0;
    	by age_cl;
    run;
     
    /* Pourcentages de bzd_ind par (age) */
    proc freq data=toto0 noprint;
    	table bzd_ind / out=toto2;
    	by age_cl;
    run;
     
    /* Sexe fictif à 3 */
    data toto2;
    	set toto2;
    		ben_sex_cod=3;
    run;
     
    data finale (keep=ben_sex_cod age_cl p);
    	set toto1 toto2;
    	p=percent;
    	where bzd_ind eq 1;
    run;
     
    proc sgplot data= finale;
    	vbar age_cl/response=p group=ben_sex_cod stat=sum groupdisplay=cluster;
    run;


    Ca offre aussi l'avantage de ne pas faire tourner la proc sqplot sur des millions de lignes mais sur une table agrégée plus petite; sur des millions de lignes, cela causait des soucis d'ods.

    (\ _ /)
    (='.'=) Voici Lapinou. Aidez le à conquérir le monde
    (")-(") en le reproduisant

  7. #7
    Membre éprouvé
    calcul de pourcentages
    Bonjour Filippo,

    Merci pour le partage.

    Ça fait une belle collection de programmes

    Cordialement,

###raw>template_hook.ano_emploi###