BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
sskt
Quartz | Level 8

お世話になっております。

以下のように、if文のthenの後をループやテーブル内の変数を使ったものにしたいと考えていますが、エラーでうまくいきません。

 

data x;
set x;
%do i = 1 %to 8; if name = "q1_&i" then catt("q1_",val,"_&i",) = .; %end;
run;

一度他ファイルに出力して、インクルードするという方法もあるかと思いますが、

それをせずにこれを実現する方法はありますでしょうか?

 

[追記]

データセットxには文字列のカラムnameやvalが入っております。

if name = "q1_1" then q1_x_1,) = .;

というプログラムは動くようです。

 

そもそもthenの後にcatt関数を使用して文字列を結合することは可能なのでしょうか?

ERROR:配列cattは定義されていません

というエラーになってしまいます。cattが関数でなく配列と認識されてしまっているようです。

 

よろしくお願いいたします。

1 ACCEPTED SOLUTION

Accepted Solutions
yu_sas
SAS Employee

DATAステップですが、コンパイルフェーズと実行フェーズに分かれており、変数名はコンパイルフェーズで決まるため、実行フェーズで決めることはできません。割り当てステートメントの左側に関数を指定しても、メッセージにあるように配列の参照と見なされ、エラーとなります。

 

ある程度複雑な内容を質問する際は、加工前のデータ例と加工後のデータ例に加え、どのようなロジックで加工するか記載頂いたほうが、回答が付きやすいと思います。

私も少々判断がついていないのですが、データセットの値に基づいて変数名を決める場合はCALL EXECUTEルーチンを使う方法があります。これによりDATAステップ内で別のDATAステップを生成することができます。

 

data x;
input name $ val $;
cards;
q1_1 x
q1_2 y
q1_3 z
;

data x;
set x end=last;
if _n_=1 then call execute('data x2;');
if substr(name,1,3)='q1_' then call execute(cats('q1_',val,substr(name,4),'=.;'));
if last then call execute('run;');
run;

 

View solution in original post

3 REPLIES 3
japelin
Rhodochrosite | Level 12

マクロのループ処理化とのことですが、通常のsasコードで(冗長だとしても)動くコードは書けていますか。

 

また、提示されたコードだけでは何をどうしたいのかわかりませんので、(マクロではない)コード、(サンプル)データを提示してください。

 

 

yu_sas
SAS Employee

DATAステップですが、コンパイルフェーズと実行フェーズに分かれており、変数名はコンパイルフェーズで決まるため、実行フェーズで決めることはできません。割り当てステートメントの左側に関数を指定しても、メッセージにあるように配列の参照と見なされ、エラーとなります。

 

ある程度複雑な内容を質問する際は、加工前のデータ例と加工後のデータ例に加え、どのようなロジックで加工するか記載頂いたほうが、回答が付きやすいと思います。

私も少々判断がついていないのですが、データセットの値に基づいて変数名を決める場合はCALL EXECUTEルーチンを使う方法があります。これによりDATAステップ内で別のDATAステップを生成することができます。

 

data x;
input name $ val $;
cards;
q1_1 x
q1_2 y
q1_3 z
;

data x;
set x end=last;
if _n_=1 then call execute('data x2;');
if substr(name,1,3)='q1_' then call execute(cats('q1_',val,substr(name,4),'=.;'));
if last then call execute('run;');
run;

 

sskt
Quartz | Level 8
ありがとうございます。

call execute、知らなかったのでレパートリーに加えさせていただきます。
ぐぐったら「自分でプログラムを書くよりもデータセットに格納されている文字列をそのまま
プログラムに使用したいときに使う機能」
とのことらしいので、今回にぴったりだと思いました。

ありがとうございました。

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

Discussion stats
  • 3 replies
  • 1265 views
  • 1 like
  • 3 in conversation