我有以下数据集:我正在尝试根据可用日期为计划和非计划访问分配访问号码。如果日期不同,那么我想增加计划外访问号码(即:101.1, 101.2)。但如果计划外访问的日期相同,那么我希望保持行数不变的访问次数(即2次或更多次计划外访问,访问次数相同,即101.1,101.1)。
data test;
infile cards dlm=" ";
input subject visit event$11. date:date9.;
format date date9.;
cards;
1 1 screening 10oct2017
1 1 screening 10oct2017
1 99 unscheduled 10oct2017
1 99 unscheduled 11oct2017
1 2 day-1 12oct2017
1 2 day-1 12oct2017
1 3 day1 16oct2017
1 99 unscheduled 15oct2017
;
run;
我想将avisitn分配如下:
1 1 screening 10oct2017 101
1 1 screening 10oct2017 101
1 99 unscheduled 10oct2017 101.1
1 99 unscheduled 11oct2017 101.2
1 2 day-1 12oct2017 102
1 2 day-1 12oct2017 102
1 3 day1 16oct2017 103
1 99 unscheduled 15oct2017 103.1
我尝试使用以下代码:
data test;
infile cards dlm=" ";
input subject visit event$11. date:date9.;
format date date9.;
cards;
1 1 screening 10oct2017
1 1 screening 10oct2017
1 99 unscheduled 10oct2017
1 99 unscheduled 11oct2017
1 2 day-1 12oct2017
1 2 day-1 12oct2017
1 3 day1 16oct2017
1 99 unscheduled 15oct2017
;
run;
proc sort data=test;
by subject date visit;
run;
data test1;
set test;
by subject date visit;
fp = first.subject;
lp = last.subject;
fo = first.date;
lo = last.date;
run;
data test2;
set test1;
by subject date visit;
retain avisitn;
prev_patient_num = lag(subject);
prev_ordering_date = lag(date);
if visit ne 99 then do;
if first.subject then avisitn = 101;
else if subject = prev_patient_num and date ne prev_ordering_date then avisitn + 1;
end;
if visit eq 99 then do;
avisitn+0.1;
end;
keep subject date visit avisitn;
run;
但是,我得到以下输出
subject visit date avisitn
1 1 10OCT2017 101
1 1 10OCT2017 101
1 99 10OCT2017 101.1
1 99 11OCT2017 101.2
1 2 12OCT2017 102.2
1 2 12OCT2017 102.2
1 99 15OCT2017 102.3
1 3 16OCT2017 103.3
请帮我解决这个问题。提前谢谢。
答案 0 :(得分:1)
在您的尝试中,您按主题和日期排序。但是,在原始样本中,最后两行在日期中是无序的。最后两个想要的值(103和103.1)基于未排序的数据。
对于排序数据,您可以在日期更改之前使用FLOOR,然后再前进1。跟踪太多.1增量是一个好主意。
data want;
set test;
by subject date;
retain avisitn;
prev_date = lag(date);
if first.subject then do;
avisitn = 101;
_99s = 0;
if visit eq 99 then do; _99s + 1; avisitn + 0.1; end;
end;
else
if visit eq 99 then do;
_99s + 1;
if _99s = 10 then do; put 'ERROR: Too many 99s' ; abort cancel; end;
avisitn + 0.1;
end;
else
if date ne prev_date then
avisitn = floor(avisitn) + 1;
drop prev_date;
run;
如果你需要按照原始顺序进行处理,比如在事务性事件记录顺序中,有解决方案,但是它们可能不是“光滑的”,并且需要跟踪“怪异”排序情况的状态。