Précédent   Forum des professionnels en informatique > Logiciels > Solutions d'entreprise > Business Intelligence > SAS > Macro
Macro Forum d'entraide sur le langage Macro de SAS
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 19/09/2011, 14h30   #1
Futur Membre du Club
 
julien quetel
Inscription : juillet 2010
Messages : 91
Détails du profil
Informations personnelles :
Nom : julien quetel

Informations forums :
Inscription : juillet 2010
Messages : 91
Points : 16
Points : 16
Par défaut Comparaison entre lignes

le probleme me semble assez simple pourtant je bloque dessus depuis ce matin...
j'ai une base en ligne a chaque fois qu'un patient passe dans mon hopital ca créé une ligne.
Voila je veux savoir sur 1 année glissante, les patients qui ont perdu plus de 3 points à un test.
Le probleme etant que je peux avoir plusieurs valeurs sur une année...
Afin de simplifier les choses je me suis dit il me suffit de tester toutes les combinaisons (oui je sais pas tres propre)
Mais meme la dessus je bloque, voila le code que j'ai fait, le probleme etant qu'a premiere vu il ecrase le resultat precedent a chaque fois au lieu de me rajouter une ligne...


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
50
51
52
53
54
55
 
%macro tours;
DATA _null_;
SET work.temp;
/*permet de creer une liste contenant centre avec un numero avec un nom de centre associé*/
call symputx('var_patientid'||LEFT(trim(_n_)),patientid);
run;
 
proc sql noprint;
SELECT count(DISTINCT patientid) INTO: nb_patient
FROM work.temp;
quit;
 
%do i=1 %TO &nb_patient;
DATA work.patient;
SET work.temp;
IF patientid = "&&var_patientid&i.." then output;
run;
 
DATA _null_;
SET work.patient;
/*permet de creer une liste contenant centre avec un numero avec un nom de centre associé*/
call symputx('nb_actes',_n_);
call symputx('var_mmse'||LEFT(trim(_n_)),mmse);
call symputx('var_date'||LEFT(trim(_n_)),dcldateacte);
run;
proc sort DATA=work.patient;
BY dcldateacte;
run;
 
 
%do j=1 %TO &nb_actes;
		%do k=2 %TO &nb_actes;
 
 
%let difference=%sysfunc(round(%sysevalf(&&var_mmse&k..-&&var_mmse&j..),0.01));
%let duree=%sysfunc(round(%sysevalf(&&var_date&j..-&&var_date&k..),0.01));
%put &difference.;
%put &duree.;
 
 
%IF (&difference.>=3) AND (&duree.<=365) %then %do;
DATA work.resultat;
SET work.patient;
BY patientid;
IF first.patientid then output;
run;
%end;
%end;
%end;
%end;
%mend;
 
 
%tours;
traersa est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/09/2011, 15h37   #2
Membre Expert
 
Avatar de MEGAMIND2
 
Homme Brice Beare
Paris
Inscription : janvier 2011
Messages : 957
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 : 957
Points : 1 368
Points : 1 368
Bonjour,
Si tu veux qu'on te vienne en aide, le mieux serait de dire ce que tu souhaitse obtenir, en occurrence sur une table.
MEGAMIND2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/09/2011, 15h43   #3
Futur Membre du Club
 
julien quetel
Inscription : juillet 2010
Messages : 91
Détails du profil
Informations personnelles :
Nom : julien quetel

Informations forums :
Inscription : juillet 2010
Messages : 91
Points : 16
Points : 16
oui désolé.
Je veux une liste de mes identifiants patients, pour qui la duree entre deux visite est inferieure a 365 jours, et pour qui la valeure au test a diminué de trois ou plus.
La je suis entrain d'essayer en passant par sql avec une proc insert a la place de mon output. Mais ca ne marche pas plus, je comprends pas trop pourquoi...

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
50
51
52
53
 
%macro tours;
DATA _null_;
SET work.temp;
/*permet de creer une liste contenant centre avec un numero avec un nom de centre associé*/
call symputx('var_patientid'||LEFT(trim(_n_)),patientid);
run;
 
proc sql noprint;
SELECT count(DISTINCT patientid) INTO: nb_patient
FROM work.temp;
quit;
 
%do i=1 %TO &nb_patient;
DATA work.patient;
SET work.temp;
IF patientid = "&&var_patientid&i.." then output;
run;
 
DATA _null_;
SET work.patient;
/*permet de creer une liste contenant centre avec un numero avec un nom de centre associé*/
call symputx('nb_actes',_n_);
call symputx('var_mmse'||LEFT(trim(_n_)),mmse);
call symputx('var_date'||LEFT(trim(_n_)),dcldateacte);
run;
proc sort DATA=work.patient;
BY dcldateacte;
run;
 
 
%do j=1 %TO &nb_actes;
		%do k=2 %TO &nb_actes;
 
 
%let difference=%sysfunc(round(%sysevalf(&&var_mmse&k..-&&var_mmse&j..),0.01));
%let duree=%sysfunc(round(%sysevalf(&&var_date&j..-&&var_date&k..),0.01));
%put &difference.;
%put &duree.;
 
 
%IF (&difference.>=3) AND (&duree.<=365) %then %do;
 
proc sql;
   INSERT INTO work.temp1
   VALUES (&&var_patientid&i..);
quit; 
 
%end;
%end;
%end;
%end;
%mend;
traersa est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/09/2011, 21h13   #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 828
Points : 2 828
Bonjour Julien.
Le but premier du macro langage c'est de paramétrer, pas de remplacer toutes les boucles !
Dans ce que je comprends de ton problème, il n'y a pas forcément besoin de macros. Surtout de comparer les lignes de différents patients. Pour faire ça, il y a l'étape DATA, avec les blocs BY et les variables protégées par RETAIN. Il y a aussi la solution de faire des proc TRANSPOSE (une pour les dates d'hospitalisation et une pour les scores, puis une jointure ; c'est plus simple à coder comme ça) puis de boucler sur tes variables avec un array et une boucle de l'étape DATA.
Bref, tout ça pour dire que les macros ne m'ont pas l'air de s'imposer dans ton cas.

Bon courage, et si tu nous proposes un jeu d'essai, je pense qu'on pourra te donner des pistes plus concrètes.
Olivier
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/09/2011, 08h33   #5
Futur Membre du Club
 
julien quetel
Inscription : juillet 2010
Messages : 91
Détails du profil
Informations personnelles :
Nom : julien quetel

Informations forums :
Inscription : juillet 2010
Messages : 91
Points : 16
Points : 16
bon tout d'abord merci a vous deux pour vos pistes, j'avoue que je ne connais pas du tout les array je vais donc m'orienter vers ca dans mes recherches.

Voici un exemple de données
patientid_________MMSE________dcldateacte
patient1___________25___________11Nov2008
patient1___________24___________17juin2009
patient1___________21___________18jan2010
patient2..........

dans ce cas je veux avoir dans une table le patient1, parce que entre sa visite 1 et 2 la difference de score n'est pas bonne, entre 1 et 3 l'ecart est trop important, mais entre 2 et 3 tout est bon.
traersa est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/09/2011, 12h35   #6
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 212
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : statisticien
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : mai 2011
Messages : 212
Points : 319
Points : 319
Bonjour,


je pense qu'il faudrait que tu précise encore un peu ce que tu veux vraiment faire...

Citation:
sur 1 année glissante
Quel est ta date de référence permettant de calculer l'année glissante ?

Tu as plusieurs choix possible, dont par exemple
  • Est-ce un jour courant qui est le même pour tous les patient ?
    Par exemple on est le 20 septembre 2011 donc tu voudrais tous les patients qui au cours de la période 20/09/2010 au 20/09/2011 on eu une chute constatée d'au moins 3 entre deux visites comprises dans cette dite période (visites consécutives ? ou non consécutives ?).

  • Est-ce un an glissant jusqu'au jour de la dernière visite du patient ?
    Par exemple la dernière visite du patient est le 30/05/2011 donc tu cherche une baisse de "3 ET plus" entre le 30/05/2010 et le 30/05/2011.

  • Est-ce une chute d'au moins 3 au cours d'un an glissant.
    Par exemple 23 a une visite de 30/06/2006
    Puis 19 le 30/09/2006
    et enfin 17 le 30/09/2010
    Donc avec une sélection sur les visites 1 et 2 mais datant de 2006.

  • Est-ce encore entre deux visites successives séparées de moins d'un an ?

Pourrais tu nous préciser plus exactement ta sélection ?


Citation:
qui ont perdu plus de 3 points à un test.
Citation:

Je suppose que tu voulais dire perdu "AU MOINS 3 PTS" ou "3PTS ET PLUS"
car "PLUS DE 3 PTS" ça ne correspond pas à un test avec > ou égal mais avec un > strict




Enfin sur le fond du programme selon ce que tu veux faire, je pense qu'un RETAIN devrait pouvoir faire les choses simplement une fois bien définie le concept "d'année glissante" enfin plutôt sa date de référence comme je te l'ai demandé au dessus.
jerome_pdv2 est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 20/09/2011, 14h26   #7
Futur Membre du Club
 
julien quetel
Inscription : juillet 2010
Messages : 91
Détails du profil
Informations personnelles :
Nom : julien quetel

Informations forums :
Inscription : juillet 2010
Messages : 91
Points : 16
Points : 16
je n'ai pas de periode definie, j'ai une base qui concerne plusieurs année, et je veux connaitre tous les patients qui ont perdu au moins 3 points sur moins d'un an, quelque soit l'année. le probleme etant que si j'ai 3 consultation dans mes 1 an, je dois toutes les comparer pour etre sure.
En fait je cherche tous les patients qui ont eu une perte rapide a leur score.
traersa est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/09/2011, 14h50   #8
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 212
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : statisticien
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : mai 2011
Messages : 212
Points : 319
Points : 319
Ok,

Un truc qui va marcher sans être optimal c'est de réaliser un produit cartésien de la table par elle-même...

avec un truc du genre....

Je n'ai pas essayé si ça marchait mais ça devrait s'écrire plus ou moins comme ceci...

Code :
1
2
3
4
5
6
7
8
9
 
PROC SQL;
CREATE TABLE CARTESIEN
AS SELECT TAB1.PatientId,TAB1.mmse AS mmse1,TAB1.dcldateacte AS DDA1,
TAB2.mmse AS mmse2,TAB2.dcldateacte AS DDA2
FROM TablePatient AS TAB1,TablePatient AS TAB2
WHERE 
(TAB1.PatientId=TAB2.PatientId AND TAB1.MMSE-TAB2.MMSE>=3
AND -365<=TAB1.dcldateacte-TAB2.dcldateacte<0);quit;
Edit : Correction d'une coquille...
jerome_pdv2 est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 20/09/2011, 15h44   #9
Futur Membre du Club
 
julien quetel
Inscription : juillet 2010
Messages : 91
Détails du profil
Informations personnelles :
Nom : julien quetel

Informations forums :
Inscription : juillet 2010
Messages : 91
Points : 16
Points : 16
merci beaucoup pour ton aide c'est vraiment super en plus avec une vitesse d'execution incroyable.
traersa 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 03h17.


 
 
 
 
Partenaires

Hébergement Web