我是SAS EG的新手,我想知道如何根据SAS EG中的三列值通过循环附加数字。 例如。
Column0 Column1 Column2 Level (desired result)
1A AA 0
1A 123AA AA 1
1A 234AA 123AA 2
2B BB 0
2B 123BB BB 1
2B 234BB BB 1
2B 345BB 123BB 2
2B 456BB 345BB 3
我只有一个数据集,column0到column2由一个proc sql生成。唯一缺少的是根据column0和column2的值来确定column1的级别。
答案 0 :(得分:0)
SQL不知道存储在磁盘上的行的顺序,并且您的数据没有附加列用于指示SORTED BY的值。
DATA步骤提供了一种更简单的方法,其中行的顺序是“读取”。由column1键控的哈希对象可以保持先前行的level值,而column2可以用作查找的键值。
例如:
data have;
infile datalines missover;
input
Column0 $ Column1 $ Column2 $; datalines;
1A AA
1A 123AA AA
1A 234AA 123AA
2B BB
2B 123BB BB
2B 234BB BB
2B 345BB 123BB
2B 456BB 345BB
run;
data want;
set have;
by column0;
if _n_ = 1 then do;
declare hash lookup();
lookup.defineKey('column1');
lookup.defineData('level');
lookup.defineDone();
end;
if first.column0 then
lookup.Clear();
if (lookup.find(key:column2) ne 0) then
level = 0;
else
level + 1;
lookup.add();
run;
注意:以上方法可能需要进行调整才能在VIYA中工作。
在SQL中执行相同操作需要多个步骤。为适当的孩子计算(或发现)每个级别的一个步骤。
proc sql;
create table level0 as
select child.*, 0 as level from have as child
where child.column2 is null;
%put &=SQLOBS;
create table level1 as
select child.*, 1 as level from level0 as parent join have as child
on parent.column0 = child.column0 and child.column2 = parent.column1;
%put &=SQLOBS;
create table level2 as
select child.*, 2 as level from level1 as parent join have as child
on parent.column0 = child.column0 and child.column2 = parent.column1;
%put &=SQLOBS;
create table level3 as
select child.*, 3 as level from level2 as parent join have as child
on parent.column0 = child.column0 and child.column2 = parent.column1;
%put &=SQLOBS;
create table level4 as
select child.*, 4 as level from level3 as parent join have as child
on parent.column0 = child.column0 and child.column2 = parent.column1;
%put &=SQLOBS; * 0 obs, so no more children needing parentage found;
create table want as
select * from level0 union
select * from level1 union
select * from level2 union
select * from level3
order by column0, level
;
一种通用方法必须循环执行,直到SQLOBS
为0
create table level&LOOPINDEX as
select child.*, &LOOPINDEX as level
from level&LOOPINDEX_MINUS_1 as parent
join have as child
on parent.column0 = child.column0 and child.column2 = parent.column1;