ラベル 関数 の投稿を表示しています。 すべての投稿を表示
ラベル 関数 の投稿を表示しています。 すべての投稿を表示

2017年9月7日木曜日

関数内での配列の使い方



「定義した配列を関数の中で使うにはどのように書けばよいですか?」

という質問を頂くことがあるので、簡単に紹介します。



* Sample data ;
data DT1;
    X=1;
    Y=2;
    Z=3;
run;






* 関数内で配列を使う例 ;
data DT2;
    set DT1;
    array AR(*) X Y Z;

    * 例① ;
    TOTAL1 = sum( AR(1), AR(2) );

    * 例② ;
    TOTAL2 = sum( of AR(*) );
run;



「例①」では配列からAR(1)とAR(2)を指定しています。
「例②」では配列ARの全要素を指定しています。

ひとつだけ注意点。
配列には色々な種類がありますが、その配列の種類によっては、例②の書き方が通用しない関数があります(実行時にERRORになる)



2014年7月3日木曜日

関数の中でOFを使うと変数の指定が楽になる例と応用例。



たとえば変数A1~A5の合計を求めたい時、

VAR = sum(of A1-A5);

と書きます。よくあるOFの使い方ですが以下のように、、

VAR2 = sum(A1, A3, A5);

VAR2 = sum(of A1 A3 A5);

変数名の間のカンマ(,)を省略したい場合にOFを使うことができます。


このカンマ省略機能が生かされる例として以下の例を見てみましょう。

%macro M_SUM( DSNAME, VARS );

  data &DSNAME;
    A=1;
    B=1;
    C=1;
    D = sum(of &VARS);
  run;

%mend;
%M_SUM( DT1, A B C );
%M_SUM( DT2, A C );


マクロを実行する際の引数の指定が楽になってますね。
OFを使わないとカンマをQUOTEするために%STR関数等を使う必要がありました。

%M_SUM( DT1, %str(A, B, C) );
%M_SUM( DT2, %str(A, C) );



2014年3月18日火曜日

関数の落とし穴



シングルバイト専用の関数に、マルチバイト文字を含む引数を指定しちゃダメという話です。
今回の内容はWindowsのSAS9.3 日本語 (shift-jis) の環境下での結果とします。他の環境下では挙動が異なります。


上記環境下で以下のプログラムを実行すると変数BとCの値は変わった動きをします。

data DT1;
   length A B $20.;

   A = "予防";
   B = compress(A, "\");
   C = index(A, "\");
run;

結果
A        B         C
予防    蘭h       2



これは文字コードが関係しています。この辺は詳しくないですが、
  • "予防"の"予"という字は文字コードだと「975C」、
  • "\" は文字コードだと「5C」になるようです。

「5C」の部分が共通なので、"予" に "\" が入っているものとして扱われてしまいます。
「5C」に限らず、マルチバイト文字だと上記のように文字コードで見たときに共通する部分が出てきてしまうため、関数の結果がおかしくなります。


たとえば以下の場合とかもおかしくなるはず。
「VAR1 = compress("右", "E");」


これを回避するのが、「K」を頭につけたマルチバイト対応の関数達です。
data DT2;
   length A B $20.;

   A = "予防";
   B = kcompress(A, "\");
   C = kindex(A, "\");
run;

結果
A        B        C
予防    予防    0



注意点として、以下の例のように、シングルバイト専用の関数はバイト数で判断するのに対して、K関数達は文字数で判断します(K関数でもバイト数で判断するものもある)

 INDEX("あいう","い") -> 3
 KINDEX("あいう","い") -> 2

2014年2月7日金曜日

関数の小技


関数の中に式を書くテクニック。


サンプルプログラム

data DT1;
   V1 = 1;
   V2 = "abc";
   VSUM = sum( V1=1, index(V2,"b")>0 );
run;


解説

関数の中にあるそれぞれの式には、
条件に合致する場合「1:true」、合致しない場合「0:false」が返される。

上記サンプルの場合、
・式「V1=1」の結果は「1:true
・式「index(V2,"b")>0」の結果は「1:true
・「sum(1:true + 1:true)」=「2」となる。


応用例

SUM関数での応用例としては
  ・条件に当てはまる個数を知りたい
  ・IF文を短縮させたい
といったとき役に立つ。

IF文の短縮とは、、
たとえば上記サンプルに、以下のようなルールで変数「FLG」を作りたいとする。
条件①「V1」=「1」である。
条件②「V2」に"b"という文字が含まれている。

・条件が全て当てはまらない場合 ・・・ FLG=「1」
・いずれか当てはまる場合 ・・・ FLG=「2」
・全て当てはまる場合 ・・・ FLG=「3」



通常、以下のようなIF文を書くことになるけど、、

if  not (V1=1  or  index(V2,"b")>0)    then FLG=1;
if  V1=1  or  index(V2,"b")>0       then FLG=2;
if  V1=1  and  index(V2,"b")>0    then  FLG=3;



関数の中に式を入れる方法を使うと、

VSUM = sum(V1=1, index(V2,"b")>0);

if  VSUM = 0  then  FLG=1;
if  VSUM > 0  then  FLG=2;
if  VSUM = 2  then  FLG=3;


このようにすっきりした文を書くことが出来る。


まとめ

パフォーマンスが悪くなったり、関数の中の式があまりにも長文になる場合を除いて、スッキリと見通しのいいプログラムになるのであれば積極的に使ってます。

他の関数でも、たくさん応用的な使い方が出来るので、どんなことが出来るかいろいろ試してみると面白いです。