Arrays SAS数据更新/操作
我对SAS编程比较陌生,但在过去的几个月里,我一直在学习基础知识,它满足了我的需要。然而,我目前有困难,希望得到一些帮助。我正在尝试更新一个数据库,并创建两个新变量,这将有助于跟踪更新。因此,我用下表简化了我的问题: 源表Arrays SAS数据更新/操作,arrays,sas,data-manipulation,proc-sql,Arrays,Sas,Data Manipulation,Proc Sql,我对SAS编程比较陌生,但在过去的几个月里,我一直在学习基础知识,它满足了我的需要。然而,我目前有困难,希望得到一些帮助。我正在尝试更新一个数据库,并创建两个新变量,这将有助于跟踪更新。因此,我用下表简化了我的问题: 源表 ID Record_ID Correction_ID 0001 A001 0002 A002 0003 A003 A001 0004 A004 A002 0005 A005 000
ID Record_ID Correction_ID
0001 A001
0002 A002
0003 A003 A001
0004 A004 A002
0005 A005
0006 A006 A004
目标表
ID Record_ID Correction_ID Original_Record Count
0001 A001 A001 0
0002 A002 A002 0
0003 A003 A001 A001 1
0004 A004 A002 A002 1
0005 A005 A005 0
0006 A006 A004 A002 2
Correction_ID表示当前记录正试图更正/修改的记录
计数表示原始记录上的更新编号
谢谢
编辑
我尝试过但不起作用的Proc SQL代码:
ID Record_ID Correction_ID Original_Record Count
Table 1
0001 A001 A001 0
0002 A002 A002 0
0005 A005 A005 0
Table 2
0003 A003 A001
0004 A004 A002
0006 A006 A004
SELECT ID,
Record_ID, *how to include ID from both table? Or don’t even separate?
Correction_ID, *same as above
CASE
WHEN Correction_ID is null THEN One.Original_Record
ELSE (SELECT Original_Record FROM One WHERE Two.Correction_ID=One.Record_ID)
END as Original_Record,
CASE
WHEN Count is not null THEN One.Count
ELSE (SELECT Count FROM One WHERE Two.Correction_ID=One.Record_ID) + 1
END as Count;
FROM Table 1 AS One, Table 2 AS Two;
下面的代码似乎适用于您的数据。它利用散列对象,其中“原始记录”被保留,而“计数”被相加。一些元素现在可能是多余的(“u start”可能不需要)
下面的代码似乎适用于您的数据。它利用散列对象,其中“原始记录”被保留,而“计数”被相加。一些元素现在可能是多余的(“u start”可能不需要)
如果您有SAS/OR许可证,那么此代码的作用大致相同,但更简单,因为PROC OPTMODEL数组是散列。它确实将所有数据加载到RAM中,因此简单性的代价是内存消耗 我将重用Haikoo的数据集:
data have;
infile cards truncover;
input (ID Record_ID Correction_ID) (:$8.);
cards;
0001 A001
0002 A002
0003 A003 A001
0004 A004 A002
0005 A005
0006 A006 A004
0007 A007
0008 A008 A006
0009 A009 A003
;
我不认为我们真的需要ID
,所以我忽略了它,以使代码更具说明性。它不在内部使用,但如果需要,可以将其添加到读取数据
和创建数据
语句中
proc optmodel;
set<str,str> RECORDS;
set ALL = setof{<i,j> in RECORDS} i;
str parent {ALL diff {<i,('')> in RECORDS}};
str original{i in ALL} init i;
num count { ALL} init 0;
read data have into RECORDS=[Record_Id Correction_ID];
for {<ri,rj> in RECORDS: rj ~= ''} do;
parent [ri] = rj;
count [ri] = count [parent[ri]] + 1;
original[ri] = original[parent[ri]];
end;
create data want from [Record_ID Correction_ID]=RECORDS
Original_Record = original[Record_ID] Count = count[Record_ID];
quit;
proc-optmodel;
创纪录,;
set ALL=setof{in RECORDS}i;
str父项{ALL diff{in RECORDS}};
str原始{i全部}init i;
num count{ALL}init 0;
将数据读入记录=[Record_Id Correction_Id];
对于{in记录:rj~=''}do;
父[ri]=rj;
计数[ri]=计数[parent[ri]]+1;
原始[ri]=原始[parent[ri]];
结束;
从[Record\u ID Correction\u ID]=记录创建所需数据
原始记录=原始[记录ID]计数=计数[记录ID];
退出
如果您有SAS/或许可证,那么此代码的作用大致相同,但更简单,因为PROC OPTMODEL数组是散列。它确实将所有数据加载到RAM中,因此简单性的代价是内存消耗
我将重用Haikoo的数据集:
data have;
infile cards truncover;
input (ID Record_ID Correction_ID) (:$8.);
cards;
0001 A001
0002 A002
0003 A003 A001
0004 A004 A002
0005 A005
0006 A006 A004
0007 A007
0008 A008 A006
0009 A009 A003
;
我不认为我们真的需要ID
,所以我忽略了它,以使代码更具说明性。它不在内部使用,但如果需要,可以将其添加到读取数据
和创建数据
语句中
proc optmodel;
set<str,str> RECORDS;
set ALL = setof{<i,j> in RECORDS} i;
str parent {ALL diff {<i,('')> in RECORDS}};
str original{i in ALL} init i;
num count { ALL} init 0;
read data have into RECORDS=[Record_Id Correction_ID];
for {<ri,rj> in RECORDS: rj ~= ''} do;
parent [ri] = rj;
count [ri] = count [parent[ri]] + 1;
original[ri] = original[parent[ri]];
end;
create data want from [Record_ID Correction_ID]=RECORDS
Original_Record = original[Record_ID] Count = count[Record_ID];
quit;
proc-optmodel;
创纪录,;
set ALL=setof{in RECORDS}i;
str父项{ALL diff{in RECORDS}};
str原始{i全部}init i;
num count{ALL}init 0;
将数据读入记录=[Record_Id Correction_Id];
对于{in记录:rj~=''}do;
父[ri]=rj;
计数[ri]=计数[parent[ri]]+1;
原始[ri]=原始[parent[ri]];
结束;
从[Record\u ID Correction\u ID]=记录创建所需数据
原始记录=原始[记录ID]计数=计数[记录ID];
退出
您尝试添加这些变量的步骤是什么?结果是什么?请发布您在问题中编写的代码。@Joe我尝试过使用proc SQL,但没有成功。我咨询了一位同事,他们告诉我使用三个临时数组作为记录ID、原始记录、计数和迭代。但鉴于我目前的知识,我认为我做不到这一点。从那以后,我一直在玩动态宏,我想我可能有一个粗略的解决方案。涉及大量重命名、排序、合并等,似乎效率不够。也许这就是我的同事建议使用临时数组的原因。您尝试添加这些变量的步骤是什么?结果是什么?请在问题中发布您迄今为止编写的代码。@Joe我尝试过使用proc SQL,但它不起作用。我咨询了一位同事,他们告诉我使用三个临时数组作为记录ID、原始记录、计数和迭代。但鉴于我目前的知识,我认为我做不到这一点。从那以后,我一直在玩动态宏,我想我可能有一个粗略的解决方案。涉及大量重命名、排序、合并等,似乎效率不够。也许这就是我的同事建议使用临时阵列的原因。谢谢。我已经采用了解决我问题的办法。你能告诉我这个“如果rc ne 0那么做;_origin=correction\u id;count=1;end;”试图编码的是什么吗?或者,如果可能的话,也可以对代码的其余部分提供一些注释?刚刚添加了一些注释。谢谢,所以rc=h.find(key:correction\u id);检查更正id是否在散列对象中,第一次基本上将所有内容设置为count=1,随后每次更正id出现在由_origin或_end?定义的散列中时,计数均为+1,这是正确的,但不仅仅是检查,如果存在匹配项,它还会返回。因此,请确保您理解为什么这里使用Find方法而不是Check方法。感谢您的帮助,我将阅读更多有关SAS中哈希的内容,以确认我的理解。谢谢。我已经采用了解决我问题的办法。你能告诉我这个“如果rc ne 0那么做;_origin=correction\u id;count=1;end;”试图编码的是什么吗?或者,如果可能的话,也可以对代码的其余部分提供一些注释?刚刚添加了一些注释。谢谢,所以rc=h.find(key:correction\u id);检查更正id是否在散列对象中,第一次基本上将所有内容设置为count=1,随后每次更正id出现在由_origin或_end?定义的散列中时,计数均为+1,这是正确的,但不仅仅是检查,如果存在匹配项,它还会返回。因此,请确保您理解为什么使用Find方法而不是Check方法