Arrays 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

我对SAS编程比较陌生,但在过去的几个月里,我一直在学习基础知识,它满足了我的需要。然而,我目前有困难,希望得到一些帮助。我正在尝试更新一个数据库,并创建两个新变量,这将有助于跟踪更新。因此,我用下表简化了我的问题:

源表

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方法