好吧这看起来很简单,但是我无法解释sas datastep中的“by statement”是什么。我知道什么时候需要使用它,但我不确定它在做什么。
在下面的示例中,我了解first.var和last.var的虚拟sas列是什么时候它具有的值。是否在var initial和metal周围创建了这些虚拟列的by语句?然后sas扫描整个数据集一次?
data jewelers ;
input id initial $ metal $ ;
datalines;
456 D Gold
456 D Silver
123 L Gold
123 L Copper
123 L PLatinum
567 R Gold
567 R Gold
567 R Gold
345 A Platinum
345 A Silver
345 A Silver
;
proc sort ;
by initial metal ;
run;
data dups;
set jewelers ;
by initial metal ;
if not (first.metal and last.metal) then output;
run;
如果我推销打印件,我希望如此:
567 R Gold
567 R Gold
567 R Gold
345 A Silver
345 A Silver
答案 0 :(得分:2)
正如您所承认的那样,SAS正在为first.byvar
声明中的每个last.byvar
创建自动变量byvar
和by
。从SAS set
语句读入的记录在SAS移动到PDV之前保存在缓冲区中(程序数据向量 - 在输出之前在每一行上执行数据步骤逻辑),因此SAS可以向前看缓冲区中的下一条记录,以查看是否有任何更改的byvars,并为当前PDV中的行设置last.byvar = 1
。
我在你所说的你所期望的内容和你在dups数据集中得到的内容之间的唯一区别是记录的顺序 - 因为你已经按照首字母排序,然后是金属,A Silver
记录在R Gold
条记录之前排序。
如果要在保留原始行顺序的同时获取这两个变量的重复项,则需要记下原始记录顺序,并在第二个数据后将重复数据集重新排序到该顺序中步骤
答案 1 :(得分:0)
SAS基本上将当前记录与之前的记录进行比较,然后计算FIRST。最后。标志。如果你愿意,你可以自己动手。
data test ;
set jewelers end=eof;
by initial metal ;
if not eof then
set jewelers (firstobs=2 keep=initial metal
rename=(initial=next_initial metal=next_metal))
;
first_initial = (_n_=1) or (initial ne lag(initial));
last_initial = eof or (initial ne next_initial) ;
first_metal = first_initial or (metal ne lag(metal)) ;
last_metal = last_initial or (metal ne next_metal);
put / (initial metal) (=);
put (first:) (=);
put (last:) (=);
run;