Les jointures de tables partie_2#

Dans cette partie du cours, nous allons appliquer les procédures proc sql que nous avons apprises, sur une base de données relationnelle d’assurance automobile. Il faut noter que ces données proviennent d’une vraie bd d’assurance. Toutefois, le contenu a été modifié et plusieurs variables ont été supprimées à des fins de confidentialité. Nous avons gardé l’essentiel des données qui nous servent de matériel pédagogique pour les cours d’actuariat à l’UQAM.

Analysons d’abord l’architecture de cette base de données présentée ci-dessous:

Base de données d'assurance dans le cadre du cours ACT3035

On voit bien que nous avons essentiellement quatre tables avec lesquelles nous allons travailler;

  1. Tout d’abord, la table donnes_demo dans laquelle nous trouvons les informations démographiques des assurés. Cette table contient une clé primaire (colonne « numeropol ») qui est le numéro de police de l’assuré. C’est avec cette colonne (attribut dans le langage sql) qui permet de relier les quatre tables entre elles.

  2. Ensuite, nous avons la table police_assurance qui nous donne l’information sur chaque police d’assurance

  3. La table pmt nous donne l’information sur les primes payées par les assurés, comme le montant, le mode de paiement …etc.

  4. Enfin, la table cars_ifo nous donne l’information sur les véhicules au dossier de l’assuré.

Analysons l’aperçu sur chacune des tables;

libname bdSQL "data/bdsql";
title "Apperçu de la table donnes_demo";
proc sql outobs=5;
    select * from bdSQL.donnes_demo
quit;
SAS Output

Apperçu de la table donnes_demo

name province company langue date_naissance agee age_permis numeropol
Shane Robinson Nova Scotia May Ltd fr 1944-10-20 72 24 1
Courtney Nguyen Saskatchewan Foley, Moore and Mitchell en 1985-12-09 31 24 5
Lori Washington Yukon Territory Robinson-Reyes fr 1970-01-27 47 28 13
Sarah Castillo Alberta Wood, Brady and English fr 2000-08-23 16 16 16
Jeffrey Garcia Nunavut Berger-Thompson en 1969-10-25 47 20 22
title "Apperçu de la table police_assurance";
proc sql outobs=5;
    select * from bdSQL.police_assurance
quit;
SAS Output

Apperçu de la table police_assurance

numeropol debut_pol fin_pol cout1 cout2 cout3 cout4 cout5 cout6 cout7 nbsin
1 1999-11-10 2000-10-16 . . . . . . . 0
1 2000-10-17 2000-11-09 . . . . . . . 0
1 2000-11-10 2001-11-09 243.85714286 . . . . . . 1
5 1996-01-03 1996-03-27 . . . . . . . 0
5 1996-03-28 1997-01-02 . . . . . . . 0
title "Apperçu de la table pmt";
proc sql outobs=5;
    select * from bdSQL.pmt
quit;
SAS Output

Apperçu de la table pmt

numeropol cout_prime credit_card_number credit_card_provider credit_card_expire freq_pmt
1 1060.28 4.4274761E15 Voyager 01APR23:00:00:00 12
5 1200.89 5.3033891E15 JCB 16 digit 01AUG26:00:00:00 1
13 940.54 3.5285692E15 Maestro 01AUG22:00:00:00 12
16 860.75 6.0115698E15 VISA 13 digit 01MAR23:00:00:00 1
22 790.17 5.2624946E15 Maestro 01AUG20:00:00:00 1
title "Apperçu de la table cars_info";
proc sql outobs=5;
    select * from bdSQL.cars_info
quit;
SAS Output

Apperçu de la table cars_info

numeropol marque_voiture couleur_voiture presence_alarme license_plate
1 Autres Autre 0 DW 3168
5 RENAULT Autre 0 926 1RL
13 RENAULT Autre 1 SOV 828
16 HONDA Autre 0 ENSK 514
22 VOLKSWAGEN Autre 1 453 CFM

Maintenant que nous avons eu connaissance de notre base de données, on peut remarquer que la table police_assurance peut contenir plusieurs informations pour un même assuré, alors que les autres tables en contiennent qu’une seule ligne par assuré. En effet, les tables peuvent avoir différentes relations qu’on appelle:

  • On to one

  • On to many

  • many to many

Étudions plus en détail les deux premières

On To One#

Lorsque nous avons deux tables où il existe une seule observation pour un id donné, nous avons alors une relation de type One to one. Cette situation s’illustre bien avec les deux tables donnes_demo, et pmt. Dans les deux tables nous avons une seule observation par id.. Les deux tables peuvent être relié par le id de l’assuré.

Si nous cherchons par exemple le fournisseur de carte de crédit de chaque assuré;

title "Type de carte de crédit pour chaque assuré";
proc sql outobs=5;
    select a.name, b.credit_card_provider
    from bdSQL.donnes_demo as a left join bdSQL.pmt as b
        on a.numeropol = b.numeropol
    ; 
quit;
SAS Output

Type de carte de crédit pour chaque assuré

name credit_card_provider
Shane Robinson Voyager
Courtney Nguyen JCB 16 digit
Lori Washington Maestro
Sarah Castillo VISA 13 digit
Jeffrey Garcia Maestro

Si nous avions voulu faire cette opération avec un data step, nous aurons fait ceci:

proc sort data = bdSQL.donnes_demo;
    by numeropol;
run;

proc sort data = bdSQL.pmt;
    by numeropol;
run;

data bdSQL.Data_step_one2one  ;
    merge bdSQL.donnes_demo(in = left) bdSQL.pmt(in = right);
    by numeropol;
    if left;
    keep name credit_card_provider;
run;
proc print data=bdSQL.Data_step_one2one (obs=5) noobs;
run;
SAS Output

Type de carte de crédit pour chaque assuré

name credit_card_provider
Shane Robinson Voyager
Courtney Nguyen JCB 16 digit
Lori Washington Maestro
Sarah Castillo VISA 13 digit
Jeffrey Garcia Maestro

On remarque que c’est beaucoup plus simple d’utiliser les procédures sql quand il s’agit de telles situations

One To Many#

Lorsque nous avons une table avec un seul identifiant pour chaque observation (assuré), et une autre table où chaque assuré peut avoir plus qu’une observation (donc un même id qui se répète sur plus qu’une ligne), nous somme alors en présence de relation entre deux tables de type On To Many. Par exemple;

title "Nombte de sinistre total par assuré";
proc sql outobs=5;
    select a.name, sum(b.nbsin) as nombreSin
    from bdSQL.donnes_demo as a left join bdSQL.police_assurance as b
        on a.numeropol = b.numeropol
        group by a.name
        order by nombreSin desc
    ; 
quit;
SAS Output

Nombte de sinistre total par assuré

name nombreSin
Betty Scott 11
Dustin Banks 10
Angela Smith 9
Jimmy Harrison 8
Aaron Tucker 8

Si nous cherchons la liste des noms de tous les assurés et le nombre de sinistres total qu’ils ont eus. Il faut noter que nous cherchons le total du nombre de sinistres de chaque assuré sachant qu’un assuré donné peut avoir zéro ou plus qu’un sinistre.

Remarquez que cela aurait pu bien fonctionner en utilisant right à la place de left

title "Nombte de sinistre total par assuré";
proc sql outobs=5;
    select a.name, sum(b.nbsin) as nombreSin
    from bdSQL.donnes_demo as a right join bdSQL.police_assurance as b
        on a.numeropol = b.numeropol
        group by a.name
        order by nombreSin desc
    ; 
quit;
SAS Output

Nombte de sinistre total par assuré

name nombreSin
Betty Scott 11
Dustin Banks 10
Angela Smith 9
Jimmy Harrison 8
Aaron Tucker 8

ou

title "Nombre de sinistre total par assuré";
proc sql outobs=5;
    select b.name, sum(a.nbsin) as nombreSin
    from bdSQL.police_assurance as a right join bdSQL.donnes_demo as b
        on a.numeropol = b.numeropol
        group by b.name
        order by nombreSin desc
    ; 
quit;
SAS Output

Nombte de sinistre total par assuré

name nombreSin
Betty Scott 11
Dustin Banks 10
Angela Smith 9
Jimmy Harrison 8
Aaron Tucker 8

Jointure de plus que deux table#

Imaginons que nous voulons créer une table qui nous donne: le nombre de sinistre par province, en plus d’avoir l’information s’il ya présence d’alarme ou pas (o ou 1)

/* petit exercice */
title;
proc sql ;
    create table bdSQL.prov_alar_sinis as
   select a.province, c.presence_alarme, sum(b.nbsin) as numbSin
          from bdSQL.donnes_demo a, bdSQL.police_assurance b , bdSQL.cars_info c
    where a.numeropol=b.numeropol and a.numeropol=c.numeropol
    group by province, presence_alarme
    ;
    
proc sql;
    select * from bdSQL.prov_alar_sinis;
quit;
SAS Output
province presence_alarme numbSin
Alberta 0 527
Alberta 1 481
British Columbia 0 483
British Columbia 1 501
Manitoba 0 435
Manitoba 1 444
New Brunswick 0 996
New Brunswick 1 991
Newfoundland and Labrador 0 526
Newfoundland and Labrador 1 484
Northwest Territories 0 464
Northwest Territories 1 458
Nova Scotia 0 457
Nova Scotia 1 442
Nunavut 0 426
Nunavut 1 517
Ontario 0 523
Ontario 1 428
Prince Edward Island 0 459
Prince Edward Island 1 430
Quebec 0 431
Quebec 1 425
Saskatchewan 0 506
Saskatchewan 1 461
Yukon Territory 0 489
Yukon Territory 1 473

Mettre à jour une table#

Avec les procédures proc sql, ils aussi possible de modifier les tables telles que l’ajout d’observations, en supprimer d’autres …etc.

Supposons que nous créerons une nouvelle table où nous avons le nombre total de sinistres, le coût total par province, pour les assurés ayant une alarme ou pas pour chacune des provinces.

/* petit exercice */
title;
proc sql ;
    create table bdSQL.prov_alar_sinis as
   select a.province, c.presence_alarme, sum(b.nbsin) as numbSin, sum(d.cout_prime) as coutTot format=dollar15.2
          from bdSQL.donnes_demo a, bdSQL.police_assurance b , bdSQL.cars_info c, bdSQL.pmt d
    where a.numeropol=b.numeropol and a.numeropol=c.numeropol and a.numeropol=d.numeropol
    group by province, presence_alarme
    ;
    
proc sql;
    select * from bdSQL.prov_alar_sinis;
quit;
SAS Output
province presence_alarme numbSin coutTot
Alberta 0 527 $1,810,648.26
Alberta 1 481 $2,159,837.70
British Columbia 0 483 $1,845,870.63
British Columbia 1 501 $2,251,772.80
Manitoba 0 435 $1,816,059.04
Manitoba 1 444 $2,052,799.22
New Brunswick 0 996 $4,063,876.55
New Brunswick 1 991 $4,910,546.77
Newfoundland and Labrador 0 526 $2,114,873.41
Newfoundland and Labrador 1 484 $2,572,403.03
Northwest Territories 0 464 $1,831,869.64
Northwest Territories 1 458 $2,303,249.95
Nova Scotia 0 457 $1,863,869.16
Nova Scotia 1 442 $2,140,654.70
Nunavut 0 426 $1,767,940.35
Nunavut 1 517 $2,299,574.47
Ontario 0 523 $1,869,489.94
Ontario 1 428 $2,198,819.46
Prince Edward Island 0 459 $1,823,033.74
Prince Edward Island 1 430 $2,302,004.23
Quebec 0 431 $1,791,020.49
Quebec 1 425 $2,099,646.42
Saskatchewan 0 506 $2,078,543.11
Saskatchewan 1 461 $2,380,597.45
Yukon Territory 0 489 $2,090,626.75
Yukon Territory 1 473 $2,271,767.28

Maintenant, supposons que nous voulons augmenter les coûts des primes par 2% pour tous les assurés n’ayant pas une alarme installée sur le véhicule. Mais d’abord, créons une copie de la table prov_alar_sinis qu’on appellera prov_alar_sinis2 afin d’y apporter de modifications

proc sql;
    create table bdSQL.prov_alar_sinis2 like bdSQL.prov_alar_sinis;
    insert into bdSQL.prov_alar_sinis2
    select * from bdSQL.prov_alar_sinis;
    select * from bdSQL.prov_alar_sinis2;
quit;
SAS Output

Selectively Updated presence_alarme Values

province presence_alarme numbSin coutTot
Alberta 0 527 $1,810,648.26
Alberta 1 481 $2,159,837.70
British Columbia 0 483 $1,845,870.63
British Columbia 1 501 $2,251,772.80
Manitoba 0 435 $1,816,059.04
Manitoba 1 444 $2,052,799.22
New Brunswick 0 996 $4,063,876.55
New Brunswick 1 991 $4,910,546.77
Newfoundland and Labrador 0 526 $2,114,873.41
Newfoundland and Labrador 1 484 $2,572,403.03
Northwest Territories 0 464 $1,831,869.64
Northwest Territories 1 458 $2,303,249.95
Nova Scotia 0 457 $1,863,869.16
Nova Scotia 1 442 $2,140,654.70
Nunavut 0 426 $1,767,940.35
Nunavut 1 517 $2,299,574.47
Ontario 0 523 $1,869,489.94
Ontario 1 428 $2,198,819.46
Prince Edward Island 0 459 $1,823,033.74
Prince Edward Island 1 430 $2,302,004.23
Quebec 0 431 $1,791,020.49
Quebec 1 425 $2,099,646.42
Saskatchewan 0 506 $2,078,543.11
Saskatchewan 1 461 $2,380,597.45
Yukon Territory 0 489 $2,090,626.75
Yukon Territory 1 473 $2,271,767.28

Appliquons maintenant l’augmentation de 2%

proc sql;
   update bdSQL.prov_alar_sinis2
      set coutTot=coutTot*1.02
         where presence_alarme=0;

   title "Selectively Updated presence_alarme Values";
   select *
      from bdSQL.prov_alar_sinis2;
quit;
SAS Output

Selectively Updated presence_alarme Values

province presence_alarme numbSin coutTot
Alberta 0 527 $1,846,861.23
Alberta 1 481 $2,159,837.70
British Columbia 0 483 $1,882,788.04
British Columbia 1 501 $2,251,772.80
Manitoba 0 435 $1,852,380.22
Manitoba 1 444 $2,052,799.22
New Brunswick 0 996 $4,145,154.08
New Brunswick 1 991 $4,910,546.77
Newfoundland and Labrador 0 526 $2,157,170.88
Newfoundland and Labrador 1 484 $2,572,403.03
Northwest Territories 0 464 $1,868,507.03
Northwest Territories 1 458 $2,303,249.95
Nova Scotia 0 457 $1,901,146.54
Nova Scotia 1 442 $2,140,654.70
Nunavut 0 426 $1,803,299.16
Nunavut 1 517 $2,299,574.47
Ontario 0 523 $1,906,879.74
Ontario 1 428 $2,198,819.46
Prince Edward Island 0 459 $1,859,494.41
Prince Edward Island 1 430 $2,302,004.23
Quebec 0 431 $1,826,840.90
Quebec 1 425 $2,099,646.42
Saskatchewan 0 506 $2,120,113.97
Saskatchewan 1 461 $2,380,597.45
Yukon Territory 0 489 $2,132,439.28
Yukon Territory 1 473 $2,271,767.28

Supprimer des observations#

Afin d’en faire un exemple seulement, sans aucune pensée politique quelconque, supposons que nous voulons séparer les données sur le Qéubec du reste des autres provinces. Donc, nous aurons deux tables, celle qui contient les informations sur les Québec, et l’autre contient les informations des autres provinces.

proc sql;
   create table bdSQL.Quebec like bdSQL.prov_alar_sinis;
   insert into bdSQL.Quebec
   select * from bdSQL.prov_alar_sinis
      where province like 'Q%';
    select * from bdSQL.Quebec;
quit;
SAS Output

Selectively Updated presence_alarme Values

province presence_alarme numbSin coutTot
Quebec 0 431 $1,826,840.90
Quebec 1 425 $2,099,646.42

Supprimons maintenant les données du Québec de notre table principale

proc sql;
   delete
      from bdSQL.prov_alar_sinis
      where province like 'Q%';
      select * from bdSQL.prov_alar_sinis;
quit;
SAS Output

Selectively Updated presence_alarme Values

province presence_alarme numbSin coutTot
Alberta 0 527 $1,846,861.23
Alberta 1 481 $2,159,837.70
British Columbia 0 483 $1,882,788.04
British Columbia 1 501 $2,251,772.80
Manitoba 0 435 $1,852,380.22
Manitoba 1 444 $2,052,799.22
New Brunswick 0 996 $4,145,154.08
New Brunswick 1 991 $4,910,546.77
Newfoundland and Labrador 0 526 $2,157,170.88
Newfoundland and Labrador 1 484 $2,572,403.03
Northwest Territories 0 464 $1,868,507.03
Northwest Territories 1 458 $2,303,249.95
Nova Scotia 0 457 $1,901,146.54
Nova Scotia 1 442 $2,140,654.70
Nunavut 0 426 $1,803,299.16
Nunavut 1 517 $2,299,574.47
Ontario 0 523 $1,906,879.74
Ontario 1 428 $2,198,819.46
Prince Edward Island 0 459 $1,859,494.41
Prince Edward Island 1 430 $2,302,004.23
Saskatchewan 0 506 $2,120,113.97
Saskatchewan 1 461 $2,380,597.45
Yukon Territory 0 489 $2,132,439.28
Yukon Territory 1 473 $2,271,767.28

Ajout d’une colonne#

Supposons qu’on veut ajouter une colonne qui serait simplement le coût par sinistre:

proc sql;
   alter table bdSQL.prov_alar_sinis
      add cout_par_sinsn num label='Coût par sinistre' format=dollar15.2;
    update bdSQL.prov_alar_sinis
       set cout_par_sinsn=coutTot/numbSin;
   select *
      from bdSQL.prov_alar_sinis;      
quit;      
SAS Output

Selectively Updated presence_alarme Values

province presence_alarme numbSin coutTot Coût par sinistre
Alberta 0 527 $1,846,861.23 $3,504.48
Alberta 1 481 $2,159,837.70 $4,490.31
British Columbia 0 483 $1,882,788.04 $3,898.11
British Columbia 1 501 $2,251,772.80 $4,494.56
Manitoba 0 435 $1,852,380.22 $4,258.35
Manitoba 1 444 $2,052,799.22 $4,623.42
New Brunswick 0 996 $4,145,154.08 $4,161.80
New Brunswick 1 991 $4,910,546.77 $4,955.14
Newfoundland and Labrador 0 526 $2,157,170.88 $4,101.09
Newfoundland and Labrador 1 484 $2,572,403.03 $5,314.88
Northwest Territories 0 464 $1,868,507.03 $4,026.95
Northwest Territories 1 458 $2,303,249.95 $5,028.93
Nova Scotia 0 457 $1,901,146.54 $4,160.06
Nova Scotia 1 442 $2,140,654.70 $4,843.11
Nunavut 0 426 $1,803,299.16 $4,233.10
Nunavut 1 517 $2,299,574.47 $4,447.92
Ontario 0 523 $1,906,879.74 $3,646.04
Ontario 1 428 $2,198,819.46 $5,137.43
Prince Edward Island 0 459 $1,859,494.41 $4,051.19
Prince Edward Island 1 430 $2,302,004.23 $5,353.50
Saskatchewan 0 506 $2,120,113.97 $4,189.95
Saskatchewan 1 461 $2,380,597.45 $5,163.99
Yukon Territory 0 489 $2,132,439.28 $4,360.82
Yukon Territory 1 473 $2,271,767.28 $4,802.89

On peut aussi modifier le format, le label ou la largeur d’une colonne avec l’option MODIFY. Par exemple, notre nouvelle colonne cout_par_sinsn qui avait un format dollar=15.2, on peut réduire le format à dollar=19.0

proc sql;
   alter table bdSQL.prov_alar_sinis
      modify cout_par_sinsn format=dollar10.0;
   select * from bdSQL.prov_alar_sinis;   
quit;
SAS Output

Selectively Updated presence_alarme Values

province presence_alarme numbSin coutTot Coût par sinistre
Alberta 0 527 $1,846,861.23 $3,504
Alberta 1 481 $2,159,837.70 $4,490
British Columbia 0 483 $1,882,788.04 $3,898
British Columbia 1 501 $2,251,772.80 $4,495
Manitoba 0 435 $1,852,380.22 $4,258
Manitoba 1 444 $2,052,799.22 $4,623
New Brunswick 0 996 $4,145,154.08 $4,162
New Brunswick 1 991 $4,910,546.77 $4,955
Newfoundland and Labrador 0 526 $2,157,170.88 $4,101
Newfoundland and Labrador 1 484 $2,572,403.03 $5,315
Northwest Territories 0 464 $1,868,507.03 $4,027
Northwest Territories 1 458 $2,303,249.95 $5,029
Nova Scotia 0 457 $1,901,146.54 $4,160
Nova Scotia 1 442 $2,140,654.70 $4,843
Nunavut 0 426 $1,803,299.16 $4,233
Nunavut 1 517 $2,299,574.47 $4,448
Ontario 0 523 $1,906,879.74 $3,646
Ontario 1 428 $2,198,819.46 $5,137
Prince Edward Island 0 459 $1,859,494.41 $4,051
Prince Edward Island 1 430 $2,302,004.23 $5,353
Saskatchewan 0 506 $2,120,113.97 $4,190
Saskatchewan 1 461 $2,380,597.45 $5,164
Yukon Territory 0 489 $2,132,439.28 $4,361
Yukon Territory 1 473 $2,271,767.28 $4,803

Supprimer une colonne:#

La clause DROP permet de supprimer une colonne d’une table donnée;

proc sql;
   alter table bdSQL.prov_alar_sinis
      drop cout_par_sinsn;
    select * from bdSQL.prov_alar_sinis;
quit;
SAS Output

Selectively Updated presence_alarme Values

province presence_alarme numbSin coutTot
Alberta 0 527 $1,846,861.23
Alberta 1 481 $2,159,837.70
British Columbia 0 483 $1,882,788.04
British Columbia 1 501 $2,251,772.80
Manitoba 0 435 $1,852,380.22
Manitoba 1 444 $2,052,799.22
New Brunswick 0 996 $4,145,154.08
New Brunswick 1 991 $4,910,546.77
Newfoundland and Labrador 0 526 $2,157,170.88
Newfoundland and Labrador 1 484 $2,572,403.03
Northwest Territories 0 464 $1,868,507.03
Northwest Territories 1 458 $2,303,249.95
Nova Scotia 0 457 $1,901,146.54
Nova Scotia 1 442 $2,140,654.70
Nunavut 0 426 $1,803,299.16
Nunavut 1 517 $2,299,574.47
Ontario 0 523 $1,906,879.74
Ontario 1 428 $2,198,819.46
Prince Edward Island 0 459 $1,859,494.41
Prince Edward Island 1 430 $2,302,004.23
Saskatchewan 0 506 $2,120,113.97
Saskatchewan 1 461 $2,380,597.45
Yukon Territory 0 489 $2,132,439.28
Yukon Territory 1 473 $2,271,767.28

Supprimer une table!#

Même s’il faut se poser cette question plusieurs fois avant d’exécuter la commande sql, on peut toujours supprimer complètement une table comme ceci:

proc sql;
   drop table bdSQL.Quebec;

615  ods listing close;ods html5 (id=saspy_internal) file=stdout options(bitmap_mode='inline') device=svg; ods graphics on /
615! outputfmt=png;
NOTE: Writing HTML5(SASPY_INTERNAL) Body file: STDOUT
616
617 proc sql;
618 drop table bdSQL.Quebec;
NOTE: Table BDSQL.QUEBEC has been dropped.
619
620 ods html5 (id=saspy_internal) close;ods listing;

621

Autres procédures SQL#

Compter le nombre de doublons:#

Compter les doublons est une des premières tâches que vous aurez à faire lorsque vous allez manipuler des bases de données un peu plus importantes

Soit la table doublons

proc sql;
    create table bdSQL.doublons
        (id char(12), Nom char(12));
    insert into bdSQL.doublons
        values("123", "Noureddine Meraihi")
        values("124", "Gabriel A")
        values("125", "JM P")
        values("126", "Mathieu P")
        values("127", "Mathieu B")
        values("126", "Mathieu P")
        values("128", "JP B");
    select * from bdSQL.doublons;
quit;
SAS Output

Duplicate Rows in Duplicates Table

id Nom
123 Noureddine M
124 Gabriel A
125 JM P
126 Mathieu P
127 Mathieu B
126 Mathieu P
128 JP B
proc sql;
   title 'Duplicate Rows in Duplicates Table';
   select *, count(*) as Count
      from bdSQL.doublons
      group by id, Nom
      having count(*) > 1;
quit;
SAS Output

Duplicate Rows in Duplicates Table

id Nom Count
126 Mathieu P 2

Ou on peut aussi utiliser la fonction freq afin de trouver le nombre de récurrences

proc freq
     data = bdSQL.doublons;
     tables Nom / nocum nocol norow nopercent
     ;
run;
SAS Output

Duplicate Rows in Duplicates Table

The FREQ Procedure

Nom Frequency
Gabriel A 1
JM P 1
JP B 1
Mathieu B 1
Mathieu P 2
Noureddine M 1

PROC rank#

Cette procédure est très intéressante si vous voulez trouver le rang d’une observation par variable. Dans l’exemple suivant, nous cherchons le rang de chaque candidat aux élections. D’abord, par le nombre de votes. Ensuite, par année.

data elect;
   input Candidate $ 1-11 District 13 Vote 15-18 Years 20;
   datalines;
Cardella    1 1689 8
Latham      1 1005 2
Smith       1 1406 0
Walker      1  846 0
Hinkley     2  912 0
Kreitemeyer 2 1198 0
Lundell     2 2447 6
Thrash      2  912 2
;
proc rank data=elect out=results ties=low descending;
   by district;
   var vote years;
   ranks VoteRank YearsRank;
run;
proc print data=results n;
   by district;
   title 'Results of City Council Election';
run; 
SAS Output

Results of City Council Election

Obs Candidate Vote Years VoteRank YearsRank
1 Cardella 1689 8 1 1
2 Latham 1005 2 3 2
3 Smith 1406 0 2 3
4 Walker 846 0 4 3
N = 4 
Obs Candidate Vote Years VoteRank YearsRank
5 Hinkley 912 0 3 3
6 Kreitemeyer 1198 0 2 3
7 Lundell 2447 6 1 1
8 Thrash 912 2 3 2
N = 4 

Compare procedure#

La procédure Compare est aussi intéressante lorsque vous voulez comparer les différences deux variables se trouvant dans deux tables différentes. En voici un exemple où l’on veut comparer la variable coutTot dans les deux tables prov_alar_sinis et prov_alar_sinis2. On se rappelle que dans la deuxième, nous avons augmenté les coûts de primes par 2%, seulement pour les véhicules qui ne sont pas munis d’un système d’alarme.

options nodate pageno=1 linesize=80 pagesize=40;
proc compare base=bdSQL.prov_alar_sinis2 compare=bdSQL.prov_alar_sinis nosummary;
   var coutTot;
   with coutTot;
   title 'Comparison of Variables in Different Data Sets';
run;
SAS Output

Comparison of Variables in Different Data Sets

                             The COMPARE Procedure                              
        Comparison of BDSQL.PROV_ALAR_SINIS2 with BDSQL.PROV_ALAR_SINIS         
                                 (Method=EXACT)                                 
                                                                                
NOTE: Values of the following 1 variables compare unequal: coutTot^=coutTot     
                                                                                
                                                                                
                     Value Comparison Results for Variables                     
                                                                                
           __________________________________________________________           
                      ||       Base    Compare                                  
                  Obs ||    coutTot    coutTot      Diff.     % Diff            
            ________  ||  _________  _________  _________  _________            
                      ||                                                        
                   1  ||  1846861.2  1810648.3     -36213    -1.9608            
                   3  ||  1882788.0  1845870.6     -36917    -1.9608            
                   5  ||  1852380.2  1816059.0     -36321    -1.9608            
                   7  ||  4145154.1  4063876.5     -81278    -1.9608            
                   9  ||  2157170.9  2114873.4     -42297    -1.9608            
                  11  ||  1868507.0  1831869.6     -36637    -1.9608            
                  13  ||  1901146.5  1863869.2     -37277    -1.9608            
                  15  ||  1803299.2  1767940.4     -35359    -1.9608            
                  17  ||  1906879.7  1869489.9     -37390    -1.9608            
                  19  ||  1859494.4  1823033.7     -36461    -1.9608            
                  21  ||  1826840.9  1791020.5     -35820    -1.9608            
                  23  ||  2120114.0  2078543.1     -41571    -1.9608            
                  25  ||  2132439.3  2090626.7     -41813    -1.9608            
           __________________________________________________________           

TRANSPOSE Procedure#

La procédure Transpose peut être très utile lorsque nous voulons transposer nos variables en observation et vice versa. Dans l’exemple suivant, nous avons une liste d’étudiants (observation) avec les notes qu’ils ont eues à trois examens (donc trois variables). On voudrait trois observations (trois lignes) qui représentent Test1, Test2 et Test3. Et sept variables (les 7 étudiants).

options nodate pageno=1 linesize=80 pagesize=40;
data score;
   input Student $9. StudentID $ Section $ Test1 Test2 Final;
   datalines;
Capalleti 0545 1  94 91 87
Dubose    1252 2  51 65 91
Engles    1167 1  95 97 97
Grant     1230 2  63 75 80
Krupski   2527 2  80 76 71
Lundsford 4860 1  92 40 86
McBane    0674 1  75 78 72
;
proc print data=score noobs;
    title 'Données oriiginales';
run;

proc transpose data=score out=score_transposed;
run;

proc print data=score_transposed noobs;
    title 'Student Test Scores in Variables';
run;
SAS Output

Données oriiginales

Student StudentID Section Test1 Test2 Final
Capalleti 0545 1 94 91 87
Dubose 1252 2 51 65 91
Engles 1167 1 95 97 97
Grant 1230 2 63 75 80
Krupski 2527 2 80 76 71
Lundsford 4860 1 92 40 86
McBane 0674 1 75 78 72

Student Test Scores in Variables

_NAME_ COL1 COL2 COL3 COL4 COL5 COL6 COL7
Test1 94 51 95 63 80 92 75
Test2 91 65 97 75 76 40 78
Final 87 91 97 80 71 86 72