2017-02-07 6 views
0

欠損値を欠損していない2つの値の平均で置き換える簡単な方法を見つけることを試みています。例:SAS:欠損値を最近隣の平均値に置き換える

Id Amount 
1 10 
2 . 
3 20 
4 30 
5 . 
6 . 
7 40 

所望の出力

Id Amount 
1 10 
2 **15** 
3 20 
4 30 
5 **35** 
6 **35** 
7 40 

任意の提案ですか?私はretain関数を使ってみましたが、最後の欠損値を保持する方法しか分かりません。

+1

を定義しているの?レコード5では、なぜ25分の20/30ではないのですか?あなたのルールには明確化が必要です。不足している値を置き換えるためのオプションについては、PROC STANDARDIZEおよびMISSINGオプションを参照してください。あなたのケースが本当にあなたのサンプルに似ている場合、欠損値が帰属された線形回帰が別の選択肢かもしれません。 – Reeza

+0

良い点。明確にするために、「近く」までは、以前の欠損値と次の欠損値を欲しかった。 – User1414

答えて

0

これは動作します:

data have; 
    input id amount; 
cards; 
1 10 
2 . 
3 20 
4 30 
5 . 
6 . 
7 40 
; 
run; 

proc sort data=have out=reversed; 
    by descending id; 
run; 

data retain_non_missing; 
    set reversed; 
    retain next_non_missing; 
    if amount ne . then next_non_missing = amount; 
run; 

proc sort data=retain_non_missing out=ordered; 
    by id; 
run; 

data final; 
    set ordered; 
    retain last_non_missing; 
    if amount ne . then last_non_missing = amount; 
    if amount = . then amount = (last_non_missing + next_non_missing)/2; 
run; 

しかし相変わらず、生産使用のためなどをチェックし、余分なエラーが必要になります。

重要なアイデアはデータを逆順に並べ替えることで、RETAINを使用してnext_non_missingの値をデータセットにバックアップすることができます。正しい順序にソートされると、不足している値を補間するのに十分な情報が得られます。

もっと制御された方法でこれを行うには、PROCがあるかもしれませんが(私はPROC STANDARDIZEについては何も知らない、Reezaのコメントに記載されています)、これはデータステップの解決策として機能します。

+0

ニース、これは機能する。私が気づく唯一の事は、最初または最後の観測が見当たらない場合、コードはそれらの(b/cが最後に欠落していないか、次の欠落していない)を埋めることがないということです。しかしそれはちょっとしたことであり、手作業でそれらを記入することができます。 – User1414

+0

幸せなら、これを正しい答えとしてください。最初の/最後の値が不足していることは間違いありません。そのため、余分なエラーチェックが必要であることを強調しました。元の質問では、これらのケースで何をするか指定されていませんでした。おそらく最後の既知の価値を前進/後退させたいと思うでしょうか? –

0

ソートを必要としない別の方法があります。それはIDが順番であることを必要としますが、そうでなければ回避することができます。

これは2つのset文を使用します.1つはメイン(および前の)金額を取得し、もう1つは次の金額が見つかるまで設定します。ここでは、idのシーケンスを使用して正しいレコードになることを保証しますが、id変数が連続していなくても、または任意の順序であれば、必要に応じてこれを書き換えることができますソート。

first.amountチェックを使用して、2番目のsetステートメントを実行しないようにしてください(早期に終了する必要があります)。

最初と最後の行を別々に扱いたい場合は、2つのことを別々に行う必要があります。ここでは、最初の行であればprev_amountは0であると仮定し、last_amountがないと仮定します。つまり、最後の行は最後のprev_amountを繰り返し取得し、最初の行は0とnext_amountの平均です。あなたが選択した場合、どちらか一方を別の方法で扱うことができます。私はあなたのデータを知らない。

data have; 
input Id Amount; 
datalines; 
1 10 
2 . 
3 20 
4 30 
5 . 
6 . 
7 40 
;;;; 
run; 

data want; 
    set have; 
    by amount notsorted; *so we can tell if we have consecutive missings; 
    retain prev_amount; *next_amount is auto-retained; 
    if not missing(amount) then prev_amount=amount; 
    else if _n_=1 then prev_amount=0; *or whatever you want to treat the first row as; 
    else if first.amount then do; 
    do until ((next_id > id and not missing(next_amount)) or (eof)); 
     set have(rename=(id=next_id amount=next_amount)) end=eof; 
    end; 
    amount = mean(prev_amount,next_amount); 
    end; 
    else amount = mean(prev_amount,next_amount); 
run; 
2

あなたが探しているものは補間のようなものかもしれません。これは2つの最も近い値の意味ではありませんが、有用かもしれません。

というデータセットで補間するための小さなツールがあります。これは、proc expandです。 (これも外挿する必要がありますが、まだ試していません)。これは、一連の日付と累積計算を行うときに非常に便利です。

data have; 
input Id Amount; 
datalines; 
    1 10 
    2 . 
    3 20 
    4 30 
    5 . 
    6 . 
    7 40 
    ; 
run; 

proc expand data=have out=Expanded; 
    convert amount=amount_expanded/method=join; 
    id id; /*second is column name */ 
run; 

PROCの詳細は、ドキュメントを参照して展開するために:どのようにあなたは、最寄りhttps://support.sas.com/documentation/onlinedoc/ets/132/expand.pdf

関連する問題