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

データセットオプションの適応順の推測

自分がしょっちゅう間違えるので、自分のために整理します。

さて

data Q1;
 do X=1 to 10;
  output;
 end;
run;

のデータセットがあります。


以下の①から④までのプログラムを実行したとき
エラー・ワーニングがでずに、きちんとYにリネームされた
データセットが作成されるのはどれでしょうか??

/*①*/
proc sort data=Q1 out=A1(rename=(X=Y) where=(X>5));
 by X;
run;

/*②*/
proc sort data=Q1 out=A2(rename=(X=Y) where=(Y>5));
 by X;
run;

/*③*/
proc sort data=Q1 out=A3(rename=(X=Y) keep=X);
 by X;
run;

/*④*/
proc sort data=Q1 out=A4(rename=(X=Y) keep=Y);
 by X;
run;


なんか、SAS BASEの資格試験にでてきそうな、いやらしい問題ですね



まず
【①の結果】








データセットは作成されません


【②の結果】








【③の結果】









【④の結果】









WARNINGだけですが、データセットは作成されてません


というわけで

①×
②○
③○
④×

でした。


推理するに、データセットオプション内でのステートメントについて
keep → rename → where
の順で適応されているということでしょうかね。

たぶん、きちんと資料読めば、どっかに書いてあるんでしょうか、とりあえずここまで






データセット名を変更する。SCL関数のrenameで、変更前後の名前リストを参照して一括変更する方法

データセットの名前を変えます。

data A0;
 X=1;
run;
data A1;
 X=1;
run;
data A2;
 X=1;
run;
data A3;
 X=1;
run;


とりあえず、データセットのよろずごとはproc datasetsにお任せって感じで、以下のようにかけます。

proc datasets;
 change A0=Z;
quit;

でも個人的にproc datasetsあんまり好きじゃないです。なんか文法が特殊で覚えにくいです。
changeステートメントなんて、ぱっとでてきません。

僕はもっぱら

data _null_;
 rc=rename('A1','B1','data');
run;

rename関数使います。
rename関数のいいところは、たとえば

data list;
OLD='A2';NEW='C2';output;
OLD='A3';NEW='C3';output;
run;

のように、現在のデータセット名と、リネーム後のデータセット名をリスト化したものを
データセットとして作成しておけば後は

data _null_;
 set list;
 rc=rename(OLD,NEW,'data');
run;


って感じで、百個だろうが二百個だろうが、一瞬でリネームできます。

dictionaryテーブルなどから現在のデータセット名の情報をとってきて、
一定のルールにしたがって(先頭にアンダースコア付けるとか、末尾に連番とか)の
処理を仕掛けたい時に重宝します。

まあ、データが小さければ、その都度新規にデータセット作ってもいいと思いますが。

あ、ちなみに、rename関数はデータセット以外でも、ファイル名やフォルダ名変えたり、色々できます。

あと、たまに質問いただきますが rc=はreturn codeの略でリターンコードです。
処理がうまくいけば「0」が入ります。なので、0じゃなかったらputで「うまくいきませんでした」的な
メッセージを出すようにすれば、どの処理が失敗したかを判別できます。

今 _null_で作っていますが、これを適当なデータセット名にして、listのoldの値を、存在しないデータセット何して、実行した後、作成されたデータセットのrcの値を見てもらえばわかりやすいと思います。

SCL関数とよばれるやつらは、みんなこういう形態をとります。

ハッシュオブジェクト扱う時のrc=とか、インデックスとかでやりくりするときの
IORC=(Input Output Return Codeの略)とかと、全く同じようなものです。








【解答求む】フォーマットがついた変数を新規変数に割り当てても解除される話

今更ながら、とても基本的な部分で質問なのですが
たとえば、以下のようなデータセットがあって

data Q1;
 X=18993;
 format X yymmdds10.;
run;





Xは数値で、日付フォーマットがついてます。

data A1;
 set Q1;
 Y=X;
run;

とすると





YにXの値が割り当てられますが、フォーマットは継承されません。

YにもXと同じフォーマットをあてたい時

data A1;
 set Q1;
 Y=X;
 format Y yymmdds10.;
run;

としてました。

まあ、同じ内容の変数を1つのデータセットの中に作る処理なんて、意味ないのでほぼやったことないせいですが、今までこのことに疑問を感じたことはありませんでした。

これって他にやりようないのでしょうか?
フォーマットを継承するオプションや関数をご存じの方がいらっしゃればご教示いただきたいです。


なぜ、そんなことをいまさら思ったのかというと
例えば、同じような処理でも

proc sql noprint;
 create table A2 as
  select X 
        ,X as Y
    from Q1
    ;
quit;

とすると





となってフォーマットは継承されているわけです。ただ、この場合は、割り当てているのではなく
変数Xをコピーしてをリネームしているという感じなので、フォーマットが同じで当たりまえといえば
当たり前なわけです。継承しているとはいわないでしょう。


じゃあ、その理屈でいくならばと思って以下のようにすると

data A3;
 set Q1;
 set Q1(rename=(X=Y));
run;





できました。
できましが、これ、変数追加するためだけに2回セットしてて、効率悪いですよね。

こんなことばかり、いつも思いついては、考え込んでしまいます






rename X_1-X_4=Y_1=Y_4 みたいな連番一括指定

大した話ではないです。

data Q1;
X_1=1;X_2=2;X_3=4;X_4=4;
run;




みたいなデータセットがあって、X_の部分を全部Y_にリネームしたいなと思って

data A0;
 set Q1(rename=(X_1=Y_1 X_2=Y_2 X_3=Y_3 X_4=Y_4));
run;

みたいな処理を書いていたんですが、

data A1;
 set Q1(rename=(X_1-X_4=Y_1-Y_4));
run;

でいけるんですね。

もちろんデータセットオプションじゃなく

data A2;
 set Q1;
 rename X_1-X_4=Y_1-Y_4;
run;

でもいけます。





renameステートメントにコロンモディファイアを使えなかったので、てっきり連番指定も無理だと
思いこんでいたら、そんなことなかったです。損してました。