假设我们有以下数据集
obs check result
---------------------
aa 0 0
bb 0 0
cc 1 0
dd 0 0
ee 1 1
ff 1 1 <- we are here. Due to prev. value both eq 1 the "result" variable for both of them should also be 1
我需要的是检查连续“check”变量中的2个或更多个案例是否等于1,如果是这样,那么两个“result”变量也应该是1.问题是唯一的方法我看到将“result”设置为1,因为它们都以某种方式返回到之前的“观察行”并将“result”变量更改为1。
答案 0 :(得分:3)
由于数据步骤循环的设计方式,我认为我们不能轻易回到之前的观察。但是,我们可以使用retain
语句和merge
数据集与自己without
和by
语句来访问上一个或下一个观察结果:
data work.sample;
input obs $ check result;
retain x;
output;
x = check;
datalines;
aa 0 0
bb 0 0
cc 1 0
dd 0 0
ee 1 0
ff 1 0
;
run;
data work.sample2;
merge work.sample
work.sample(firstobs = 2 keep = check
rename = (check = c));
if (check = 1 and x = 1) or (check = 1 and c = 1) then result = 1;
run;
OUTPUT看起来像这样:
Obs obs check result x c
1 aa 0 0 . 0
2 bb 0 0 0 1
3 cc 1 0 0 0
4 dd 0 0 1 1
5 ee 1 1 0 1
6 ff 1 1 1 .
因此,变量x表示使用retain
语句和output
语句保留的值。变量c表示我们在观察= 2时将数据集与自身合并时创建的变量。
最后,如果连续出现check = 1,我们会使用条件语句将新值放入结果变量。
答案 1 :(得分:2)
Yick的答案是一种非常好的通用方法,但这个具体问题有一个有趣,简单的答案。
SAS有一种方法可以向前看,而不必以某种方式第二次读取数据:使用LAST.<variable>
语句创建的BY
自动变量。这些涉及SAS的自动前瞻,而不会强迫您手动完成。感谢NOTSORTED
,这可以让您查看下一个值是否恰好等于变量的当前值。
使用Yick的数据集:
data work.sample;
input obs $ check result;
retain x;
output;
x = check;
datalines;
aa 0 0
bb 0 0
cc 1 0
dd 0 0
ee 1 0
ff 1 0
;
run;
data want;
set sample;
by check notsorted;
if not (first.check and last.check) and (check=1) then result=1;
*if it is not the first record AND the last record with the same check value in a row,
then it is one of a sequence of two or more and if check=1 then result should be 1;
put _all_;
run;