Précédent   Forum des professionnels en informatique > Logiciels > Solutions d'entreprise > Business Intelligence > SAS > SAS Base
SAS Base Forum d'entraide sur SAS base : étape data, procédures non statistiques, procédures non graphiques, SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 10/02/2011, 10h56   #1
Invité de passage
 
Inscription : février 2011
Messages : 20
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 20
Points : 2
Points : 2
Par défaut problème boucle sas

Bonjour,
je bloque depuis quelques temps sur un programme sas dans lequel on répète plusieurs fois la même chose mais je ne parviens pas à écrire une boucle (ou une macro) permettant de faire ce que je veux.
Mon jeu de données se compose comme suit: j'ai une ligne par patient et des variables allant de visite1 à visite20 correspondant aux dates des visites des patients. J'ai aussi des scores EGS1 à EGS25 et les dates associés date_EGS1 à date_EGS25 (j'espère que je suis assez clair).

Voici ce que je souhaiterais faire:
je voudrais créer une variable remission qui vaut 1 si le temps entre deux visites est d'au moins deux ans et s'il existe des score EGS à ces dates qui sont égaux. Autrement dit il faudrait que je compare deux à deux les visites pour vérifier s'il y a bien plus de deux ans d'écarts et si les dates de scores EGS coincident avec ces dates de visites et que les scores soient égaux.

J'espere vraiment que quelqu'un pourra m'aider car je suis coincé et je ne sais pas comment m'en sortir.

Merci beaucoup
fabien21 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/02/2011, 11h57   #2
Membre Expert
 
Avatar de MEGAMIND2
 
Homme Brice Beare
Paris
Inscription : janvier 2011
Messages : 956
Détails du profil
Informations personnelles :
Nom : Homme Brice Beare
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Paris

Informations forums :
Inscription : janvier 2011
Messages : 956
Points : 1 366
Points : 1 366
Tu peux poster quelques lignes de ta table? ça éviterait de travailler sur une table qui n'a pas la même structure que la tienne
MEGAMIND2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/02/2011, 12h14   #3
Invité de passage
 
Inscription : février 2011
Messages : 20
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 20
Points : 2
Points : 2
Voici quelques lignes de ma table en piece jointe ! Il y a trop de variables pour pouvoir afficher sur ce message.

J'espere que cela suffira
Merci
Fichiers attachés
Type de fichier : xls test.xls (17,0 Ko, 5 affichages)
fabien21 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/02/2011, 14h12   #4
Expert Confirmé
 
Avatar de olivier.decourt
 
Homme Olivier Decourt
Formateur en informatique
Inscription : avril 2008
Messages : 1 467
Détails du profil
Informations personnelles :
Nom : Homme Olivier Decourt
Âge : 34
Localisation : France

Informations professionnelles :
Activité : Formateur en informatique
Secteur : Conseil

Informations forums :
Inscription : avril 2008
Messages : 1 467
Points : 2 823
Points : 2 823
Bonjour Fabien.
A l'import, je ne retrouve pas toutes les variables dont tu parles, et plutôt que de chercher, j'ai essayé de faire un programme "de tête" (non testé : il y a donc de fortes chances que ça plante).
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
DATA work.solution ;
  SET work.test ;
  ARRAY date_visite visite1-visite20 ;
  ARRAY date_score  date_EGS1-date_EGS25 ;
  ARRAY score       EGS1-EGS25 ;
 
  remission = 0 ; /* initialisation pour chaque patient */
  DO i=2 TO DIM(date_visite) ; /* parcourons les visites */
    delai = YRDIF(date_visite[i-1],date_visite[i],"ACT/ACT") ; /* nb d'années entre 2 visites */
	IF delai >= 2 THEN DO ;
	  /* on va rechercher les scores */
	  date1 = date_visite[i-1] ; /* créées pour alléger les notations */
	  date2 = date_visite[i] ;
	  DO j=1 TO DIM(date_score) ;
	    IF date_score[j]=date1 THEN score1 = score[j] ;
	  END ;
	  DO k=1 TO DIM(date_score) ;
	    IF date_score[k]=date2 THEN score2 = score[k] ;
	  END ;
      IF score1=score2 THEN remission=1 ;
	END ;
  END ;
RUN ;
L'idée est de parcourir tes séries de variables rassemblées en arrays. Avec les différents compteurs de boucle, on peut calculer aisément des écarts, et ensuite aller récupérer les valeurs qui vont bien.
J'aurais pu m'épargner la boucle d'indice k si j'avais la certitude que tous les scores sont mesurés à des dates consécutives, mais j'ai préféré assurer le coup.
On peut peut-être faire plus simple, mais déjà, est-ce que ça te met dans la bonne direction ?

Bon courage.
Olivier
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/02/2011, 14h37   #5
Invité de passage
 
Inscription : février 2011
Messages : 20
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 20
Points : 2
Points : 2
Ah oui je vois ce que tu veux dire avec les arrays. Il faut que je transforme ma table en vecteurs pour pouvoir ainsi faire des boucles indicées. Je vais voir si j'y arrive avec ce que tu m'as donné comme solutions. Je reviendrais si je n'y arrive toujours pas ^^

Merci.
fabien21 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/02/2011, 14h51   #6
Membre Expert
 
Avatar de MEGAMIND2
 
Homme Brice Beare
Paris
Inscription : janvier 2011
Messages : 956
Détails du profil
Informations personnelles :
Nom : Homme Brice Beare
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Paris

Informations forums :
Inscription : janvier 2011
Messages : 956
Points : 1 366
Points : 1 366
Le problème 1 est résolu:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
%MACRO MM;
%DO i=1 %TO 2 ;
%let diff_egs&i=%scan(&diff_egs.,&i.,' ');
DATA PATIENT&i;
SET PATIENT;
IF &&diff_egs&i eq 0;/* score égale*/
run;
%end;
DATA FINAL; SET %DO i=1 %TO 2; PATIENT&i %end;; RUN;
 
%MEND;
%MM;
mais je bloque sur le 2
MEGAMIND2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/02/2011, 16h05   #7
Invité de passage
 
Inscription : février 2011
Messages : 20
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 20
Points : 2
Points : 2
j'ai une mauvaise nouvelle pour moi, après plusieurs tentatives mon code ne fonctionne pas. Je me suis servi de ce que tu m'avais donné Olivier et j'ai tenté de l'appliquer à mon problème mais ça m'affiche une erreur :

Code :
1
2
ERROR: Indice inférieur du tableau impossible à la ligne 940
       colonne 12.
Voici mon code:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
DATA work.test ;
  SET work.episo_perso_diag_clin_simplifie;
  ARRAY date_episode dat_episo1-dat_episo22 ;
  ARRAY date_score  date_clin1-date_clin20 ;
 
   remission = 0 ; /* initialisation pour chaque patient */
  DO i=2 TO DIM(date_episode) ; /* parcourons les visites */
    delai = YRDIF(date_episode[i-1],date_episode[i],"ACT/ACT") ; /* nb d'années entre 2 visites */
	IF ( delai >= 2 & delai ne . & ( ( (date_episode[i]-date_episode[1])/365.25<=5 & date_episode[i] ne .) | ( (date_episode[i-1]+2*365.25<= (date_episode[1]+5*365.25)) & date_episode[i-1] ne .) )) |
		( (last_clinical_follow_up-date_episode[1])/365.25>=2 & (last_clinical_follow_up-date_episode[1])/365.25<=5 & last_clinical_follow_up ne . & (date_episode[2]=. | (date_episode[2] ne . & (date_episode[2]-date_episode[1])/365.25>5)) ) THEN do;
	DO j=0 TO 19;
		IF date_score[1+5*j]=date_episode[i-1] & date_score[1+5*j] ne . then do; score1=date_score[2+5*j]; score1bis=date_score[4+5*j];end;
	end;
	DO k=1 TO 19;
		IF date_score[1+5*k]=date_episode[i] & date_score[1+5*k] ne . then do; score2=date_score[2+5*k]; score2bis=date_score[2+5*k];end;
	end;
	IF score1=score2 | score1bis=score2 | score1=score2bis | score1bis=score2bis then remission=1;
	end;
 end;
run;
Je joins le jeu de données qui m'a servi pour ce code. Je pense pourtant que mon code est juste ...

Merci de votre aide
Fabien
Fichiers attachés
Type de fichier : xls test.xls (118,5 Ko, 6 affichages)
fabien21 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/02/2011, 16h25   #8
Membre Expert
 
Avatar de MEGAMIND2
 
Homme Brice Beare
Paris
Inscription : janvier 2011
Messages : 956
Détails du profil
Informations personnelles :
Nom : Homme Brice Beare
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Paris

Informations forums :
Inscription : janvier 2011
Messages : 956
Points : 1 366
Points : 1 366
Dans ton fichier, c'est quoi la date de visite, la date de score et le score?
MEGAMIND2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/02/2011, 16h29   #9
Invité de passage
 
Inscription : février 2011
Messages : 20
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 20
Points : 2
Points : 2
Alors dans mon fichier la date de visite c'est dat_episo1 dat_episo2 .... dat_episo22, la date de score c'est dat_clin1 dat_clin2 .... dat_clin20 et les scores c'est egs_entered1 edss_entered1, egs_entered2 edss_entered2 .... egs_entered20 edss_entered20.
A chaque date de score il y a deux scores à prendre en compte.

Je ne sais pas si je suis très clair
Fabien
fabien21 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/02/2011, 16h33   #10
Membre Expert
 
Avatar de MEGAMIND2
 
Homme Brice Beare
Paris
Inscription : janvier 2011
Messages : 956
Détails du profil
Informations personnelles :
Nom : Homme Brice Beare
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Paris

Informations forums :
Inscription : janvier 2011
Messages : 956
Points : 1 366
Points : 1 366
Si, c'est clair mais lequel des scores tu vas retenir?
MEGAMIND2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/02/2011, 16h40   #11
Invité de passage
 
Inscription : février 2011
Messages : 20
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 20
Points : 2
Points : 2
ben justement il faut que je compare si un des deux scores d'une date de score i est egal à un des deux autres scores d'une date de score j en prenant biensur en compte que les dates de score i et j doivent coincider avec les dates d'épisodes.
fabien21 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/02/2011, 17h40   #12
Expert Confirmé
 
Avatar de olivier.decourt
 
Homme Olivier Decourt
Formateur en informatique
Inscription : avril 2008
Messages : 1 467
Détails du profil
Informations personnelles :
Nom : Homme Olivier Decourt
Âge : 34
Localisation : France

Informations professionnelles :
Activité : Formateur en informatique
Secteur : Conseil

Informations forums :
Inscription : avril 2008
Messages : 1 467
Points : 2 823
Points : 2 823
Bon, je pense pouvoir dire sans trop me mouiller que les boucles fautives sont celles d'indices j et k.
J va vraiment de 0 à 19 ? Et k de 1 à 19 ? Ils m'ont l'air vraiment symétriques tous les deux !
Effectivement, sinon, le code a l'air correct.
N'hésite pas à essayer de tracer l'exécution de ton code avec des instructions PUT dans l'étape DATA : tu verras dans la log les valeurs de tes indices de boucle et des autres variables.
Code :
1
2
PUT _ALL_ ;
PUT i= j= k= remission= /* etc. */ ;
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/02/2011, 18h51   #13
Membre Expert
 
Avatar de MEGAMIND2
 
Homme Brice Beare
Paris
Inscription : janvier 2011
Messages : 956
Détails du profil
Informations personnelles :
Nom : Homme Brice Beare
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Paris

Informations forums :
Inscription : janvier 2011
Messages : 956
Points : 1 366
Points : 1 366
Un début de code qui pourrait t'inspirer (le fichier en pièce jointe est une copine de la tienne en remplaçant les valeurs manquantes par 0).
Sur le même principe, tu vas determiner la differénce des date de score et le score et appliquer tes conditions pour constituer ta nouvelle variable.

Code :
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
PROC IMPORT DATAFILE= "C:\Documents and Settings\BEARE\***\test.xls"
	OUT = PATIENT2
 
	DBMS = excel2000;
	GETNAMES = YES ;
RUN;
 
DATA PATIENT2;
SET PATIENT2;
IF Patient_ID='' then DELETE;
run;
 
proc contents DATA=PATIENT2 out=NAME ;
run;
 
DATA name2  ;
SET NAME ;
IF INDEX(name,'dat_episo') then output name2;
run;
 
/* date de visite*/
DATA name3;
SET name2;
diff_date_episode=compress('diff_'!!name);
IF name ='dat_episo22'  then DELETE;
run;
 
/* stockage en macro */
PROC SQL;
SELECT diff_date_episode INTO:diff_date_visite separated BY ' ' FROM name3;
SELECT count(*) INTO:NB  FROM name3;
 
 
SELECT name INTO:episode separated BY ' ' FROM name2;
 
quit;
%put diff_date_visite=&diff_date_visite.;
%put episode=&episode.;
 
 
DATA PATIENT2;
SET PATIENT2;
array episode(*) &episode;
array diff_date_visite(*) &diff_date_visite;
do i=1 TO dim(diff_date_visite);
diff_date_visite(i)=ABS(YRDIF(episode(i),episode(i+1),"ACT/ACT")) ;
end;
DROP i;
run;
MEGAMIND2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/02/2011, 09h55   #14
Expert Confirmé
 
Avatar de olivier.decourt
 
Homme Olivier Decourt
Formateur en informatique
Inscription : avril 2008
Messages : 1 467
Détails du profil
Informations personnelles :
Nom : Homme Olivier Decourt
Âge : 34
Localisation : France

Informations professionnelles :
Activité : Formateur en informatique
Secteur : Conseil

Informations forums :
Inscription : avril 2008
Messages : 1 467
Points : 2 823
Points : 2 823
Bonjour Fabien.
Je regarde ton code d'un oeil neuf ce matin, et j'ai deux remarques :
1) tu ne définis que 2 arrays alors que j'en proposais 3 (1 pour les dates de visite, 1 pour les dates de scores et 1 pour les scores eux-mêmes : c'est celui-là qui manque ?!)
2) une approche radicalement différente serait de "pivoter" ta table, de manière à avoir une observation par patient et par visite. Avec plusieurs PROC TRANSPOSE et un MERGE, ça doit bien se faire.

PATIENT_ID DATE SCORE
1 12/02/2010 325
1 15/07/2010 .
1 02/12/2010 322
etc.

Dans mon exemple, il y a une visite le 15/7/2010 mais pas de score mesuré. Est-ce qu'on peut facilement coder ton problème dans ce cas ? Il faudrait des LAG pour comparer les dates et les scores, du RETAIN pour compléter les trous éventuellement...
Si vraiment tu es sur le point de laisser tomber l'approche avec les arrays, ce sera un moyen de te changer les idées.
Par contre, je ne pense pas que les macros fassent autre chose que compliquer les programmes dans ce cas.

Bon courage.
Olivier
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/02/2011, 10h10   #15
Invité de passage
 
Inscription : février 2011
Messages : 20
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 20
Points : 2
Points : 2
Bonjour,
Olivier, pour répondre à ta question dans ton mail d'hier, j va bien de 0 à 19 et k de 1 à 19 puisqu'en fait la premiere boucle j regarde s'il y a une date de score (il y en a 19) qui est égale à la date d'épisode i -1. La deuxième boucle k parcourt les dates de score pour voir s'il y en a une qui est égale à la date d'épisode i. Après réflexion peut-etre que j va de 0 à 18 finalement ????

Megamind2, je ne comprend pas trop ton programme. Disons que je ne suis pas très doué à tout ce qui touche des macros

Olivier, dans ton mail de ce matin, j'ai défini 2 arrays car en fait mes score sont dans l'array des date de score. C'est pour cela que j'ai codé date_score[2+5*j] ou date_score[4+5*j] pour selectionner les scores dans cette array.
Je ne vois pas comment m'en sortir si je transpose ma table. Comment faire correspondre les dates d'épisodes avec les dates de score?

Merci
Fabien
fabien21 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/02/2011, 10h16   #16
Membre Expert
 
Avatar de MEGAMIND2
 
Homme Brice Beare
Paris
Inscription : janvier 2011
Messages : 956
Détails du profil
Informations personnelles :
Nom : Homme Brice Beare
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Paris

Informations forums :
Inscription : janvier 2011
Messages : 956
Points : 1 366
Points : 1 366
un select into + array &episode que tu appelles ça une macro Olivier?
C'est exactement la même chose que tu as fait avec une autre approche...
MEGAMIND2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/02/2011, 10h28   #17
Expert Confirmé
 
Avatar de olivier.decourt
 
Homme Olivier Decourt
Formateur en informatique
Inscription : avril 2008
Messages : 1 467
Détails du profil
Informations personnelles :
Nom : Homme Olivier Decourt
Âge : 34
Localisation : France

Informations professionnelles :
Activité : Formateur en informatique
Secteur : Conseil

Informations forums :
Inscription : avril 2008
Messages : 1 467
Points : 2 823
Points : 2 823
Citation:
Envoyé par fabien21 Voir le message
j va bien de 0 à 19 et k de 1 à 19 puisqu'en fait la premiere boucle j regarde s'il y a une date de score (il y en a 19) qui est égale à la date d'épisode i -1. Après réflexion peut-etre que j va de 0 à 18 finalement ????
Si tu as 19 variables, j ne peut effectivement pas aller de 0 à 19 (ce qui fait 20 valeurs). Je pense bien que c'est là qu'est le noeud du problème.
As-tu essayé de tracer l'exécution de tes boucles avec des PUT ?
Citation:
Envoyé par fabien21 Voir le message
j'ai défini 2 arrays car en fait mes score sont dans l'array des date de score. C'est pour cela que j'ai codé date_score[2+5*j] ou date_score[4+5*j] pour selectionner les scores dans cette array.
Cette subtilité m'avait échappé, j'étais persuadé que tu avais 3 séries de variables, les dates d'épisodes, les dates de mesure de scores et les scores eux-mêmes. Remarque sans objet de ma part, donc.
Citation:
Envoyé par fabien21 Voir le message
Je ne vois pas comment m'en sortir si je transpose ma table. Comment faire correspondre les dates d'épisodes avec les dates de score?
C'était juste pour proposer une piste alternative, au cas où. Mais comme j'avais une vision erronée de tes données, elle n'est pas forcément pertinente. Et les boucles avec arrays devraient bien rendre leur service, à condition de maîtriser ces indices de boucles qui sont le coeur de ton souci.

Allez, on y croit, il fait beau aujourd'hui, ce programme fonctionnera avant le week-end !
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/02/2011, 10h45   #18
Invité de passage
 
Inscription : février 2011
Messages : 20
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 20
Points : 2
Points : 2
Quand je fais tourner le programme pour j de 0 à 2 et k de 1 à 3 ça fonctionne ( après je ne pense pas que les résultats soient ceux que j'attends ) mais lorsque je passe de j de 0 à 3 et k de 1 à 4 ça bugg ! Je ne vois pas pourquoi !!!

On y croit on y croit, moyen, je commence à desespérer .... et puis je n'ai pas de grand soleil chez moi

Merci
fabien21 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/02/2011, 10h51   #19
Expert Confirmé
 
Avatar de olivier.decourt
 
Homme Olivier Decourt
Formateur en informatique
Inscription : avril 2008
Messages : 1 467
Détails du profil
Informations personnelles :
Nom : Homme Olivier Decourt
Âge : 34
Localisation : France

Informations professionnelles :
Activité : Formateur en informatique
Secteur : Conseil

Informations forums :
Inscription : avril 2008
Messages : 1 467
Points : 2 823
Points : 2 823
Bon, alors désolé pour le soleil.
On va déjà essayé de résoudre les questions de SAS avant celles de la météo.
Citation:
date_score[1+5*k]
Avec k=4 effectivement ça ne peut que planter si tu as 19 variables dans ton array.
Peux-tu nous expliquer ton raisonnement quand tu donnes ces indices calculés (le genre 1+5k) ? Parce que je n'arrive pas à le visualiser (peut-être un cas de manque de caféine), désolé.
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/02/2011, 11h13   #20
Invité de passage
 
Inscription : février 2011
Messages : 20
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 20
Points : 2
Points : 2
Alors en fait l'array date_score est organisé comme suit:
date_clin1 edss_entered1 edss_calc1 egs_entered1 egs_calc1 et ainsi de suite jusqu'à dat_clin20 edss_entered20 edss_calc20 egs_entered20 egs_calc20 dans le même ordre.
Donc lorsque je fais
Citation:
date_score[1+5*k]
je ne prend que les date_clin pour vérifier s'il y en a une qui coincide avec date_episode.

C'est mieux expliquer?
fabien21 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 11h42.


 
 
 
 
Partenaires

Hébergement Web