2016-11-11 10 views
0

以下のSASコードを書くことによって表2を作成しようとしましたが、私が得たものは表1です。私が逃したものは分かりませんでした。非常に感謝していただきありがとうございますSAS SymputXとSymget Function

 &counter = 4 

    data new;set set1; 
    total = 0; 
    a = 1; 
    do i = 1 to &counter; 
     call symputX('a',a); 
     total = total + Tem_&a.; 
     a = symget('a')+1; 
     call symputX('a',a); 
    end; 
    run; 



     Table 1 
     ID Amt Tem_1 Tem_2 Tem_3 Tem_4 total 
     4 500 1  4  5 900 3600 
     5 200 50  100  200  0  0 
     9 50 40  0  0  0  0 
     10 500 70  100  250  0  0 



    Table 2 
    ID Amt Tem_1 Tem_2 Tem_3 Tem_4 total 
     4 500 1  4  5 900  910 
     5 200 50  100  200  0  350 
     9 50 40  0  0  0  40 
    10 500 70  100  250  0  420 

答えて

2

残念なことに、SYMPUTとSYMGETを使用することはできません。それらを使用してマクロ変数値を格納/取得することはできますが、実行後にコンパイラに送信されるコードは変更できません。

基本的に、SASは、データを見る前にデータステップループの各繰り返しでマシンのコードを調べなければなりません(これはコンパイルと呼ばれます)。したがって問題は、tem_&a.を定義することはできず、実行中に何を変更することができると期待します。そのマシンコードが行う必要があるものが変更され、SASがそれを十分に準備できないためです。

したがって、&a.を書き込んだものは、プログラムがコンパイルされたときに解決され、データステップ前に&a.の値が何であってもtem_&a.になると解決されます。おそらくこれを初めて実行したときにエラーが発生した(&a. does not resolve、次にエラーは&であり、変数名では不正です)、最終的にはcall symputがその仕事を行い、ループの最後に&aに4が入りました。 tem_&a.tem_4に解決されました。

解決策はありますか?これにはマクロを使用しないでください。代わりに、配列を使用します。

data new; 
    set set1; 
    total = 0; 
    array tem[&counter.] tem_1-tem_&counter.; 
    a = 1; 
    do i = 1 to &counter; *or do i = 1 to dim(tem); 
     total = total + Tem[i]; 
    end; 
run; 

もちろん、それらを直接合計するだけです。

data new; 
    set set1; 
    total = sum(of tem_1-tem_4); 
run; 

それはデータステップ技術に固執するのはとても良いでしょう、これは、この目的のために推奨さないですが、あなたが本当にマクロ変数のように、あなたはもちろん、マクロ doループでこれを行うことができれば。とにかく、これをマクロの中で実行すると、これはうまくいくはずです(これはオープンコードでは有効ではありません)。

data new; 
    set set1; 
    total = 0; 
    %do i = 1 %to &counter; 
     total = total + Tem_&i.;   
    %end; 
    run; 
+0

ありがとう、ジョー! –

+0

@Joeおそらく、ハードコードされた上限をマクロ変数リファレンスで置き換えるか、マクロ変数リファレンスを削除する必要があります。今のところ、COUNTERが4でなければ問題が発生します。 – Tom

+0

@tomに同意します。なぜなら、私は並列コードを表示するために元のコードからコードをずらすことではなかったからです。 – Joe