SAS – Guide Complet

Reference complete pour manipuler, analyser et automatiser vos donnees avec SAS.

Sommaire

📚 Fondamentaux

Structure de base

ElementRoleExemple
DATACreer/modifier une tabledata resultat; set source; run;
PROCAnalyser/afficher des donneesproc print data=table; run;
LIBNAMEDefinir une bibliothequelibname mylib "/chemin";
WORKBibliotheque temporaire (defaut)data test; = data work.test;

Bibliotheques

/* Creer une reference vers un dossier */
libname mylib "/chemin/vers/dossier";

/* Copier une table */
data work.copie;
  set mylib.ma_table;
run;

🔧 DATA Step

Operations courantes

ActionSyntaxe
Nouvelle variablenouvelle_var = calcul;
Garder colonnesset source (keep=col1 col2);
Exclure colonnesset source (drop=col1 col2);
Renommerset source (rename=(ancien=nouveau));
Definir longueur textelength nom $50;
Supprimer lignedelete;
Garder ligneoutput;

Conditions IF/THEN/ELSE

data resultat;
  set source;
  length categorie $10;  /* Toujours definir length AVANT */

  if age < 18 then categorie = 'Mineur';
  else if age <= 65 then categorie = 'Adulte';
  else categorie = 'Senior';
run;

SELECT/WHEN (switch case)

data resultat;
  set source;
  length libelle $20;

  select(code);
    when('A') libelle = 'Actif';
    when('I') libelle = 'Inactif';
    when('S', 'P') libelle = 'Suspendu';  /* plusieurs valeurs */
    otherwise libelle = 'Inconnu';
  end;
run;

Boucles DO

/* Boucle simple */
do i = 1 to 10;
  /* code */
end;

/* Boucle avec pas */
do annee = 2020 to 2025 by 1;
  /* code */
end;

/* DO WHILE / DO UNTIL */
do while(condition);
  /* tant que vrai */
end;

do until(condition);
  /* jusqu'a ce que vrai */
end;

🎯 Filtres et Tri

WHERE vs IF

WHEREIF
Filtre a la lecture (performant)Filtre apres lecture
Ne peut pas utiliser variables calculeesPeut utiliser variables calculees
where age >= 18;if total > 1000;

Operateurs WHERE

OperateurDescriptionExemple
= ou EQEgalwhere ville = 'Paris';
^= ou NEDifferentwhere statut ^= 'X';
> < >= <=Comparaisonwhere age >= 18;
INDans une listewhere ville in ('Paris', 'Lyon');
BETWEENEntre deux valeurswhere age between 18 and 65;
LIKEPattern matchingwhere nom like 'DUP%';
CONTAINSContientwhere email contains '@gmail';
IS NULLValeur manquantewhere date is null;
IS NOT NULLNon manquantwhere date is not null;

PROC SORT

/* Tri croissant */
proc sort data=ma_table;
  by nom prenom;
run;

/* Tri decroissant */
proc sort data=ma_table;
  by descending date;
run;

/* Supprimer doublons (garde 1ere occurrence) */
proc sort data=ma_table nodupkey;
  by id_client;
run;

/* Supprimer lignes identiques */
proc sort data=ma_table nodup;
  by _all_;
run;

🔗 Jointures

Types de jointures

TypeMERGESQL
INNER JOINif a and b;inner join
LEFT JOINif a;left join
RIGHT JOINif b;right join
FULL JOIN(pas de condition)full join

MERGE (DATA Step)

/* IMPORTANT: trier les tables avant MERGE */
proc sort data=clients; by id; run;
proc sort data=commandes; by id; run;

/* LEFT JOIN */
data fusion;
  merge clients(in=a) commandes(in=b);
  by id;
  if a;
run;

Empiler des tables

/* SET = empiler verticalement */
data tout;
  set table1 table2 table3;
run;

/* PROC APPEND (plus rapide) */
proc append base=existante data=nouvelles force;
run;

💾 PROC SQL

Syntaxe de base

proc sql;
  create table resultat as
  select
    departement,
    count(*) as nb,
    avg(salaire) as sal_moy format=8.2,
    sum(salaire) as total
  from employes
  where statut = 'A'
  group by departement
  having count(*) > 5
  order by sal_moy desc;
quit;

Fonctions SQL utiles

FonctionDescription
count(*)Nombre de lignes
count(distinct col)Valeurs distinctes
sum(col)Somme
avg(col)Moyenne
min(col) / max(col)Min / Max
coalesce(a, b, c)Premiere valeur non null
case when ... then ... else ... endCondition
calculated colUtiliser colonne calculee

Jointures SQL

proc sql;
  create table fusion as
  select a.*, b.montant
  from clients as a
  left join commandes as b
    on a.id = b.id_client;
quit;

📝 Fonctions Texte

FonctionDescriptionExemple
upcase(x)Majuscules'pierre''PIERRE'
lowcase(x)Minuscules'PIERRE''pierre'
propcase(x)Premiere lettre maj'pierre''Pierre'
strip(x)Supprime espaces debut/fin' abc ''abc'
compress(x)Supprime tous les espaces'a b c''abc'
compress(x, '', 'kd')Garde que chiffres'ab12cd''12'
compress(x, '', 'ka')Garde que lettres'ab12cd''abcd'
substr(x, pos, len)Extraire sous-chainesubstr('HELLO', 1, 2)'HE'
length(x)Longueurlength('abc')3
index(x, 'mot')Position du motindex('hello', 'l')3
find(x, 'mot', 'i')Position (insensible casse)Option 'i' = ignore case
tranwrd(x, 'old', 'new')RemplacerRemplace toutes occurrences
catx(sep, a, b, c)Concatener avec separateurcatx('-', 'a', 'b')'a-b'
cats(a, b)Concatener sans espacesStrip puis concat
scan(x, n, 'delim')Nieme motscan('a-b-c', 2, '-')'b'
countw(x, 'delim')Compter les motscountw('a b c')3
reverse(x)Inverser'abc''cba'

🔢 Fonctions Numeriques

FonctionDescriptionExemple
round(x, 0.01)Arrondirround(3.456, 0.01)3.46
ceil(x)Arrondi superieurceil(3.1)4
floor(x)Arrondi inferieurfloor(3.9)3
int(x)Partie entiereint(3.7)3
abs(x)Valeur absolueabs(-5)5
mod(x, y)Modulo (reste)mod(10, 3)1
min(a, b, c)MinimumIgnore les missings
max(a, b, c)MaximumIgnore les missings
sum(a, b, c)SommeIgnore les missings
mean(a, b, c)MoyenneIgnore les missings
n(a, b, c)Nb valeurs non missingn(1, ., 3)2
nmiss(a, b, c)Nb valeurs missingnmiss(1, ., 3)1
missing(x)Test si missingRetourne 1 si missing
coalesce(a, b, c)1ere valeur non missingUtile pour valeur defaut
log(x)Logarithme naturel
exp(x)Exponentielle
sqrt(x)Racine carree
ranuni(seed)Nombre aleatoire [0,1]

📅 Fonctions Date

Dates courantes

FonctionRetourne
today()Date du jour (SAS date)
date()Idem today()
datetime()Date et heure actuelles
time()Heure actuelle

Extraire des composants

FonctionDescription
year(date)Annee (ex: 2025)
month(date)Mois (1-12)
day(date)Jour du mois (1-31)
weekday(date)Jour semaine (1=dim, 7=sam)
qtr(date)Trimestre (1-4)
week(date)Numero semaine
hour(datetime)Heure
minute(datetime)Minutes
second(datetime)Secondes

Creer et calculer des dates

/* Creer une date */
ma_date = mdy(12, 25, 2025);   /* mois, jour, annee */
ma_date = yymmdd(2025, 12, 25);

/* Difference entre dates */
nb_jours = date_fin - date_debut;
nb_mois = intck('month', date_debut, date_fin);
nb_ans = intck('year', date_naissance, today());

/* Ajouter a une date */
date_future = intnx('month', today(), 3);      /* +3 mois */
date_future = intnx('year', today(), 1, 'same'); /* +1 an, meme jour */

/* Debut/fin de periode */
debut_mois = intnx('month', today(), 0, 'beginning');
fin_mois = intnx('month', today(), 0, 'end');

Intervalles INTCK/INTNX

IntervalleDescription
'day'Jours
'week'Semaines
'month'Mois
'qtr'Trimestres
'year'Annees
'weekday'Jours ouvres

Conversions PUT / INPUT

ConversionFonctionExemple
Num → Texteput()put(age, 3.)"25"
Date → Texteput()put(date, date9.)"25DEC2025"
Texte → Numinput()input("25", 3.)25
Texte → Dateinput()input("2025-12-25", yymmdd10.)

🎨 Formats d'Affichage

Formats courants

FormatResultatExemple
8.Nombre entier12345678
8.22 decimales12345.67
comma12.2Separateur milliers1,234,567.89
dollar12.2Dollar$1,234.56
eurox12.2Euro (format EU)1.234,56
percent8.1Pourcentage75.5%
date9.Date SAS25DEC2025
ddmmyy10.Date EU25/12/2025
yymmdd10.Date ISO2025-12-25
datetime20.Date + heure25DEC2025:14:30:00
$char50.Texte 50 carPreserve espaces

Formats personnalises

proc format;
  /* Format texte ($ = caractere) */
  value $statut_fmt
    'A' = 'Actif'
    'I' = 'Inactif'
    other = 'Inconnu'
  ;

  /* Format numerique */
  value age_grp
    low-17 = 'Mineur'
    18-64 = 'Adulte'
    65-high = 'Senior'
  ;
run;

/* Appliquer */
format statut $statut_fmt. age age_grp.;

📊 Procedures Courantes

PROC PRINT

proc print data=table (obs=10) noobs;
  var nom prenom age;
  where age > 30;
run;

PROC FREQ

/* Frequences simples */
proc freq data=table;
  tables categorie / missing;
run;

/* Tableau croise */
proc freq data=table;
  tables cat1 * cat2 / nocol norow nopercent;
run;

/* Exporter resultats */
proc freq data=table;
  tables categorie / out=freq_result;
run;

PROC MEANS

proc means data=table n mean std min max sum;
  var salaire age;
  class departement;
  output out=stats
    mean=sal_moy age_moy
    sum=sal_total;
run;

PROC SUMMARY

/* Comme MEANS mais sans affichage par defaut */
proc summary data=table nway;
  class region annee;
  var ventes;
  output out=resume(drop=_type_ _freq_)
    sum=total
    mean=moyenne;
run;

PROC TRANSPOSE

/* Pivoter lignes → colonnes */
proc transpose data=source out=pivot;
  by id;
  id variable_pivot;
  var valeur;
run;

PROC CONTENTS

/* Voir structure table */
proc contents data=table;
run;

/* Exporter metadonnees */
proc contents data=table out=meta noprint;
run;

📥 Import / Export

Importer

/* CSV */
proc import datafile="/chemin/fichier.csv"
  out=ma_table
  dbms=csv replace;
  getnames=yes;
  guessingrows=max;
  delimiter=';';
run;

/* Excel */
proc import datafile="/chemin/fichier.xlsx"
  out=ma_table
  dbms=xlsx replace;
  sheet="Feuille1";
  getnames=yes;
run;

Exporter

/* CSV */
proc export data=ma_table
  outfile="/chemin/export.csv"
  dbms=csv replace;
  delimiter=';';
run;

/* Excel */
proc export data=ma_table
  outfile="/chemin/export.xlsx"
  dbms=xlsx replace;
  sheet="Donnees";
run;

⚙️ Macros SAS

Variables Macro

/* Definir */
%let annee = 2025;
%let chemin = /dossier/data;

/* Utiliser */
data donnees_&annee;
  set "&chemin/source.sas7bdat";
run;

/* Afficher dans log */
%put Annee: &annee;

Macros avec parametres

%macro stats(table=, var=);
  proc means data=&table;
    var &var;
  run;
%mend;

/* Appel */
%stats(table=employes, var=salaire)

Boucles et conditions

/* Boucle */
%macro traiter;
  %do i = 2020 %to 2025;
    data data_&i;
      set source;
      where year(date) = &i;
    run;
  %end;
%mend;

/* Condition */
%if &type = detail %then %do;
  proc print; run;
%end;

Fonctions macro utiles

FonctionDescription
%sysfunc(today(), date9.)Date du jour formatee
%sysfunc(exist(table))Table existe? (1/0)
%scan(&liste, 2)2eme element liste
%eval(1+1)Calcul entier
%sysevalf(1.5+2.5)Calcul decimal
%length(&var)Longueur variable
%upcase(&var)Majuscules
%substr(&var, 1, 3)Sous-chaine

💡 Tips et Bonnes Pratiques

Debug

/* Activer debug macros */
options mprint mlogic symbolgen;

/* Messages log */
%put NOTE: Traitement OK;
%put WARNING: Attention;
%put ERROR: Echec;

Nettoyer

/* Supprimer toutes tables WORK */
proc datasets library=work kill nolist;
quit;

/* Supprimer une table */
proc delete data=table_temp;
run;

Dictionnaires systeme

/* Lister tables */
proc sql;
  select memname, nobs
  from dictionary.tables
  where libname = 'WORK';
quit;

/* Lister colonnes */
proc sql;
  select name, type, length
  from dictionary.columns
  where libname = 'WORK' and memname = 'MA_TABLE';
quit;

Raccourcis utiles

AstuceDescription
_all_Toutes les variables
_numeric_Variables numeriques
_character_Variables texte
_n_Numero de ligne courante
_error_Flag erreur (0/1)
first.var1ere ligne du groupe BY
last.varDerniere ligne du groupe BY
col1--col10Range de colonnes
col:Colonnes commencant par "col"