SAS:用冲突标记下一个和以前的观察结果
SAS: Marking next and previous observations with conflicts
我想在 SAS 中创建虚拟对象。我的计划是,每次 AnnouncementDate ne 。我想创建一个名为 event=2 的变量,下一个变量 (event=2) 以及之前的五个观察结果 1
如果前 5 次观察和公告日期后的第二天不为空,则所有这些都会被标记。
在 class 中(例如按库存)
输出数据
date announcementdate event conflict
1115 . . .
2115 . . .
3115 . . .
4115 . . .
5115 . . .
6115 . 1 .
7115 . 1 .
8115 . 1 .
9115 . 1 .
10115 . 1 .
11115 1115 2 .
12115 . 2 .
13115 . .
14115 . 1 .
16115 . 1 .
17115 . 1 .
18115 . 1 .
19115 . 1 .
20115 20115 2
21115 . 1 Y
21115 . 1 Y
22115 22115 2 Y
23115 . 2 Y
24115 . .
25115 . .
如果现在切换到下一只股票,它应该重新开始并且不考虑之前的观察结果。
我当前的代码有一个前导项,因为我仅将事件列与 firstobs=2 合并。无论如何,这 5 倍的延迟困扰着我,以及之前有观察时的冲突。
data want1 ; set have;;
if announcementdate ne . then event=0;
run;
data want2; merge want1 (firstobs=2) want1 (keep=event rename= (event=event2));
if event2=0 then event=0;
if event2=0 then event=event2;
run;
感谢任何意见!
我的方法是首先解析数据集以计算出范围,使用 _n_
作为指标(而不是 id)。然后您可以构建一个简单的开始-结束范围并使用它来构建格式(好吧,两个,一个用于 1,一个用于 2)。
然后,使用前瞻合并解析那个数据集(以获取下一个开始值)并查看是否存在冲突;然后使用您的逻辑为冲突标记定义另一种格式。我的例子包括这个逻辑;它可能会或可能不会满足您的确切需求,因此您可能需要更多地考虑这个逻辑并修改它一些,因为它非常具体。
然后您只需应用使用 _n_
作为输入的格式。当然,请确保原始数据集未排序。
这是完整的代码。
data have;
input date announcementdate event_want conflict_want $;
datalines;
1115 . . .
2115 . . .
3115 . . .
4115 . . .
5115 . . .
6115 . 1 .
7115 . 1 .
8115 . 1 .
9115 . 1 .
10115 . 1 .
11115 1115 2 .
12115 . 2 .
13115 . . .
14115 . 1 .
16115 . 1 .
17115 . 1 .
18115 . 1 .
19115 . 1 .
20115 20115 2 .
21115 . 1 Y
21115 . 1 Y
22115 22115 2 Y
23115 . 2 Y
24115 . . .
25115 . . .
;;;;
run;
data for_fmt;
set have nobs=nobs;
length fmtname ;
fmtname = 'eventf';
if _n_=1 then do; *HLO='o' gives the 'other' value;
start=.;
end =.;
label = ' ';
hlo='o';
output;
end;
hlo=' ';
if not missing(announcementdate) then do;
start = max(1,_n_-5);
end = max(1,_n_-1);
label='1';
output;
start = _n_;
end = min(_n_+1,nobs);
label='2';
output;
end;
run; *now we have a dataset of the ranges - but they overlap;
data for_fmt_conflicts;
merge for_fmt(in=a) for_fmt(in=_in_next firstobs=2 keep=start rename=start=next_start); *look-ahead merge;
retain new_start conflict_marker;
if hlo='o' then do; *again the 'other' row;
output;
fmtname='conflictf';
output;
end;
else if end gt next_start and (_in_next) then do; *if the next row will be a conflict, adjust the end back one and indicate where next should start;
end = end-1;
new_start = end+1;
conflict_marker=1;
output;
end;
else if conflict_marker=1 then do; *if this is a conflict row type 1;
start = new_start;
output;
fmtname='conflictf';
label ='Y';
output;
conflict_marker=2;
end;
else if conflict_marker=2 then do; *if this is the 2s for a conflict row;
output;
fmtname='conflictf';
label ='Y';
output;
conflict_marker=0;
end;
else output;
run;
proc sort data=for_fmt_conflicts; *must sort to get fmtnames grouped together;
by fmtname start;
run;
proc format cntlin=for_fmt_conflicts; *import formats;
quit;
data want; *now apply formats;
set have;
event = put(_n_,eventf.);
conflict = put(_n_,conflictf.);
run;
我想在 SAS 中创建虚拟对象。我的计划是,每次 AnnouncementDate ne 。我想创建一个名为 event=2 的变量,下一个变量 (event=2) 以及之前的五个观察结果 1 如果前 5 次观察和公告日期后的第二天不为空,则所有这些都会被标记。 在 class 中(例如按库存)
输出数据
date announcementdate event conflict
1115 . . .
2115 . . .
3115 . . .
4115 . . .
5115 . . .
6115 . 1 .
7115 . 1 .
8115 . 1 .
9115 . 1 .
10115 . 1 .
11115 1115 2 .
12115 . 2 .
13115 . .
14115 . 1 .
16115 . 1 .
17115 . 1 .
18115 . 1 .
19115 . 1 .
20115 20115 2
21115 . 1 Y
21115 . 1 Y
22115 22115 2 Y
23115 . 2 Y
24115 . .
25115 . .
如果现在切换到下一只股票,它应该重新开始并且不考虑之前的观察结果。
我当前的代码有一个前导项,因为我仅将事件列与 firstobs=2 合并。无论如何,这 5 倍的延迟困扰着我,以及之前有观察时的冲突。
data want1 ; set have;;
if announcementdate ne . then event=0;
run;
data want2; merge want1 (firstobs=2) want1 (keep=event rename= (event=event2));
if event2=0 then event=0;
if event2=0 then event=event2;
run;
感谢任何意见!
我的方法是首先解析数据集以计算出范围,使用 _n_
作为指标(而不是 id)。然后您可以构建一个简单的开始-结束范围并使用它来构建格式(好吧,两个,一个用于 1,一个用于 2)。
然后,使用前瞻合并解析那个数据集(以获取下一个开始值)并查看是否存在冲突;然后使用您的逻辑为冲突标记定义另一种格式。我的例子包括这个逻辑;它可能会或可能不会满足您的确切需求,因此您可能需要更多地考虑这个逻辑并修改它一些,因为它非常具体。
然后您只需应用使用 _n_
作为输入的格式。当然,请确保原始数据集未排序。
这是完整的代码。
data have;
input date announcementdate event_want conflict_want $;
datalines;
1115 . . .
2115 . . .
3115 . . .
4115 . . .
5115 . . .
6115 . 1 .
7115 . 1 .
8115 . 1 .
9115 . 1 .
10115 . 1 .
11115 1115 2 .
12115 . 2 .
13115 . . .
14115 . 1 .
16115 . 1 .
17115 . 1 .
18115 . 1 .
19115 . 1 .
20115 20115 2 .
21115 . 1 Y
21115 . 1 Y
22115 22115 2 Y
23115 . 2 Y
24115 . . .
25115 . . .
;;;;
run;
data for_fmt;
set have nobs=nobs;
length fmtname ;
fmtname = 'eventf';
if _n_=1 then do; *HLO='o' gives the 'other' value;
start=.;
end =.;
label = ' ';
hlo='o';
output;
end;
hlo=' ';
if not missing(announcementdate) then do;
start = max(1,_n_-5);
end = max(1,_n_-1);
label='1';
output;
start = _n_;
end = min(_n_+1,nobs);
label='2';
output;
end;
run; *now we have a dataset of the ranges - but they overlap;
data for_fmt_conflicts;
merge for_fmt(in=a) for_fmt(in=_in_next firstobs=2 keep=start rename=start=next_start); *look-ahead merge;
retain new_start conflict_marker;
if hlo='o' then do; *again the 'other' row;
output;
fmtname='conflictf';
output;
end;
else if end gt next_start and (_in_next) then do; *if the next row will be a conflict, adjust the end back one and indicate where next should start;
end = end-1;
new_start = end+1;
conflict_marker=1;
output;
end;
else if conflict_marker=1 then do; *if this is a conflict row type 1;
start = new_start;
output;
fmtname='conflictf';
label ='Y';
output;
conflict_marker=2;
end;
else if conflict_marker=2 then do; *if this is the 2s for a conflict row;
output;
fmtname='conflictf';
label ='Y';
output;
conflict_marker=0;
end;
else output;
run;
proc sort data=for_fmt_conflicts; *must sort to get fmtnames grouped together;
by fmtname start;
run;
proc format cntlin=for_fmt_conflicts; *import formats;
quit;
data want; *now apply formats;
set have;
event = put(_n_,eventf.);
conflict = put(_n_,conflictf.);
run;