Exercices_de_synthese_-_SAS_Base
- Mobiliser, sur des cas complets, l'ensemble des notions vues dans les modules I à VII
- Enchaîner import, transformation, statistiques et graphiques sur un même jeu de données
- Savoir repérer et corriger une anomalie de saisie à partir d'un graphique
Avant de commencer
Cette page contient le corrigé complet des exercices donnés en devoir à l'issue du bloc SAS Base (devoirs 1 à 6), réalisés en direct le vendredi 11 septembre entre 14h00 et 18h00. Elle reste masquée pendant que vous travaillez et n'est publiée qu'à la clôture du dépôt, à 18h00 : tant que vous n'avez pas déposé votre travail, vous ne devriez de toute façon pas pouvoir la consulter.
Exercice 1 — Prix des voitures d'occasion
On s'intéresse au prix de vente des voitures d'occasion et aux différents facteurs qui peuvent l'influencer. On travaille sur le fichier cars.txt, la description des données étant disponible dans cars-short-desc.txt.
Voir le corrigé
PROC IMPORT OUT = WORK.CARS
DATAFILE = "/chemin/cars.txt"
DBMS = TAB REPLACE ;
GETNAMES = YES ;
RUN ;
data cars2 ;
set cars ;
format price 8.2 mileage 6.0 cylinder 1.0 liter 3.1
doors 1.0 cruise 1.0 sound 1.0 leather 1.0 ;
run ;
Voir le corrigé
data cars2 ;
set cars2 ;
kilometrage = mileage * 1.6 ;
drop mileage ;
run ;
Voir le corrigé
symbol1 i=none v=star c=red ;
proc gplot data=cars2 ;
plot price*kilometrage = 1 ;
run ; quit ;
À première vue, le nuage de points ne montre aucun lien net entre le prix et le kilométrage. Mais en triant et en stratifiant l'analyse par marque, modèle et finition, la relation devient beaucoup plus nette :
proc sort data=cars2 ;
by Make Model Trim ;
run ;
proc sgplot data=cars2 ;
by Make ;
reg y=Price x=Kilometrage ;
run ;
C'est une bonne illustration d'un principe général : un nuage de points global peut masquer une relation qui n'apparaît qu'une fois la population correctement stratifiée.
Voir le corrigé
proc print data=cars ;
where price > 52000 ;
run ;
Il ne s'agit pas de valeurs aberrantes : ce sont des véhicules haut de gamme cohérents entre eux (cylindrée, équipement). La bonne approche, comme à la question 3, est d'analyser par marque et par modèle plutôt que sur la population entière.
Exercice 2 — Températures
Le fichier temperatures.txt contient 546 données mensuelles et quatre variables correspondant à l'année et au mois de chaque observation, ainsi qu'au niveau des précipitations (en mm) et à la température (en °C).
Voir le corrigé
PROC IMPORT DATAFILE = "/chemin/temperatures.txt"
OUT = WORK.TEMPERATURES DBMS = TAB REPLACE ;
RUN ;
Voir le corrigé
data temp2 ;
set temperatures ;
format year 4.0 month z2. ;
year = year + 1900 ;
run ;
Point important : dans ce fichier, l'année est codée sur deux chiffres (75 pour 1975). Aucun format ne peut deviner ce décalage à votre place : c'est une correction explicite (
year = year + 1900) qu'il faut faire dans les données, pas seulement un affichage.Voir le corrigé
data temp3 ;
set temp2 ;
date = mdy(month, 1, year) ;
format date monyy5. ;
run ;
Voir le corrigé
proc print data=temp3 (obs=10) ;
var precp temp ;
id date ;
run ;
Voir le corrigé
proc means data=temp3 noprint ;
var precp ;
output out=tab1 mean=m1 std=sigma max=maxi min=mini ;
run ;
proc print data=tab1 ; run ;
Voir le corrigé
proc means data=temp3 noprint ;
var temp precp ;
class year ;
output out=tab2 mean=m_temp m_precp ;
run ;
data tab2 ;
set tab2 ;
if _type_ = 0 then delete ;
drop _type_ ;
run ;
proc print data=tab2 ;
var m_temp m_precp ;
id year ;
run ;
symbol1 i=join v=none c=black ;
symbol2 i=join v=none c=red ;
proc gplot data=tab2 ;
plot m_temp*year=1 m_precp*year=2 / overlay ;
title "Moyennes annuelles - temperatures et precipitations" ;
run ;
/* Avec deux echelles distinctes en ordonnee */
proc gplot data=tab2 ;
plot m_temp*year=1 ;
plot2 m_precp*year=2 ;
run ;
title ;
Voir le corrigé
proc means data=temp3 noprint ;
var temp precp ;
class month ;
output out=tab3 mean=m_temp m_precp ;
run ;
data tab3 ;
set tab3 ;
if _type_ = 0 then delete ;
drop _type_ ;
run ;
proc print data=tab3 ;
var m_temp m_precp ;
id month ;
run ;
proc gplot data=tab3 ;
plot m_temp*month=1 m_precp*month=2 / overlay ;
title "Moyennes mensuelles - temperatures et precipitations" ;
run ;
proc gplot data=tab3 ;
plot m_temp*month=1 ;
plot2 m_precp*month=2 ;
run ;
title ; goptions reset=title ;
Exercice 3 — Pourboires
On étudie les facteurs qui pourraient influencer le montant des pourboires dans un restaurant, à partir du fichier tips.txt (description dans tips-short-desc.txt).
Voir le corrigé
data tips ;
infile "/chemin/tips.txt" ;
input IDEN $ 1-4 TOTBILL 7-11 TIP 15-18 SEX 23-23
SMOKER 30-30 DAY 35-35 TIME 40-40 SIZE 45-45 ;
run ;
Voir le corrigé
data tips2 ;
set tips ;
rate = (tip*100) / totbill ;
format rate 5.2 ;
run ;
Voir le corrigé
proc means data=tips2 ;
var totbill tip rate size ;
run ;
Voir le corrigé
proc format ;
value jour 3='Jeudi' 4='Vendredi' 5='Samedi' 6='Dimanche' ;
value moment 0='Dejeuner' 1='Diner' ;
run ;
data tips3 ;
set tips2 ;
format day jour. time moment. ;
run ;
Voir le corrigé
proc sort data=tips3 ;
by day ;
run ;
proc means data=tips3 ;
var rate ;
by day ;
class time ;
run ;
Voir le corrigé
proc sort data=tips3 ;
by sex smoker ;
run ;
proc means data=tips3 ;
var rate ;
by sex smoker ;
class size ;
run ;
Exercice 4 — Notes d'étudiants
Voir le corrigé
data notes ;
input nom $ int1 int2 int3 ;
cards ;
Eric 12 3 8
Maxence 15 4 13
Margaux 12 13 17
Xavier 4 12 10
Elisa 16 5 9
;
run ;
Voir le corrigé
data notes2 ;
set notes ;
format etendue 4.2 moyenne 4.2 std 4.2 ;
etendue = max(of int1-int3) - min(of int1-int3) ;
moyenne = mean(of int1-int3) ;
std = std(of int1-int3) ;
run ;
Voir le corrigé
proc print data=notes2 ; run ;
Voir le corrigé
proc sort data=notes2 out=notes_tri1 ;
by nom ;
run ;
proc sort data=notes2 out=notes_tri2 ;
by descending moyenne ;
run ;
Voir le corrigé
proc sort data=notes2 out=notes_tri3 ;
by descending int2 ;
run ;
proc print data=notes_tri3 ;
var int2 ;
id nom ;
run ;
Point de vigilance : après un tri vers une table de sortie (
out=), pensez à diriger la PROC PRINT vers cette nouvelle table triée, et non vers la table d'origine — c'est l'erreur la plus fréquente sur ce type de question.Exercice 5 (facultatif) — Graphique combiné
On retravaille sur la table temp3 de l'exercice 2.
Voir le corrigé
symbol1 i=join v=none c=black ;
symbol2 v=star c=red l=2 ;
proc gplot data=temp3 ;
plot precp*date=1 temp*date=2 / overlay ;
title "Precipitations et temperatures au Canada" ;
run ;
title ;
Exercice 6 — Courses de voitures (NASCAR)
On s'intéresse aux gains des pilotes lors des courses NASCAR, à partir du fichier nascar.txt (description dans nascar-short-desc.txt).
Voir le corrigé
data nascar ;
infile "/chemin/nascar.txt" lrecl=100 pad ;
input Series 1-3 Year 6-9 @12 Race_Year 2. @16 Finish_Pos 2. @20 Start_Pos 2.
@24 Laps 3. @29 Winnings 7. @38 Cars 2. @42 Car_Make $9. @53 Driver $30. ;
run ;
proc contents data=nascar ; run ;
Voir le corrigé
proc means data=nascar noprint ;
by year ;
class driver ;
var winnings ;
output out=gain_annuel sum=gain ;
run ;
data gain_annuel2 ;
set gain_annuel ;
if _type_ = 0 then delete ;
drop _type_ ;
run ;
Voir le corrigé
proc sort data=nascar out=nascar_tri ;
by year descending laps ;
run ;
data all_laps ;
set nascar_tri ;
by year ;
retain laps_max ;
if first.year then laps_max = laps ; /* le pilote de tete du classement a boucle le plus de tours */
if laps = laps_max then output ; /* on ne garde que ceux qui ont boucle autant de tours que lui */
run ;
proc print data=all_laps (obs=10) noobs ; run ;
Un pilote qui abandonne en course boucle moins de tours que celui qui mène la course jusqu'au bout : comparer le nombre de tours de chaque pilote à celui du meneur de son année est donc un bon indicateur de qui a réellement terminé la course. La sélection elle-même reste une pure étape DATA, construite avec RETAIN et FIRST., exactement comme au module V ; seul le tri préalable (nécessaire à l'instruction BY) passe par une PROC SORT.
Exercice 7 — Factures d'électricité
On s'intéresse au montant (en dollars) des factures d'électricité d'une famille américaine, à partir du fichier electricbill.txt (description dans electricbill-short-desc.txt).
Voir le corrigé
data electric ;
infile "/chemin/electricbill.txt" ;
input NUM 1-3 YEAR 5-8 MONTH $ 10-12 BILL 14-19 TEMP 21-24 HDD 26-29 CDD 31-33
SIZE 35 METER 37 PUMP1 39 PUMP2 41 RIDER_TOTAL 43-52 CONSUMPTION 54-58 ;
run ;
proc contents data=electric ; run ;
Voir le corrigé
data electric2 ;
set electric ;
format temp_c 4.1 ;
temp_c = (5/9)*(temp-32) ;
drop temp ;
run ;
Voir le corrigé
data electric3 ;
set electric2 ;
a = mod(num,12) ; /* reconstruit un cycle 1 a 12 a partir du numero sequentiel */
if a = 0 then a = 12 ;
ident = mdy(a, 1, year) ;
format ident monyy7. ;
drop a ;
run ;
Voir le corrigé
symbol1 i=join v=none c=black ;
proc gplot data=electric3 ;
plot bill*ident=1 / skipmiss ;
run ;
Un point clairement aberrant apparaît fin décembre. En y regardant de plus près (observation NUM=24) : il s'agit d'une véritable erreur de saisie, l'année ayant été notée 93 au lieu de 92.
data electric4 ;
set electric3 ;
if num = 24 then year = 1992 ;
a = mod(num,12) ;
if a = 0 then a = 12 ;
ident = mdy(a, 1, year) ;
format ident monyy7. ;
drop a ;
run ;
proc gplot data=electric4 ;
plot bill*ident=1 / skipmiss ;
run ;
Voir le corrigé
proc means data=electric4 ;
var bill ;
class year ;
run ;
proc means data=electric4 ;
var bill ;
class month ;
run ;
Voir le corrigé
proc means data=electric4 ;
var bill ;
class size ;
run ;
Voir le corrigé
proc means data=electric4 ;
var bill ;
class meter ;
run ;
Background Colour
Font Face
Font Kerning
Image Visibility
Line Height
Link Highlight
Text Alignment
Font Size
Letter Spacing
Text Colour
Paragraph Width