2017-02-21 10 views
1

マクロプログラムを作成して、複数の変数の値をグループ内の以前の欠損値で置き換える前に、複数の変数を順番に使用してデータセットをソートする必要がありますすべての観察を特定する。欠損値をマクロに置き換えます

私は、テストデータセットがあります。

data temp2; 
input countryname $1-5 +1 countrycode $7-8 +1 dev 1. +1 legal 1. +1 audit 1.; 
datalines; 
china 22 9 2 3 
china 22 . . 3 
china 22 7 3 . 
china 21 4 . . 
japan 13 3 . 1 
japan 12 3 . . 
japan 13 1 2 3 
; 
run; 

そして、あなたが見ることができるように、私はCOUNTRYNAMEと国番号でソートする必要があります。 devlegalauditの値を置き換えます。私は次のようなマクロを試しました:

`%macro replace(dsetin=,dsetout=,idvars=,vars=); 
%if &dsetout = %then %let dsetout = &dsetin; 
%let char=_; 
%do xi=1 %to %sysfunc(countw(&vars)); 
%let var = %scan(&vars,&xi); 
%let _VARs_=%sysfunc(cat(&char,&var)); 
%end; 
%let m=%sysfunc(countw(&vars)); 
%do yi=1 %to %sysfunc(countw(&idvars)); 
%let idvar = %scan(&idvars,&yi); 
%let lagid = lag(&idvar); 
%end; 
%let n=%sysfunc(countw(&idvars)); 
proc sort data=&dsetin out=temp1; 
by &idvars; 
run; 
data &dsetout; 
set temp1; 
by &idvars; 
array id(&n)&idvar; 
array lag(&n)&lagid; 
array vara(&m)&var; 
array vars(&m)&_VARs_; 
do yi = 1 to &n; 
if lag(yi)=id(yi) then do; 
do xi= 1 to &m; 
retain &_VARs_; 
if not missing(&var) then &_VARs_ =&var; 
else &var = &_VARs_; 
end; 
%end; 
end; 
drop of &_VARs_:; 
run; 
%mend replace; 
%replace(dsetin=temp,dsetout=temp2,idvars=countryname countrycode,vars=DEV LEGAL AUDIT)` 

これは面倒です。 タスクを処理できません。 sortを使用するby-variablesの数は 'replace'変数の数と異なる可能性があるためです。私は、マクロがさまざまな機会に適用されることを願っています。ソートを使用するidvarsの数は、 'replace'変数の数よりも多くなることがあります。時には前者は後者よりも小さくなることがあります。

私の問題を説明できることを願っています。ありがとう。

答えて

0

このようなことが望ましい結果をもたらすか?

& varsに定義されている変数が見つからない場合は、それ自体のラグに置き換えられます。

data temp; 
    input countryname $1-5 +1 countrycode $7-8 +1 dev 1. +1 legal 1. +1 audit 1.; 
    datalines; 
china 22 9 2 3 
china 22 . . 3 
china 22 7 3 . 
china 21 4 . . 
japan 13 3 . 1 
japan 12 3 . . 
japan 13 1 2 3 
;run; 

%macro replace(dsetin,dsetout,idvars,vars); 
    %if &dsetout = %then %let dsetout = &dsetin; 

    proc sort data=&dsetin out=temp1; 
     by &idvars; 
    run; 

    data &dsetout; 
     set temp1; 
     *by &idvars; 

     array variables &vars; 
     array lags {%sysfunc(countw("&vars"))}; 

     do i=1 to countw("&vars"); 
      lags[i] = lag(variables[i]); 
      if variables[i]=. then variables[i] = lags[i]; 
     end; 

     drop of lags: ; 
     drop i; 

    run; 

%mend replace; 
%replace(temp,,countryname countrycode,DEV LEGAL AUDIT); 
+0

ありがとうございました!私は私の問題を解決しました。 – JNWong

0

UPDATEステートメントを使用して、欠損値を転送することができます。

このマクロを作成してデータをソートし、UPDATEステートメントを使用して、選択した変数の欠損していない値を転送することができます。追加のSET文を追加することで、他の変数がUPDATE操作の影響を受けないことを確認できます。最後に、すべての観測を書き込むためにOUTPUTステートメントが必要です。そうしないと、BYグループの最後の観測のみが書き込まれます。 VARSを空白のままにしておくと、すべての変数を更新するほどスマートにすることさえできます。

data have; 
    length countryname $5 countrycode $2 dev legal audit 8 ; 
    input countryname -- audit ; 
datalines; 
china 22 9 2 3 
china 22 . . 3 
china 22 7 3 . 
china 21 4 . . 
japan 13 3 . 1 
japan 12 3 . . 
japan 13 1 2 3 
;;;; 

して保持されているすべての変数とマクロを実行します。

%macro replace(dsetin=,dsetout=,idvars=,vars=); 
    %if not %length(&dsetin) %then %let dsetin=&syslast; 
    %if not %length(&dsetout) %then %let dsetout=&dsetin ; 
    %if %length(&vars) %then %let vars=&idvars &vars; 
    proc sort data=&dsetin out=&dsetout; 
    by &idvars; 
    run; 
    data &dsetout ; 
    update &dsetout (obs=0) &dsetout (keep=&vars) ; 
    by &idvars ; 
    set &dsetout(drop=&vars); 
    output; 
    run; 
%mend replace ; 

今度は、いくつかのテストデータを作成してみましょう。そしてもう一度、もう一度。

%replace(dsetin=have,dsetout=want1,idvars=countryname countrycode,vars=); 
%replace(dsetin=have,dsetout=want2,idvars=countryname countrycode,vars=legal); 

次に、結果を比較してください。

proc compare data=want1 compare=want2 ; 
run; 
+0

ありがとうございます!あなたは新しい方法を提供しました。それは将来のケースで私を助けるかもしれません。 – JNWong

関連する問題