(gH) -_- statgh.sas ; TimeStamp (unix) : 27 Mai 2008 vers 15:06 /**************************************************************************************/ * version 1.41 ; /**************************************************************************************/ /* */ /* s'utilise par */ /* */ /* %include 'x:\statgh.sas' ; */ /* */ /* */ /* ensuite pour appler une macro mettre % devant son nom */ /* et indiquer les paramètres éventuels ; par exemple */ /* */ /* %matcor(vins) ; */ /* */ /* pour calculer la matrice de corrélation du dataset VINS */ /* */ /* ==> les fichiers de données usuels (gH) comme */ /* */ /* elf, vins, pbio, titanic, antal... */ /* */ /* sont dans x:\datagh.sas */ /* */ /* ==> des exemples d'analyse sont dans x:\anas.sas */ /* */ /**************************************************************************************/ /**************************************************************************************/ /* */ /* Liste des macros disponibles : */ /* */ /* optionsgh : pour un autre affichage des pages de résultats */ /* */ /* titregen : titre général avec nom dossier, nblig et nbcol */ /* tete,queue : lignes de début et de fin */ /* decritQT : calcule m,s,cdv pour une seule variable */ /* asgqt : calcule m,s,cdv avec divers affichages (toutes les variables) */ /* combien : donne le nombre de lignes et de colonnes */ /* print10 : affiche les 10 premières lignes de données */ /* matcor : affiche une matrice des corrélations triangulaires */ /* xls2dbf : conversion .xls vers .dbf */ /* compMoy : comparaison de moyennes de deux variables */ /* pgqlm : nb de valeurs plus grandes que la moyenne */ /* courbe_roc : tracé de courbe Roc */ /* comp2roc : tracés et comparaison de 2 courbes Roc */ /* comp3roc : tracés et comparaison de 3 courbes Roc */ /* likratDS : calcul de +LR et -LR avec intervalle de confiance DATASET */ /* likratFR : calcul de +LR et -LR avec intervalle de confiance FREQUENCES */ /* nbmots : compte les mots d'une chaine */ /* allcompRoc2a2 : comparaisons deux à deux de courbes Roc */ /* */ /**************************************************************************************/ %macro optionsgh(ls=256,pgs=50) ; /* par exemple */ /* options nodate LINESIZE=256 PAGESIZE=50 NOCENTER FORMDLIM=' ' FORMCHAR='-----------' nonumber ; */ options nodate LINESIZE=&ls PAGESIZE=&pgs NOCENTER FORMDLIM=' ' FORMCHAR='-----------' nonumber ; %mend optionsgh ; /**************************************************************************************/ /**************************************************************************************/ /**************************************************************************************/ %macro titregen(ds) ; * options mprint mlogic symbolgen ; /******************************************/ /* exemple d'utilisation : */ /* %include 'z:\demoSas\statgh.sas' ; */ /* %titregen(vins) ; */ /******************************************/ %let dset = &ds ; %let dsid = %sysfunc(open(&dset)) ; %let nblig = %sysfunc(attrn(&dsid,NOBS)) ; %let nbcol = %sysfunc(attrn(&dsid,NVARS)) ; %let rc = %sysfunc(close(&dsid)) ; %global phrase ; %global sl ; %let phrase = ETUDE DU DATASET %upcase(&dset) avec &nblig ligne(s) et &nbcol colonne(s) ; %put ; %put ; %put &phrase ; %let sl = %str() ; %do i=1 %to %length(&phrase) ; %let sl = %str(&sl=) ; %end ; %put &sl ; %put ; %put ; TITLE "%str(&phrase) " ; TITLE2 "&sl " ; run ; %mend titregen ; /**************************************************************************************/ %macro combien(ds) ; * options mprint mlogic symbolgen ; /******************************************/ /* exemple d'utilisation : */ /* %include 'z:\demoSas\combien.sas' ; */ /* %combien(vins) ; */ /******************************************/ %let dset = &ds ; %let dsid = %sysfunc(open(&dset)) ; %if &dsid=0 %then %do ; %put Le fichier de données &dset est inaccessible !? ; data infos ; file "infos.txt" ; label phrase='00'x ; length phrase $ 70 ; format phrase $70. ; phrase = "Aucun nom de dossier fourni correspondant à &dset (malheureusement)" ; put phrase ; output ; run ; %end ; %else %do ; %let nblig = %sysfunc(attrn(&dsid,NOBS)) ; %let nbcol = %sysfunc(attrn(&dsid,NVARS)) ; %let rc = %sysfunc(close(&dsid)) ; %global phrase ; %let phrase = "Dans le fichier %str(%upcase(&dset)) il y a &nblig ligne(s) et &nbcol colonne(s)." ; %put &phrase ; * TITLE DOSSIER %upcase(&dset) : &nblig ligne(s) et &nbcol colonne(s) ; data infos ; file "infos.txt" ; label phrase='00'x ; length phrase $ 70 ; format phrase $70. ; phrase = &phrase ; put phrase ; output ; run ; %end ; /* fin de si le fichier de donnees existe */ title ; proc print data=infos noobs label ; run ; %mend combien ; /**************************************************************************************/ %macro tete(ds,nfirst) ; %if &nfirst= %then %do ; %let nfirst=10 ; %end ; %put Les &nfirst premières lignes ; %put proc print data=&ds (firstobs=1 obs=&nfirst) ; title &ds ; title2 "(les &nfirst premières lignes)" ; proc print data=&ds (firstobs=1 obs=&nfirst) ; run ; %mend tete ; /**************************************************************************************/ %macro queue(ds,nlast) ; %let dset = &ds ; %let dsid = %sysfunc(open(&dset)) ; %let nblig = %sysfunc(attrn(&dsid,NOBS)) ; %if &nlast= %then %do ; %let nlast=9 ; %end ; %let deblig = %eval(1+&nblig-&nlast) ; %let flast = %eval(1+&nlast) ; %put Les &flast dernières lignes ; %put proc print data=&ds (firstobs=&deblig obs=&nblig) ; title &ds ; title2 "(les &nlast dernières lignes)" ; proc print data=&ds (firstobs=&deblig obs=&nblig) ; run ; %mend queue ; /**************************************************************************************/ %macro decritQT(ds,ti,qt,un) ; /******************************************/ /* exemple d'utilisation : */ /* %decritQT(vins,"Exportations du Royaume-Uni",UK,"hl") ; */ /******************************************/ %global tit ; %let tit = &ti ; %global vqt ; %let vqt = &qt ; %global uni ; %let uni = &un ; proc means data=&ds noprint vardef=n maxdec=1 ; var &qt ; output out=decritQT USS=uss N=nbv MEAN=Moyenne STD=ect CV=cdv MIN=Minimum Q1=q1 MEDIAN=med Q3=q3 MAX=Maximum NMISS=nmi ; proc transpose data=decritQT out=QTdecrit; * proc print data=QTdecrit ; data decritQT ; set QTdecrit ; ATTRIB MRG LABEL='00'x ; ATTRIB phrase length=$ 70 LABEL='00'x ; ATTRIB debp length=$ 30 ; ATTRIB finp length=$ 40 ; ATTRIB vn length=$ 12 ; MRG = " " ; UNITE = " " || %str( &uni ) ; vn = PUT(COL1,10.2) ; finp = vn || UNITE ; if _n_=1 then do ; debp = "Variable " ; finp = %str(" %upcase(&vqt) ") ; end ; if _n_=2 then do ; debp = "Description " ; finp = " " || %str( &tit ) ; end ; if _n_=3 then do ; debp = "" ; finp = "" ; end ; if _n_=4 then do ; debp = "Nombre de valeurs : " ; vn = PUT(COL1,7.0) ; finp = vn ; end ; if _n_=5 then do ; debp = "Moyenne " ; end ; if _n_=6 then do ; debp = "Ecart-type " ; end ; if _n_=7 then do ; UNITE = " % " ; debp = "Coefficient de variation " ; vn = PUT(COL1,9.1) ; finp = vn || " % " ; end ; if _n_=8 then do ; vn = PUT(COL1,10.1) ; debp = _NAME_ ; end ; if _n_=9 then do ; debp = "Premier quartile " ; end ; if _n_=10 then do ; debp = "Médiane " ; end ; if _n_=11 then do ; debp = "Troisième quartile " ; end ; if _n_=12 then do ; debp = _NAME_ ; end ; if _n_=13 then do ; debp = "" ; finp = "" ; end ; phrase = " " || substr(debp||" ",1,30) || finp ; keep MRG phrase ; proc print data=decritQT noobs label ; run ; %mend decritQT ; /**************************************************************************************/ %macro print10(ds,tit) ; %let titd = "(les 10 premières lignes de données du dataset &ds )" ; proc print data=&ds (firstobs=1 obs=10) ; *title &tit ; *title2 &titd ; run ; /* obligatoire pour valider les titres */ %mend print10 ; /**************************************************************************************/ /**************************************************************************************/ %macro asgqt(ds) ; ** 1. Transfert des données et affichage du début des données ; data asg_tmp ; set &ds ; title2 Début des données ; proc print data=asg_tmp (firstobs=1 obs=10) ; ** 2. Calculs moyenne, écart-type etc. ; proc means data=asg_tmp noprint ; output out=tmp_gsa ; ** 3. Transposition du fichier des résultats ; proc transpose data=tmp_gsa out=tmp_asg ; ** 4. Suppression des lignes "parasites" ** et calcul du cdv ; data asg_tmp ; set tmp_asg ; if col1=0 then delete ; if _name_='_FREQ_' then delete ; min = col2 ; max = col3 ; moy = col4 ; ect = col5 ; if moy > 0 then cdv = 100*abs(ect)/abs(moy) ; else cdv = -1 ; run ; ** 5. Tri et affichage par cdv décroissant ; title2 Tri et affichage par cdv décroissant ; proc sort data=asg_tmp ; by descending cdv ; proc print data=asg_tmp ; var _name_ moy ect cdv min max ; run ; /* obligatoire pour que titre2 soit exécuté */ ** 6. Tri et affichage par moyenne décroissante ; title2 Tri et affichage par moyenne décroissante ; proc sort data=asg_tmp ; by descending moy ; proc print data=asg_tmp ; var _name_ moy ect cdv min max ; run ; ** 7. Affichage par ordre historique ; title2 Affichage par ordre historique ; proc print data=asg_tmp ; var _name_ moy ect cdv min max ; run ; ** 8. Matrice des corrélations %matcor(&ds) ; ** Exécution finale ; run ; %mend asgqt ; /**************************************************************************************/ %macro matcor(ds) ; %let donnees = &ds ; %let dsid = %sysfunc(open(&donnees)) ; %if &dsid=0 %then %do ; %put Le fichier de donn‚es &donnees est inaccessible !? ; %end ; %else %do ; %let nbcol = %sysfunc(attrn(&dsid,NVARS)) ; proc corr data=&ds noprint out=scorr ; data mcor ; set scorr ; where _type_ = 'CORR' ; rename _name_ = nom ; drop _type_ ; data mcortr ; set mcor ; array cor(*) _numeric_ ; attrib rho length = $200 ; attrib v length = $200 ; do i = 1 to _n_ ; if i = 1 then do ; w = int(cor(1)*100+0.5)/100 ; v = put(w,6.3) ; end ; else do ; w = int(cor(i)*100+0.5)/100 ; t = put(w,6.3) ; v = trim(v) || ' ' || t ; end ; end ; rho = v ; keep nom rho ; data lnom ; set scorr ; where _type_ = 'CORR' ; rename _name_ = ndl ; drop _type_ ; data lnoml ; set lnom ; attrib noml length = $015 ; attrib ldv length = $200 ; noml = trim(ndl) || '________' ; noml = substr(noml,1,6) ; if _n_ = 1 then ldv = noml ; else ldv = trim(ldv) || ' ' || noml ; ndl = ' ' ; retain ldv ; keep ndl ldv ; data premlig ; set lnoml ; rename ndl = nom ; rename ldv = rho ; if _n_ = &nbcol - 1 ; data matcor ; set premlig mcortr ; data _null_ ; set matcor ; file 'matcor.sor' ; rhot = ' : ' || rho ; put nom @10 rhot $ ; proc print data=matcor noobs ; run ; %put Vous pouvez consulter le fichier 'matcor.sor' ; %end ; /* fin de si le fichier de donnees existe */ run ; %mend matcor ; /**************************************************************************************/ /* */ /* Conversion Excel --> Dbase */ /* */ /**************************************************************************************/ /* */ /* exemple d'utilisation : */ /* %xls2dbf(bof) ; */ /* pour convertir bof.xls en bof.dbf */ %macro xls2dbf(basename) ; %let nomxls = %str(&basename)str(.)xls ; %let nomxls = &basename%str(.)xls ; %let nomdbf = &basename%str(.)dbf ; %let nomdbf = &basename%str(.)dbf ; title Conversion de &nomxls en &nomdbf ; * lecture du fichier Excel et affichage des 10 premières lignes ; proc import datafile="&nomxls" out=basesasin dbms=excel replace ; proc print data=basesasin (firstobs=1 obs=10) ; * conversion en Dbase ; filename basedbf "&nomdbf" ; proc export data=basesasin outfile="&nomdbf" dbms=dbf replace ; * relecture du fichier Dbase et affichage des 10 premières lignes ; proc import datafile="&nomdbf" out=basesasout dbms=dbf replace; proc print data=basesasout (firstobs=1 obs=10) ; %mend xls2dbf ; /**************************************************************************************/ /**************************************************************************************/ /* */ /* Comparaison de moyennes pour deux variables dans deux datasets différents */ /* */ /**************************************************************************************/ /* */ /* exemple d'utilisation : */ /* %compMoy("AGE : elf vs. ronfle",elf,age,ronfle,age) ; */ /* pour comparer age de elf et alge de ronfle */ %macro compMoy(titre,ds1,var1,ds2,var2) ; data d1 ; set &ds1 ; vqt = &var1 ; grp = 1 ; keep vqt grp ; data d2 ; set &ds2 ; vqt = &var2 ; grp = 2 ; keep vqt grp ; data all ; set d1 d2 ; proc ttest data=all ; var vqt ; class grp ; %mend compMoy ; /*************************************************************************************/ %macro comp2roc(ds,clas,var1,var2) ; /* attention : il faut disposer dans un même dataset de la classe en 0/1, */ /* et des scores (en principe en 0 et 1) */ /* exemple : on compare pre_17 et fm_v3 pour fcs via dans ghdata */ /* %comp2roc(ghata,fcs,pre_17,fm_v3) */ data comp2roc ; set &ds ; /***************************************** ROC 1 *******************/ title Variable &var1 ; proc logistic data=comp2roc; model &clas(event='1') = &var1 / outroc=outvar1 roceps=0; output out=out1 p=p1; ods output association=assoc1; run; data _null_; set assoc1; if label2='c' then call symput("area",cvalue2); if label2='c' then call symput("area1",cvalue2); run; title2 "Approximate area under curve = &area"; %rocplot(out=out1, outroc=outvar1, p=p1, id=SCORE,color=white,size=0,plotchar=.) title2; data joint; set _rocplot; length Index $ 13; Index='SCORE'; run; /***************************************** ROC 2 *******************/ title Variable &var2 ; proc logistic data=comp2roc ; model &clas(event='1') = &var2 / outroc=outvar2 roceps=0; output out=out2 p=p2; ods output association=assoc2; run; data _null_; set assoc2; if label2='c' then call symput("area2",cvalue2); run; title2 "Approximate area under curve = &area"; %rocplot(out=out2, outroc=outvar2, p=p2, id=SCORE,color=white,size=0,plotchar=.) title2; data joint2 ; set _rocplot; length index $ 13; Index='SCORE'; data joint ; set joint joint2 ; run; /***************************************** COMPARAISON *******************/ %roc(data=&ds,var=&var1 &var2, response=&clas, details=YES) ; symbol1 i=join v=. c=green h=0.1 ; symbol2 i=join v=. c=red h=0.1; symbol3 i=join v=. c=blue h=0.1; proc gplot data=joint; title "Comparaison des SCORES &var1 et &var2 "; title2 "Test of H0: equal areas under curves -- p=&pvalue"; run ; footnote "From DeLong, et. al. (1988, Biometrics 44)"; label index="Index"; plot _sensit_ * _1mspec_ = Index / vaxis=0 to 1 by .1 haxis=0 to 1 by .1 cframe=ligr; run; quit; title; title2; footnote; %put ; %put Au final ; %put aire 1 = &area1 ; %put aire 2 = &area2 ; %put p diff = &pvalue ; %put ; %mend comp2roc ; /*************************************************************************************/ %macro comp3roc(ds,clas,var1,var2,var3) ; /* attention : il faut disposer dans un même dataset de la classe en 0/1, */ /* et des scores (en principe en 0 et 1) */ /* exemple : on compare pre_17, fm_v3 et fm_v4 pour fcs via dans ghdata */ /* %comp3roc(ghata,fcs,pre_17,fm_v3,fm_v4) */ data comp3roc ; set &ds ; /***************************************** ROC 1 *******************/ title Variable &var1 ; proc logistic data=comp3roc; model &clas(event='1') = &var1 / outroc=outvar1 roceps=0; output out=out1 p=p1; ods output association=assoc1; run; data _null_; set assoc1; if label2='c' then call symput("area",cvalue2); if label2='c' then call symput("area1",cvalue2); run; title2 "Approximate area under curve = &area"; %rocplot(out=out1, outroc=outvar1, p=p1, id=SCORE,color=white,size=0,plotchar=.) title2; data joint; set _rocplot; length Index $ 13; Index='SCORE'; run; /***************************************** ROC 2 *******************/ title Variable &var2 ; proc logistic data=comp3roc ; model &clas(event='1') = &var2 / outroc=outvar2 roceps=0; output out=out2 p=p2; ods output association=assoc2; run; data _null_; set assoc2; if label2='c' then call symput("area",cvalue2); if label2='c' then call symput("area2",cvalue2); run; title2 "Approximate area under curve = &area"; %rocplot(out=out2, outroc=outvar2, p=p2, id=SCORE,color=white,size=0,plotchar=.) title2; data joint2 ; set _rocplot; length index $ 13; Index='SCORE'; data joint ; set joint joint2 ; run; /***************************************** ROC 3 *******************/ title Variable &var3 ; proc logistic data=comp3roc ; model &clas(event='1') = &var3 / outroc=outvar2 roceps=0; output out=out3 p=p3; ods output association=assoc3; run; data _null_; set assoc3; if label2='c' then call symput("area",cvalue2); if label2='c' then call symput("area3",cvalue2); run; title2 "Approximate area under curve = &area"; %rocplot(out=out2, outroc=outvar3, p=p3, id=SCORE,color=white,size=0,plotchar=.) title2; data joint3 ; set _rocplot; length index $ 13; Index='SCORE'; data joint ; set joint joint2 joint3 ; run; /***************************************** COMPARAISON *******************/ %roc(data=&ds,var=&var1 &var2 &var3, response=&clas, details=YES) ; symbol1 i=join v=. c=green h=0.1 ; symbol2 i=join v=. c=red h=0.1; symbol3 i=join v=. c=blue h=0.1; proc gplot data=joint; title "Comparaison des SCORES &var1 et &var2 "; title2 "Test of H0: equal areas under curves -- p=&pvalue"; run ; footnote "From DeLong, et. al. (1988, Biometrics 44)"; label index="Index"; plot _sensit_ * _1mspec_ = Index / vaxis=0 to 1 by .1 haxis=0 to 1 by .1 cframe=ligr; run; quit; title; title2; footnote; %put ; %put Au final ; %put aire 1 = &area1 ; %put aire 2 = &area2 ; %put aire 3 = &area3 ; %put p diff = &pvalue ; %put ; %mend comp3roc ; /***********************************************************/ /* PGQLM : Plus Grand Que La Moyenne */ /* ou comment utiliser des variables */ /* en dehors des macros */ %macro pgqlm(ds,var) ; /* exemple d'utilisation : %pgqlm(vins,RFA) */ /* calcul de la moyenne avec stockage du résultat */ /* dans le dataset pgqlm */ proc means data=&ds noprint ; output out=pgqlm mean= ; var &var ; /* mise en mémoire de la valeur de la moyenne */ data evdlm ; set pgqlm ; if _n_ = 1 then call symput("vdlm",&var); /* comptage des valeurs plus grandes que la moyenne */ data cpgqlm ; if _n_ = 1 then cpgqlm = 0 ; vdlm = &vdlm ; set &ds ; retain cpgqlm ; if &var>vdlm then cpgqlm = cpgqlm + 1 ; /* affichons le résultat ! */ proc print data=cpgqlm ; %mend pgqlm ; /***********************************************************/ %macro courbe_roc(ds,ql,rlb_vars) ; proc logistic data=&ds; model &ql (event='1')= &rlb_vars / outroc=or roceps=0; output out =qlpred pred =pql ; ods output association=assoc; data _null_; set assoc; if label2='c' then call symput("area",cvalue2); run ; /* obligatoire */ title2 "Approximate area under curve = &area"; %rocplot(out=qlpred,outroc=or, p=pql, id=&ql) %mend courbe_roc ; /***************************************************************/ /* calcul de -LR et +LR à partir des données ou du tri croisé */ /***************************************************************/ %macro likratDS(ds,Vtest,Vresp) ; proc freq data=&ds ; tables &Vtest*&Vresp / out =prepFreq ; %likratFR(prepFreq,&Vtest,&Vresp) ; %mend likratDS ; /***********************************************************/ %macro likratFR(dsFREQ,Vtest,Vresp) ; data freqs ; set &dsFREQ (rename=(&Vtest=Test &Vresp=Response)) ; proc sort data=freqs out=freqst ; by descending Test descending Response ; run ; proc freq data=freqst order=data ; weight Count ; tables Test*Response ; run ; title 'Sensitivity' ; proc freq data=freqst order=data ; where Response=1 ; weight Count ; tables Test ; exact binomial ; run ; title 'Specificity' ; proc freq data=freqst ; where Response=0 ; weight Count ; tables Test ; exact binomial ; run ; title 'Positive predictive value' ; proc freq data=freqst order=data ; where Test=1 ; weight Count ; tables Response ; exact binomial ; run ; title 'Negative predictive value' ; proc freq data=freqst ; where Test=0 ; weight Count ; tables Response ; exact binomial ; run ; title 'False Positive Probability (Col)' ; proc freq data=freqst order=data ; where Response=0 ; weight Count ; tables Test ; exact binomial ; run ; title 'False Positive Probability (Row)' ; proc freq data=freqst ; where Test=1 ; weight Count ; tables Response ; exact binomial ; run ; title 'False Negative Probability (Col)' ; proc freq data=freqst ; where Response=1 ; weight Count ; tables Test ; exact binomial ; run ; title 'False Negative Probability (Row)' ; proc freq data=freqst order=data ; where Test=0 ; weight Count ; tables Response ; exact binomial ; run ; title 'Data for LR' ; data prepLR2 ; set freqst ; if test=1 and response=1 then do ; testpos1 = count ; total1 = count ; end ; if test=0 and response=1 then do ; total1 = total1 + count ; end ; if test=1 and response=0 then do ; total2 = count ; end ; if test=0 and response=0 then do ; testpos2 = count ; total2 = total2 + count ; end ; retain testpos1 total1 testpos2 total2 ; data prepLR3 ; length stat $ 8 ; set prepLR2 ; stat = '???' ; testpos = 0 ; total = 0 ; if _n_ = 3 then do ; stat = 'sens' ; testpos = testpos1 ; total = total1 ; end ; if _n_ = 4 then do ; stat = 'spec' ; testpos = testpos2 ; total = total2 ; end ; keep stat testpos total ; if stat='???' then delete ; proc print data=prepLR3 ; data LR ; set prepLR3 ; lntotal=log(total) ; output ; if stat='sens' then do ; stat='senscomp' ; testpos=total-testpos ; output ; end ; if stat='spec' then do ; stat='speccomp' ; testpos=total-testpos ; output ; end ; proc genmod data=LR ; where stat in ('sens','speccomp') ; class stat ; model testpos/total=stat / d=b link=log ; estimate 'log LR+' stat 1 -1 / exp ; run ; proc genmod data=LR ; where stat in ('senscomp','spec') ; class stat ; model testpos/total=stat / d=b link=log ; estimate 'log LR-' stat 1 -1 / exp ; run ; %mend likratFR ; /***********************************************************/ %macro nbmots(list) ; /* 27 mai 2008 */ %local nbwords ; %let nbwords = 0 ; %do %while(%qscan(&list,&nbwords+1,' ') ne %str()) ; %let nbwords = %eval(&nbwords+1) ; %end ; &nbwords /* surtout pas de point-virgule */ %mend nbmots ; /***********************************************************/ %macro allcompRoc2a2(ds,lstvarQT,ql) ; %let nbm = %nbmots(&lstvarQT) ; %put donc nbm = &nbm car &lstvarQT ; %do idv=1 %to &nbm ; %let var1 = %scan(&lstvarQT,&idv,' ') ; %let deb = %eval(&idv+1) ; %do jdv=&deb %to &nbm ; %let var2 = %scan(&lstvarQT,&jdv,' ') ; %put V1 = &var1 et V2 = &var2 ; title Delong sur les 2 tests : &var1 et &var2 dans cohortes1et2 ; %roc(data=&ds,var=&var1 &var2,response=&ql, details=YES) ; run ; %end ; %end ; %mend allcompRoc2a2 ; /***********************************************************/