いいのか悪いのかわからないのですが,SASのARRAYは文字型変数と数値型変数をまぜて作れないので,少し不便なことがあります.
まず 処理したい変数をくくって,そこから文字変数はこう処理,数値変数はこうってしたいことってあると思うんですよね.ってことで,それっぽいマクロを作りました
%macro x_array(list=,
ch_code=,
num_code=,
array_no=
);
%let list=%sysfunc(upcase(%sysfunc(compbl(&list))));
%let qlist = %sysfunc( tranwrd( %str("&list") , %str( ) , %str(",") ) );
%let itemnum = %sysfunc( count( &list, %str ( ) ));
_banpei_num=.;
_banpei_char="";
array arch&array_no. _character_;
array arnum&array_no. _numeric_;
do over arch;
if upcase(vname(arch&array_no.)) in (&qlist) then do;
arch&array_no.=arch&array_no.;
&ch_code;
end;
end;
do over arnum&array_no.;
if upcase(vname(arnum&array_no.)) in (&qlist) then do;
arnum&array_no.=arnum&array_no.;
&num_code;
end;
end;
drop _banpei_num _banpei_char;
%mend;
例えば以下のようなテストデータ
C1-C3に文字でABC
N1-3は数値で1-3入れて
Z1ーZ3には文字で1-3入れてます
ここで適当に
ここで,
① C1,C3,N1で 型混合配列1として定義し,配列内の文字型要素を---に数字型要素を1000倍
② C2,N2で 型混合配列2として定義し,配列内の文字型要素を3倍繰り返しに数字型要素を正負反転処理
③ Z1 Z2 Z3を型混合配列3として定義し,文字で入ってるけど,すべて数値に変えて,合計値をZSUMとして求める
とかって 処理をしたい時にさっきのマクロで
data out;
set test;
%x_array(list=C1 C3 N1
,ch_code=%str(arch='---')
,num_code=%str(arnum = arnum*1000 )
);
%x_array(list=C2 N2
,array_no=1
,ch_code=%str(arch1=compress(repeat(arch1,2)))
,num_code=%str(arnum1 = arnum1*-1 )
);
array NZ NZ1-NZ99;
%x_array(list=Z1 Z2 Z3
,array_no=2
,ch_code=%str(
NZ=input(arch2,best.);
)
);
ZSUM=sum(of NZ:);
put ZSUM=;
drop NZ:;
run;
まあ,できちゃうよと.
別途,C: みたいにコロンモディファイアでリスト指定したいとか
N1-N3とかで連番指定 C1--Z1みたいな位置していで型混合配列にしたい場合
事前に変数リストを作るマクロも作りました
%varlist_modi(listno=1,ds=test,modi=C:);
とすれば
&namelist1 というマクロ変数の中に C1 C2 C3という データに基づいて生成された
リストができるので,それを先のマクロで指定してくださいってことですね
ただ,良し悪しかなと思うのは
SASは2つしか型がなくて,それはSASの根幹の部分なので,それを見せかけ上マスクしてしまうのは,作業的には便利なんですが,プログラム的にはどうなのかなと思わなくもないですね.
明示的に数値は数値の処理,文字は文字の処理って書いたほうが綺麗な気もします
0 件のコメント:
コメントを投稿