Alle möglichen Variablen-Kombinationen in Proc logistic ausprobieren

Hallo Forum,

ich möchte ein logistisches Regressionsmodell fitten. Es kommen 9 unabhängige Variablen in Frage von denen 3 Stück klassiert sind, also ins class-statement müssen. Ich möchte jetzt ein Makro schreiben, dass alle möglichen Kombination (ungeordnet) durchspielt und mir gewünschte Statistiken in ein Dataset schreibt.
Nach meinen Berechnung gibt es 511 Möglichkeiten die Variablen anzuordnen. Bloß wie setze ich das am klügsten in SAS um? Mein Problem ist mehr konzeptioneller als technischer Natur. Mir fallen nur 9 ineinander geschachtelte Schleifen ein, die alle Variablen und ein Leerfeld durchlaufen. Aber das macht dann eine Milliarde Kombinationen statt 511...

Viele Grüße,

Simon

STEPWISE?

Was bedeutet "alle möglichen Kombination (ungeordnet)"? Wie kommen Sie auf 511? Geht es um alle einzelnen Variablen, alle Paare, alle Tripel etc. bis schließlich alle neun Variablen im Modell sind? Haben Sie sich schon mal mit der Option SELECTION=STEPWISE der MODEL-Anweisung von PROC LOGISTIC beschäftigt, die eine automatische Modellselektion zulässt?

Ungeordnet heißt, dass die

Ungeordnet heißt, dass die Reihenfolge keine Rolle spielt. Richtig, dann einzeln, Paare, Tripel usw.
Nimmt man für alle Anzahlen "n über k" und summiert kommt man auf 511.
Stepwise kenne ich und habe ich auch gemacht. Ich möchte aber trotzdem noch mal alle Kombination durchspielen, um zu sehen, ob irgendwo eine deutlich bessere Anpassung vorliegt.

SAS Macro

Das folgende Macro kann zumindest die Generierung der Variablenkombinationen übernehmen

/* Dieses Makro erstellt aus einer Liste mit n Elementen Listen mit allen möglichen Kombinationen dieser Elemente.
Dabei kann optional eine Mindest- und Maximaltiefe angegeben werden, bis zu der Kombinationen ermittelt werden
(z.B. alle Kombinationen mit mindestens drei und höchstens fünf Elementen). Die generierten Kombinationen werden in
einer SAS-Datei gespeichert. */

%MACRO AllComb(
     lst=
/* Elementliste */
    
,MinDepth=0 /* minimale Tiefe, für Kombinationen ermittelt werden sollen. D.h. alle Kombinationen, die mindestens
        &MinDepth Elemente enthalten. */
    
,MaxDepth= /* maximale Tiefe, bis zu der Kombinationen ermittelt werden sollen. D.h. nur Kombinationen, die nicht mehr
        als &MaxDepth Elemente enthalten. Voreingestellt ist die Anzahl der Elemente in &lst, d.h. bis zur maximalen Tiefe */
    
,out=AllCombOut /* SAS-Ausgabetabelle */
    
,sort=alpha /* alpha | binary Sortierreihenfolge der Ausgabelisten. Alphabetisch oder gemäß der Reihenfolge der
        Binärstrings */
    
,options= /* noclean, nolog */
);

%LOCAL lst MinDepth MaxDepth out sort options;

%LET sort = %upcase(&sort);
%LET options = %upcase(&options);

%LOCAL ErrCode ErrMsg;
%LET ErrCode = 0;
%LET ErrMsg =;


/* Bestimmen der Anzahl der Listenelemente */
%LOCAL NElem;
%LET NElem = %CountArgs(&lst);

/* Wenn &depth nicht angegeben ist, werden alle Kombinationen ausgegeben, die Tiefe enttspricht dann gerade der Anzahl der
    Listenelemente */
%IF NOT %length(&MaxDepth) OR &MaxDepth < 1 %THEN
    
%LET MaxDepth = &NElem;

DATA _AllComb;
LENGTH lst $
%length(&lst). elem $%length(&lst).;
/* Schleife über alle möglichen Parameterkombinationen (=2**p) */
DO i = 0 TO 2**&NElem - 1;
    b = reverse(put(i,binary&
NElem..)); /* Darstellung des Schleifenindex in Binärform. reverse(), um
        die Lesart des Binärstrings umzudrehen. 1 entspricht normal 0001, nun 1000. Sinn ist es, im Zuge der
        anschließenden Abfragen der Teilstrings zu erreichen, daß die erste Position im Binärstring dem
        ersten Listenelement entspricht und die Auflistung der Kombinationen mit diesem beginnt. */
    
lst = ""; /* Initialisierung der Ausgabeliste für jede Kombinationsmöglichkeit */
    
count = 0;
    DO e =
1 TO &NElem;
        IF substr(b,e,
1) THEN DO;/* Auswahl des e-ten Wertes der ElementListe, wenn e-tes Element des Binärstrings
            gleich 1 ist */
            
elem = scan("&lst",e);
            count +
1; /* Hochzählen der Anzahl der aktuell enthaltenen Listenelemente */
        
END;
        ELSE
            elem =
"";
        
/* Zusammensetzen der Liste */
        
lst = strip(strip(lst) || " " || elem);
    END;
    
/* Ausschreiben der Liste, wenn die Anzahl der Werte innerhalb der vorgegebenen Tiefenangaben liegt */    
    
IF count le &MaxDepth AND count ge &MinDepth THEN
        OUTPUT;
END;
RUN;

%IF &sort ne BINARY %THEN %DO;
    PROC SORT data = _AllComb;
    BY lst;
    RUN;
%END;

%LOCAL NCombs;
DATA &out;
SET _AllComb end = ende;
KEEP lst;
CombNo = _n_;
IF ende THEN
    CALL SYMPUTX(
"NCombs",_n_);
RUN;

/* Clean up  */
 
%IF NOT %index(&Options, NOCLEAN) %THEN %DO;
    PROC DATASETS library = work nolist nodetails;
    DELETE _AllComb;
    RUN;
    QUIT;
%END;

%IF NOT %index(&Options,NOLOG) OR &ErrCode ne 0 %THEN %DO;
    
%PUT;
    
%PUT --------------------------------------&sysmacroname--------------------------------------;
    
%IF &ErrCode ne 0 %THEN %DO;
        
%PUT %cmpres(&ErrMsg (&ErrCode));
    
%END;
    
%ELSE %DO;
        
%PUT %cmpres(Input-Liste "&lst" mit &NElem Elementen);
        
%PUT Sortierreihenfolge: &sort;
        
%PUT %cmpres(Mindesttiefe der Kombinationen: &MinDepth);
        
%PUT %cmpres(Maxmimaltiefe der Kombinationen: &MaxDepth);
        
%PUT %cmpres(Ausgabedatei &out mit &NCombs DS/Kombinationen erstellt.);
    
%END;
    
%PUT --------------------------------------&sysmacroname--------------------------------------;
    
%PUT;
%END;

%MEND AllComb;
Mit
%AllComb(lst=a b c d e f g h i, MinDepth=1, MaxDepth=9);
wird dann eine SAS-Datei mit den möglichen 511 Kombinationen (die mindestens ein Element enthalten) der Buchstaben (oder eben Variablennamen) a bis i erstellt. Über eine Schleife lassen sich die einzelnen Variablenkombinationen auslesen und im MODEL-Statement weiterverarbeiten. Zusätzlich ist dann lediglich noch das CLASS-Statement in Abhängigkeit von den in der jeweiligen Kombination enthaltenen Variablen zu füllen.
Damit das Macro läuft braucht's auch noch das folgende, das die Anzahl von Elementen in einem String zählt.
%MACRO CountArgs(
     ArgLst
/* List of arguments to be counted. optional */
    
,dlm /* Delimiter. optional. default = blank */
);

%LOCAL ArgLst dlm;

%LET ArgLst = %cmpres(&ArgLst);

/* Set default value of &dlm to blank */
%IF not %length(&dlm) %THEN
    
%LET dlm = %str( );

%LOCAL return; /* return value */
/* There is one more element than delimiters provided that &string is not empty */
%IF %length(&ArgLst) %THEN
    
%LET return = %eval(%sysfunc(countc(%quote(&ArgLst),&dlm)) + 1);
%ELSE
    
%LET return = 0;


/* Return number of arguments */
&return

%MEND CountArgs;

Danke :-)

Danke :-)