Partielles Sortieren in DataSets

Hallo,

für folgendes Problem ist mir noch keine "Standardlösung" bekannt:
Ein Dataset soll blockweise sortiert werden.
Zu einem Block gehören Werte von je &anz. float-Variablen var1--var&anz. innerhalb einer Beobachtung.

Folgendes DataSet soll das verdeutlichen:

%MACRO erzeugen;
DATA beispiel;
    DO rep =
1 TO 5;
        
%LET liste = A B C D;
        
%DO i = 1 %TO 4;
            
%LET var = %SCAN(&liste, &i);
            
%DO j=1 %TO 10;
                &
var.&j.=ranuni(-1);
            
%END;
        
%END;
        drop rep;
        output;
    END;
RUN;
%MEND erzeugen;
%erzeugen;

(Also: Die 10 Werte A1...A10, B1...B10, usw. sollen jede für sich getrennt für jede Beobachtung sortiert werden.)

Vorhandene Lösung 1:
Ich habe mir einen kleinen Makro geschrieben, der die (im konkreten Fall je 31) Werte sortiert.
Das fordert natürlich seine Rechenzeit, da dieser Makro bei 8 Variablenblöcken und 9 Beobachtungen also 72-mal aufgerufen wird .

Ansatz 2:
Eine andere Überlegung wäre die,
a) das Dataset zu transponieren,
b) es in kleine Sets aufzusplitten (--> 1 Spalte je &anz. Beobachtungen),
c) diese mit PROC SORT zu sortieren und
d) die sortierten Sets wieder zusammenzufügen.
(Das erscheint mir nur sinnvoll, wenn es die Anzahl &anz. je gleichartiger Variablenwerte groß ist.)

Gibt es eine Möglichkeit, mit SAS-Standardwerkzeugen jede Variable eines (solchen transponierten) Sets für sich zu sortieren (SQL?)?

Ich bin schon gespannt auf Ihre Ideen.
Gruß

Meinhard Mende

noch eine Lösung

Hallo Herr Mende,

das Problem läßt sich innerhalb eines Datasteps lösen.

data beispiel_sort ;
  
set beispiel ;

  
array A_Array a1-a10 ;

  I = lbound(A_Array) ;
  
do while (I <= hbound(A_Array) - 1) ;
    J = I +
1 ;
    
do while (J < hbound(A_Array)) ;
      
if A_Array(I) < A_Array(J) then do ;
        temp = A_Array(J) ;
        A_Array(J) = A_Array(I) ;
        A_Array(I) = temp ;
      
end ;
      J = J +
1 ;
    
end ;
    I = I +
1 ;
  
end ;

  
drop I J temp ;
run ;

Das Ganze kann man jetzt natürlich noch in ein Makro packen und für die anderen Variabelenblöcke verwenden.

Ausserdem bleibt noch anzumerken, daß der verwendete Sortieralgorithmus(BubbleSort) nicht der Schnellste ist. Bei häufigem Gebauch lohnt es sich sicherlich hier z.B. QuickSort einzusetzen.

Viel Erfolg
Lutz Ritter

Lösung

Hallo Herr Mende,

ich würde das Problem wie folgt angehen:

proc transpose data=beispiel out=z;
run;
%macro z;
data z2;
set %do i=1 %to 5; z(keep= _name_ col&i rename=( col&i=col) in=a&i) %end;;
%do i=1 %to 5; if a&i then id=&i;%end;
namid=substr(_name_,1,1);
run;
%mend;
%z;

proc sort data=z2;
by id namid col;
run;

Eine Lösung über Proc IML erscheint mir ebenfalls sinnvoll!

Viel Spaß+Grüße
B. Muschik

Elegante Lösung

Hallo,

vielen Dank!
Das ist eine gute Lösung mit sehr knappem Text.

Freundliche Grüße

Meinhard Mende