2017-04-12 44 views
0

我想特別本月平均值來代替所有0.0如何用sas或sql中的組平均值替換0?

value date  month year 
33.2 01SEP2016 9 2016 
33.7 02SEP2016 9 2016 
34.8 03SEP2016 9 2016 
33.8 04SEP2016 9 2016 
33.7 05SEP2016 9 2016 
33.8 06SEP2016 9 2016 
32.7 07SEP2016 9 2016 
33.4 08SEP2016 9 2016 
32.5 09SEP2016 9 2016 
33.7 10SEP2016 9 2016 
32.7 11SEP2016 9 2016 
32.5 12SEP2016 9 2016 
32.1 13SEP2016 9 2016 
32.2 14SEP2016 9 2016 
32.0 15SEP2016 9 2016 
31.8 16SEP2016 9 2016 
31.8 17SEP2016 9 2016 
31.9 18SEP2016 9 2016 
32.5 19SEP2016 9 2016 
32.5 20SEP2016 9 2016 
32.3 21SEP2016 9 2016 
32.6 22SEP2016 9 2016 
14.2 23SEP2016 9 2016 
0.0  24SEP2016 9 2016 
0.0  25SEP2016 9 2016 
0.0  26SEP2016 9 2016 
0.0  27SEP2016 9 2016 
0.0  28SEP2016 9 2016 
0.0  29SEP2016 9 2016 
0.0  30SEP2016 9 2016 
+0

發現然後將其合併回原始表,如果值爲0.0,則將其替換爲平均值 – NEOmen

+0

並且還有另一種情況,我需要將av最後三次發生的情況。那麼將會怎樣處理?例如。我在「2016年9月24日」有0值,那麼我需要平均23,22,21七月。 –

+0

接下來的幾天如何? 27日,28日等,目前沒有價值的前3天? – Longfish

回答

0

你的問題的第一部分是很容易的。首先將零值更改爲缺失值,然後使用proc stdsize將缺失值更改爲月份的平均值。

/* create initial dataset */ 
data have; 
input value date :date9. month year; 
format date date9.; 
datalines; 
33.2 01SEP2016 9 2016 
33.7 02SEP2016 9 2016 
34.8 03SEP2016 9 2016 
33.8 04SEP2016 9 2016 
33.7 05SEP2016 9 2016 
33.8 06SEP2016 9 2016 
32.7 07SEP2016 9 2016 
33.4 08SEP2016 9 2016 
32.5 09SEP2016 9 2016 
33.7 10SEP2016 9 2016 
32.7 11SEP2016 9 2016 
32.5 12SEP2016 9 2016 
32.1 13SEP2016 9 2016 
32.2 14SEP2016 9 2016 
32.0 15SEP2016 9 2016 
31.8 16SEP2016 9 2016 
31.8 17SEP2016 9 2016 
31.9 18SEP2016 9 2016 
32.5 19SEP2016 9 2016 
32.5 20SEP2016 9 2016 
32.3 21SEP2016 9 2016 
32.6 22SEP2016 9 2016 
14.2 23SEP2016 9 2016 
0.0  24SEP2016 9 2016 
0.0  25SEP2016 9 2016 
0.0  26SEP2016 9 2016 
0.0  27SEP2016 9 2016 
0.0  28SEP2016 9 2016 
0.0  29SEP2016 9 2016 
0.0  30SEP2016 9 2016 
; 
run; 

/* replace zeros with missing */ 
data have; 
modify have; 
call missing(value); 
where value=0; 
run; 

/* replace missing with mean of month */ 
proc stdize data=have out=want 
      method=mean reponly; 
by month year; 
var value; 
run; 
0

您可以使用proc sql生成一個新的結果集:

proc sql; 
    select (case when t.value = 0 then t2.avg_value else value end) as value, 
      t.date, t.month, t.year 
    from t left join 
     (select year, month, avg(value) as avg_value 
      from t 
      group by year, month 
     ) t2 
     on t.year = t2.year and t.month = t2.month; 

如果你想短語以此爲update,然後我會用一個相關子查詢:

proc sql; 
    update t 
     set value = (select avg(t2.value) 
        from t t2 
        where t2.value <> 0 and 
          t2.year = t.year and t2.month = t.month 
        ) 
     where value = 0; 
+0

我相信你需要給子查詢添加一個where子句,以便它在平均值計算中不包括零(這個問題並不完全清楚,但是包含它們沒有多大意義)。另外,由於您無法引用子查詢 – Longfish

+0

@Longfish中正在更新的表,因此您的更新語句不起作用。 。 。我現在沒有SAS現在正在測試。它真的有這個限制嗎?據我所知,唯一有此限制的數據庫是MySQL。 –

+0

是的!錯誤消息表示您無法重新打開更新訪問表,因爲它已被使用。這表明它首先運行子查詢(這是有道理的),但保持表打開,因此阻止更新 – Longfish