2017-11-28 40 views
0

UserとID_optionでグループ分けされた最後の3時間の使用(データセット内のカラムの1つ)をすべての行で検索する必要があります。 すべての行(行)は1レコード(3分の時間間隔内)を表します。 (所望の列sum_usage_3hrを含む)、例えば:SASベース内の無効なDOループ制御情報

User ID_option   time    usage  sum_usage_3hr 
1   a1  12OCT2017:11:20:32  3    10 
1   a1  12OCT2017:10:23:24  7    14 
1   b1  12OCT2017:09:34:55  12   12 
2   b1  12OCT2017:08:55:06  4    6 
1   a1  12OCT2017:07:59:53  7    7 
2   b1  12OCT2017:06:59:12  2    2 

Iは、ハッシュテーブルについては、以下のコードを使用している:

data want; 
if _n_=1 then do; 
    if 0 then set have(rename=(usage=_usage)); 
    declare hash h(dataset:'have(rename=(usage=_usage))',hashexp:20); 
    h.definekey('user','id_option','time'); 
    h.definedata('_usage'); 
    h.definedone(); 
end; 
set have; 
sum_usage_3hr=0; 
do i=time-3*3600 to time ; 
if h.find(key:user,key:id_option,key:i)=0 then sum_usage_3hr+_usage; 
end; 
drop _usage i; 
run; 

しかし、私はエラー得た:INITIAL又は発現するか無効DOループ制御情報を、 BY式が欠落しているか、ゼロまたは無効です。私が追加した場合: 出力; end: 「実行」のすぐ上にあります。 'No DO/Select statement'と一致していません。 問題の原因は誰でも知っていますか? 私はテーブルを最初にソートするバージョンも持っていて、同じエラーが出ます。 は答えを実装した後、あなた

ありがとう:

User ID_option   time    usage sum_usage_3hr col_i_got 
1   a1  12OCT2017:11:22:32  3   12    3  
1   a1  12OCT2017:11:20:24  0   9    3 
1   a1  12OCT2017:10:34:55  2   9    2 
1   a1  12OCT2017:09:55:06  0   7    2 
1   a1  12OCT2017:09:43:45  0   7    0 
1   a1  12OCT2017:08:59:53  7   7    7 
1   a1  12OCT2017:06:59:12  0   0    7 
+0

時間変数は数値または文字列として保存されていますか? – user2877959

+0

@ user2877959これは、日時形式で保存されます。 – jovicbg

+0

私の質問には答えられていません。 SASには、数値と文字の2種類しかありません。どちらですか? _ "はフォーマット日時に格納されています" _はSASでは何も意味しません。 datetime形式が適用された数値として格納されているか、またはdatetime形式の値の文字表現として格納されていることを意味すると解釈することができます。数値として格納されている場合、doループは正常です。文字として格納されている場合、doループは明らかに無効であり(文字列から数値を減算する)、そのエラーメッセージはその場合に得られるものです。 – user2877959

答えて

1

これを試してみてください:

問題1:

入力:

data have; 
input User ID_option $  time   usage ; 
informat time datetime18.; 
format time datetime18.; 
cards; 
1   a1  12OCT2017:11:20:32  3 
1   a1  12OCT2017:10:23:24  7 
1   b1  12OCT2017:09:34:55  12 
2   b1  12OCT2017:08:55:06  4 
1   a1  12OCT2017:07:59:53  7 
2   b1  12OCT2017:06:59:12  2 
; 
run; 

コード:

proc sort data=have out=have1; 
by user id_option time; 
quit; 

data have2; 
set have1; 
by user id_option; 
format previous_time datetime18.; 
previous_time = lag(time); 
previous_usage = lag(usage); 
if first.ID_option then previous_time=.; 
if previous_time ~= . and intnx("hour",time,-3,"s") <= previous_time <= time then sum_usage_3hr=usage+previous_usage; 
else sum_usage_3hr = usage; 
drop previous_time previous_usage; 
run; 

proc sort data=have2 out=want; 
by descending time ; 
quit; 

出力:

User ID_option time usage sum_usage_3hr 
    1 a1 12Oct2017 11:20:32 3 10 
    1 a1 12Oct2017 10:23:24 7 14 
    1 b1 12Oct2017 9:34:55 12 12 
    2 b1 12Oct2017 8:55:06 4 6 
    1 a1 12Oct2017 7:59:53 7 7 
    2 b1 12Oct2017 6:59:12 2 2 

Problem2:

入力:

data have; 
input user1 ID_option $  time   usage ; 
informat time datetime18.; 
format time datetime18.; 
cards; 
1   a1  12OCT2017:11:22:32  3 
1   a1  12OCT2017:11:20:24  0 
1   a1  12OCT2017:10:34:55  2 
1   a1  12OCT2017:09:55:06  0 
1   a1  12OCT2017:09:43:45  0 
1   a1  12OCT2017:08:59:53  7 
1   a1  12OCT2017:06:59:12  0 
; 
run; 

コード:

proc sql; 
create table want as 
select user1,id_option,time,min(usage) as usage,sum(usage1) as sum_usage_3hr 
from 
(
select a.*,b.time as time1 ,b.usage as usage1 
from 
have a 
left join 
have b 
on a.user1 = b.user1 and a.id_option = b.id_option and b.time <= a.time 
where intck("hour",a.time ,b.time) >= -3 
) 
group by 1,2,3 
order by time desc; 
quit; 

出力:

user1 ID_option time usage sum_usage_3hr 
1 a1 12Oct2017 11:22:32 3 12 
1 a1 12Oct2017 11:20:24 0 9 
1 a1 12Oct2017 10:34:55 2 9 
1 a1 12Oct2017 9:55:06 0 7 
1 a1 12Oct2017 9:43:45 0 7 
1 a1 12Oct2017 8:59:53 7 7 
1 a1 12Oct2017 6:59:12 0 0 

私は任意のクエリの場合に知らせてください。

+0

出力はサンプルでは良いですが、実際のデータでは、使用量が0の行がたくさんあるため、実際のデータではありません。行の下の行以外の使用が0の行はコードで計算されません。私はあなたの出力のサンプルを見ることができるように私の質問を編集します。 – jovicbg

+0

私のQを編集しました – jovicbg

+0

あなたのコードを(両方のクエリに対して)実行すると、そのようなエラーは発生せず、完全に動作します!! –