変数のソート方法

[OS]ALL
[リリース] 5.18, 6.07, 6.08, 6.09, 6.10
[キーワード] base, transpose, datastep, sort, variables, array, dim

[質問]

オブザベーションのソートはSORTプロシジャを使用すれば出来ますが、変数のソートはどうすればよいでしょうか。

[回答]

いろいろな方法が考えられますが、下記のケースで2パターンの例を示します。

●あるオブザベーションをキーとする場合

1オブザベーション目をキーとして、以降のオブザベーションについても変数をソートします。
(ソート前)
SASデータセット : SAMPLE1
--------------------------------
VAR1   VAR2   VAR3   VAR4   VAR5
4      12      2      5      7
5       1      8      9     10
2       9     13      1      6
11      5      7      3      2
8       3      9     12      8           

(ソート後)
SASデータセット : SAMPLE2
--------------------------------
VAR1   VAR2   VAR3   VAR4   VAR5
2      4      5      7     12
8      5      9     10      1
13     2      1      6      9
7     11      3      2      5
9      8     12      8      3

次のプログラムは、TRANSPOSEプロシジャで転置(変数とオブザベーションを入れ替える)したデータセットをSORTプロシジャでソートし、 ふたたびTRANSPOSE プロシジャで転置されたデータをもとの形式にもどします。

proc transpose data=sample1 out=work1 ;
    run ;
    proc sort data=work1 ;
      by col1 ;            
    run ;      /*COLn(nはオブザベーション番号と等しい)*/
    proc transpose data=work1 out=sample2(drop=_name_); 
    run ;

●すべての変数のデータ値をソートする場合

(ソート前)
SASデータセット : SAMPLE1
--------------------------------
VAR1   VAR2   VAR3   VAR4   VAR5
4      12      2      5      7
5       1      8      9     10
2       9     13      1      6
11      5      7      3      2
8       3      9     12      8

(ソート後)
SASデータセット : SAMPLE2
--------------------------------
VAR1   VAR2   VAR3   VAR4   VAR5
2      4      5      7     12
1      5      8      9     10
1      2      6      9     13
2      3      5      7     11
3      8      8      9     12

次のプログラムは、読み込んだデータ値を配列に持ち、その配列の大小比較をしながらデータをソートしています。
イメージとしては、オブザベーション単位に左右のデータを比較し、より小さいデータを左側にもってくる動きを繰り返すと考えてください。

data sample2(keep=var1-var5);
      array varlist(5) var1-var5;
      set sample1;
      do k=1 to dim(varlist)-1;
        do j=1 to dim(varlist)-k;
          if varlist(j) > varlist(j+1) then do;
            varcopy      = varlist(j+1);
            varlist(j+1) = varlist(j);
            varlist(j)   = varcopy;
          end;
        end;
      end;
    run;
※備考:例題のデータセットは変数が5つですが、配列数とループの回数を変えることで、変数の増減に対応できます。