Wie bilde ich alle Permutationen eines Vektors?

Hallo SAS-Forum,

gegeben ist ein Vektor mit zwanzig Elementen, wobei 10 Elemente die Zahl Eins und die übriggebliebenen als Null definiert werden, also (1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0). Nun gibt es im Sinne der Kombinatorik 20 über 10 Möglichkeiten diese Zahlen anzuordnen, also 184756. Meine Frage lautet, gibt es in SAS eine Prozedur die mir alle 184756 Anordnungen in Form einer Matrix bzw. Vektor für Vektor ausgibt? Ich will nicht, wie es die comb-Funktion in SAS ausführt, das nummerische Ergebnis haben, sondern alle Kombinationsmöglichkeiten in Form einer Matrix oder in seperaten Vektoren, z.B. (1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0) oder (1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0) usw.
Das Problem ist, dass ich bald meine Diplomarbeit abgeben muss und mir nur noch diese letzte Matrix für einen bestimmten Algorithmus fehlt.

Vielen Dank
Daniel

Alle Permutationen

Hallo Daniel,

als Datastep würde ich das folgendermaßen machen, mit MAkro spart man sich auch Schreibarbeit und macht das ganze noch flexibel.

So sollte es funktionieren, mit dem Makroaufruf kommen 184.756 Obs. heraus, zwar nicht als Matrix, sondern als Zeilen eines Datasets.
Vielleicht gibt es ja die Möglichkeit, diese mit IML in eine MAtrix einzulesen, damit kenn ich mich allerdings nicht aus.


%macro vektor(dim=,sum=);
data vektor(keep=a1-a&
dim.);

array _vektor(
1:&dim.) a1-a&dim.;

%do i = 1 %to &dim.;
  do x&
i.= 0 to 1;
    a&
i.=x&i.;
%end;
    if sum(of a1-a&
dim.)=&sum. then output;
%do i = 1 %to &dim.;
  end;
%end;

run;
%mend vektor;
%vektor(dim=
20,sum=10);

Gruß
Wolfgang

Too many variables defined...32767

Hallo Wolfgang,

wow, ich bin beeindruckt. Hab dein Vorschlag mal in SAS laufen lassen und auf den ersten Blick sieht es tatsächlich so aus, als ob alle Permutation berechnet wurden. Anschließend wollte ich diesen Datensatz transponieren und danach mittels IML als Matrix einlesen. Leider gibt SAS es eine mir bis dato unbekannte Fehlermeldung aus.

proc transpose data = trans out = trans_neu;
88   run;

ERROR:
Too many variables defined for file WORK.TRANS_NEU.  This file may not have more than
       
32767 variables.
NOTE: The SAS System stopped processing this step because of errors.
WARNING: The data set WORK.TRANS_NEU was only partially opened and will not be saved.

Das heißt doch, dass SAS nur 32767 Variablen darstellen kann, oder? Dabei dachte ich immer SAS sei eine mächtige Software, aber 32767 find ich ein bisschen wenig. Naja, wollen wir nicht mecker.

Dankeschön
Daniel

sieht nach 16 Bit aus. (-32768 bis +32767)

Hallo Daniel,

mal eine vielleicht blöde Frage, warum wolltest Du das transponieren?
Ich habe inzwischen mal nachgeschaut, mit

PROC IML;
USE vektor VAR _all_;
READ all INTO Mvektor;
/* ... weitere Operationen
*/
QUIT;

müsstest du das Dataset Vektor in die Matrix Mvektor innerhalb eines PROC IML einlesen können, oder ist es doch nicht so einfach, wie es in der OnlineDoc aussieht?

Gruß
Wolfgang

... funktioniert

Hallo,

SAS kann innerhalb von Datasets in der Tat nur mit maximal 32767 Variablen arbeiten. Mit IML kann man es aber so machen, wie von W. Hornung vorgeschlagen: Dataset mit > 32767 Observations einlesen, und dann transponieren.

data work.test;
   
do i=1 to 50000;
      
output;
   
end;
run;

proc iml;
   
use work.test;
   
read all var {i} into i;
   nr = nrow(i);
   
print nr;
   i_trans = t(i);
   nc = ncol(i_trans);
   
print nc;
quit;

Damit hast du deine Eingabedaten transformiert und kannst innerhalb von IML deine Berechnungen ausführen (wobei die Frage natürlich bestehen bleibt, ob die Transformierung tatsächlich notwendig ist oder die Berechnung auch mit einem Spaltenvektor statt eines Zeilenvektors ausgeführt werden kann...)

Schönen Gruß
- MH -