投稿

2017の投稿を表示しています

マクロの引数にカンマ、クォートなどを渡す : %bquote, %str, %superq - SAS

%bquote , %str などを用いて、マクロの引数に、カンマ、クォートといった記号を渡す方法です。何度か質問されたので、まとめてみます。 まずはサンプル用のマクロとして、マクロの引数に渡った値をログに出力するだけの単純なマクロを作ります。 %macro TEST(ARGS) ; %put &=ARGS. ; %mend TEST ; まずは失敗例。下記のように、カンマやダブルクォーテーションを引数として渡そうとしてみます。しかし、カンマを付けてしまうと、"1"が 1つ目の引数の値、"2"が 2つ目の引数の値としてみなされてしまいます。マクロ定義の引数より多く引数を渡したと言われ、ERROR になってしまいます。 実行ログ 67 %TEST("1", "2") ; ERROR: マクロに定義された数よりも多い定位置パラメータが与えられています。 68 カンマやダブルクォーテーションを渡すためには、%bquote あるいは %str を使うことで、渡すことができます。 %str は、ダブルクォーテーションの前に % を書かないといけないので、少々面倒ですね。 実行ログ 69 %TEST(%bquote("1", "2")) ; ARGS="1", "2" 70 71 %TEST(%str(%"1%", %"2%")) ; ARGS="1", "2" また、引数をマクロ変数にて、渡したい場合は %bquote を使うことでできます。%str だと渡すことができません。 実行ログ 61 %let ARGS = "1", "2" ; 62 %TEST(%bquote(&ARGS.)) ; ARGS="1", "2" 63

マクロ %if とデータステップ if ステートメントで、●● < ▲▲ < ★★ の動作が異なる

SASのデータステップでは、if の条件分岐にて、if ●● < ▲▲ < ★★ ; という書き方をすることができます。 どのように動作するかというと、以下のように動きます。 まず、●● < ▲▲ が評価されます。 つぎに、▲▲ < ★★ が評価されます。 書いている通り、数学で出てくる条件文みたいな動作をしてくれます。他の言語だとあまり見ない動きです。 では、データステップ以外の条件分岐、マクロの %if でも同じ動作をしてくれるかというと、そんなことはない、というのが今回のお話です。 マクロ %if にて、同じように %if ●● < ▲▲ < ★★ ~ と記載すると、どんな動きをするのか。 まず、●● < ▲▲ が評価されます。(ここは同じ) つぎに、直前の評価結果(falseなら 0 , trueなら 1) < ★★ が評価されます。 こちらの動きの方が他の言語でよく見る論理式の動きではないでしょうか。 2つ目の処理の仕方が違うので、一見して同じような書き方でも、データステップとは処理結果が異なることになります。 この動きの違いがどんなことを起こすのか。試しに、データステップ、マクロのサンプルコードを作ってみましょう。 62 /* データステップの例 */ 63 data _null_ ; 64 if 10 < 20 < 30 then putlog "TRUE" ; else putlog "FALSE" ; 65 if 10 < 20 < 10 then putlog "TRUE" ; else putlog "FALSE" ; 66 if 10 < 20 = 1 then putlog "TRUE" ; else putlog "FALSE" ; 67 if 20 < 10 = 0 then putlog "TRUE" ; else putlog

ユーティリティファイルのサイズを調べたい : sort プロシジャ details オプション - unix版SAS限定?

sortプロシジャは、実行しているとき、ユーティリティファイルという一時ファイルを作成します。そのファイルの中でソート処理が行われるわけですが、ユーティリティファイルの容量は、ソート対象のデータセットの 1~3倍くらい?のサイズになります。どのくらいのサイズになるかは、データセットがどのような構造をしているかなどで上下します。ユーティリティファイルは、ソートの終了とともに消えてしまうので、サイズを調べるのは少々面倒です。 sortプロシジャの details オプションは、ユーティリティファイルのサイズをログに出力してくれるオプションです。このオプションをつけることで、簡単にサイズがわかります。どんな風に出力してくれるかを見てみましょう。 71 option msglevel=i lognumberformat ; 72 73 proc sort data=TEST details ; 74 by R ; 75 run ; NOTE: ユーティリティファイルが必要です。 NOTE: ユーティリティファイル 1 のページサイズは 131072 バイトです。 NOTE: データセットWORK.TESTから100,000,000オブザベーションを読み込みました。 NOTE: ユーティリティファイル 1 には 100000000 レコードと 3 並べ替えられた実行が含まれます。 NOTE: ユーティリティファイル 1 は 30527 ページ (合計 3907456.00 KB) あります。 NOTE: SASスレッドソートを使用します。 NOTE: データセットWORK.TESTは100,000,000オブザベーション、3変数です。 NOTE: PROCEDURE SORT処理(合計処理時間): 処理時間 1:16.55 ユーザーCPU時間 1:20.44 システムCPU時間 7.35 秒 メモリ 3165715.60k OSメモリ 3193028.00k タイムスタンプ 201

SAS 入力方式 $CHARw. VS $w.

入力方式 $CHARw. と $w. は文字を取り込むときに使う入力方式です(w には変数の長さが入ります)。 同じ意味の入力方式かと思いきや、少し動作が異なります。 $CHARw. は、一文字のドット . をきちんと読み込みますが、$w. は読み込まず欠損値となります。 また、頭と末に空白があった場合の動作も、若干異なります。 $CHARw. と $w. の動作の違いを確かめるテストコード data TEST ; infile cards dlm="," dsd missover ; input STR_1 : $char10. STR_2 : $10. ; LEN_1 = length(STR_1) ; LEN_2 = length(STR_2) ; cards ; ABC,DEF .,. ..,.. BC, EF "BC ","EF " " A B C "," D E F " ; run ; proc print data=TEST ; run ; OBS STR_1 STR_2 LEN_1 LEN_2 1 ABC DEF 3 3 2 . 1 1 3 .. .. 2 2 4 BC EF 3 2 5 BC EF 2 2 6 A B C D E F 6 5 一文字のドットがある場合、$CHARw. はそのまま取り込めているのがわかります。$w. は欠損値となっています。 頭と末の空白については、見た目上はわからないですが、length 関数の値が異なる場合があるのがわかります。どうやら、先頭の空白の有無で違いが現れているようで、末の空白は違いがないようです。(ただし、頭と末の空白の扱い方は、