SAS9

Optimiser PROC TTEST sur des milliers de variables et structurer ses données

Simon 12 vues
Niveau de difficulté
Confirmé
Publié le :
Stéphanie

Le conseil de l'expert

Stéphanie

Le réflexe de la boucle macro est souvent l'ennemi de la performance : lancer 2 500 fois une procédure est incroyablement coûteux pour le système. La règle d'or en statistique SAS est de privilégier la structure des données (format "Long") pour exploiter le traitement par groupe (BY statement). C'est la différence entre un code qui tourne en 30 minutes et un code qui tourne en 30 secondes

L'analyse de données d'expression génétique présente souvent un défi de taille : la multiplicité des variables. Lorsqu'il s'agit de comparer l'expression de milliers de gènes entre deux groupes (par exemple, des sujets "affectés" vs "non affectés"), l'approche naïve consiste souvent à utiliser des macros pour boucler sur chaque variable.

Cependant, cette méthode peut se heurter à des problèmes de performance et, plus sournoisement, à des erreurs de structure de données menant à des résultats nuls ($n=0$).

Optimiser PROC TTEST sur des milliers de variables et structurer ses données -

Le piège de l'instruction PAIRED et des données manquantes

Imaginez un jeu de données où chaque ligne représente un sujet. Vous avez des colonnes pour les gènes d'individus sains (unaffected_gene_x) et d'autres pour les individus malades (affected_gene_x).

Si vous tentez d'utiliser l'instruction PAIRED dans PROC TTEST :

1
1paired unaffected_gene_1 * affected_gene_1;

SAS© va automatiquement exclure toute ligne contenant une valeur manquante dans l'une des deux variables. Si vos données sont structurées de telle sorte qu'un sujet est soit dans le groupe sain, soit dans le groupe malade (et a donc une valeur manquante pour l'autre condition), SAS© exclura toutes les observations. Résultat : le journal affiche 0 observation utilisée.

La Solution : Restructurer les données ("Wide to Long")

Au lieu de créer une macro complexe qui lance PROC TTEST 2500 fois (ce qui est inefficace), la meilleure pratique consiste à restructurer les données pour n'avoir qu'une seule colonne de valeurs et une colonne d'identification (Groupe/Statut).

Voici comment transformer vos données "larges" en données "longues" avec une étape DATA et des tableaux (ARRAY) :

1DATA analyse_genes;
2 SET donnees_source;
3 /* Déclaration des tableaux pour vos colonnes existantes */
4 /* Ajustez la dimension (ici 10) au nombre réel de gènes (ex: 2500) */
5 array u unaffected_gene_1 - unaffected_gene_10;
6 array a affected_gene_1 - affected_gene_10;
7
8 /* Boucle pour pivoter les données */
9 DO gene_id = 1 to dim(u);
10 /* Traitement du cas 'Non Affecté' */
11 IF u[gene_id] ne . THEN DO;
12 STATUS = 'Unaffected';
13 value = u[gene_id];
14 OUTPUT;
15 END;
16
17 /* Traitement du cas 'Affecté' */
18 IF a[gene_id] ne . THEN DO;
19 STATUS = 'Affected';
20 value = a[gene_id];
21 OUTPUT;
22 END;
23 END;
24 keep gene_id STATUS value;
25RUN;
26 
27/* Tri indispensable pour le traitement par groupe */
28PROC SORT DATA=analyse_genes;
29 BY gene_id;
30RUN;
Cette transformation permet de passer d'une structure dispersée à une structure optimisée pour l'analyse statistique de groupe.

Exécuter le T-Test efficacement

Une fois les données restructurées, plus besoin de macro. Une seule procédure PROC TTEST suffit, en utilisant l'instruction BY pour traiter chaque gène séparément et CLASS pour définir les groupes.

1PROC TTEST DATA=analyse_genes;
2 BY gene_id; /* Effectue le test pour chaque gène */
3 class STATUS; /* Définit les groupes (Affected / Unaffected) */
4 var value; /* La variable contenant la mesure */
5RUN;
Cette méthode est nettement plus rapide que d'invoquer la procédure des milliers de fois.

Automatiser la récupération des résultats significatifs

Avec des milliers de tests, lire la sortie standard est impossible. L'astuce consiste à utiliser ODS OUTPUT pour récupérer les statistiques (valeurs t et p-values) dans une table, puis de filtrer cette table.

1/* Redirection des résultats vers une table SAS */
2ods OUTPUT ttests = resultats_ttests;
3 
4PROC TTEST DATA=analyse_genes;
5 BY gene_id;
6 class STATUS;
7 var value;
8RUN;
9 
10/* Filtrer pour ne garder que les différences significatives */
11DATA genes_significatifs;
12 SET resultats_ttests;
13 /* On filtre souvent sur la méthode Pooled ou Satterthwaite selon l'égalité des variances */
14 where Probt < 0.05;
15RUN;

La table resultats_ttests contiendra des variables comme tValue (statistique t) et Probt (la p-value), vous permettant d'identifier immédiatement les gènes d'intérêt parmi des milliers.