Macros SAS-将一个观测值读入另一个观测值

Macros SAS-将一个观测值读入另一个观测值,macros,sas,Macros,Sas,我正在使用SAS,我正在尝试将一个观察值从以前的观察值读入当前的观察值 下面是数据的样子 Obs URN Description Error_Bucket inputAcctNumber count 1 010001234567 Base Invalid Name AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 1 2 010001234567 No Error No Error 0

我正在使用SAS,我正在尝试将一个观察值从以前的观察值读入当前的观察值

下面是数据的样子

Obs URN       Description Error_Bucket inputAcctNumber             count 
1 010001234567 Base      Invalid Name  AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 1 
2 010001234567 No Error  No Error          0                          2 
3 010007891023 No Error  No Error      BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB 1 
4 010007891023 A2/J2     Invalid Name      0                          2 
5 010004567890 No Error  No Error      CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 1 
6 010004567890 A2/J2     Invalid Name      0                          2 
7 010001354321 No Error  No Error      DDDDDDDDDDDDDDDDDDDDDDDDDDDDDD 1 
我已经创建了Count字段,在这个示例中,只有两个观测值具有相同的URN,但是将来可能会有3-N个观测值具有相同的URN编号。我要做的是,给所有这些观察结果提供相同的输入编号,它们具有相同的URN编号,但现在它们都是0。我如何才能做到这一点,尤其是当urn的“计数”数不明确时

理想情况下,我希望我的数据是这样的:

    Obs URN       Description Error_Bucket inputAcctNumber             count 
1 010001234567 Base      Invalid Name  AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 1 
2 010001234567 No Error  No Error      AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 2 
3 010007891023 No Error  No Error      BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB 1 
4 010007891023 A2/J2     Invalid Name  BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB 2 
5 010004567890 No Error  No Error      CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 1 
6 010004567890 A2/J2     Invalid Name  CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2 
7 010001354321 No Error  No Error      DDDDDDDDDDDDDDDDDDDDDDDDDDDDDD 1 

我想出了一种方法来实现您的要求,使用PROC-SQL。为此,我创建了4个不同的表,最后一个是您想要的表。这可能不是您执行此操作的最有效方式,但您比我更了解您的数据

代码:

数据集“e”的proc打印输出:

Obs URN Description Error_Bucket inputAcctNumber count 
1 10001234567 No Error No Error  AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 2 
2 10001234567 Base Invalid Name  AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 1 
3 10001354321 No Error No Error  DDDDDDDDDDDDDDDDDDDDDDDDDDDDDD 1 
4 10004567890 No Error No Error  CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 1 
5 10004567890 A2/J2 Invalid Name CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2 
6 10007891023 A2/J2 Invalid Name BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB 2 
7 10007891023 No Error No Error  BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB 1 
详细说明:

(1) 我制作了一个“count”等于1的行表。 (2) 我制作了另一个表,其中“count”不等于1。 (3) 然后,我将(2)中生成的表与(1)中生成的表进行了内部联接,并使用(1)中生成的表中的“inputAcctNumber”代替(2)中生成的表。 (4) 然后,我将(3)中的表格附加到(1)中的表格,然后按“URN”排序


希望这会有所帮助。

一个简单的方法就是将inputAcctNumber变量合并回数据中

data want ;
  merge have (drop=inputAcctNumber )
        have (keep=URN inputAcctNumber where=(inputAcctNumber ne '0'))
  ;
  by URN;
run;
如果第一条记录始终具有正确的编号,则可以创建一个新变量并保留该值

data want;
  set have ;
  by urn count ;
  if first.urn then new=inputAcctNumber;
  retain new;
  drop inputAcctNumber;
  rename new=inputAcctNumber;
run;

您可以使用
retain
语句让SAS在数据步骤中保留以前的记录值

假设可以对数据进行排序,以便首先出现具有有效
inputAcctNumber
的记录,则可以使用如下代码:

proc sort; by URN count;

data test_output (drop=replacement);
 length replacement $50;
 retain replacement;
 set test_input;
 if trim(inputAcctNumber) = '0' then inputAcctNumber=replacement;
 output;
 if trim(inputAcctNumber) ne '0' then replacement=inputAcctNumber;
run;

我看不出代码的哪一部分为两个观察值都提供了acount number值,而不仅仅是“null”或0…当我创建表d时,根据匹配URN的内部联接将有效的inputAcctNumber分配给缺少值的inputAcctNumber。具有有效AcctNumber的记录是否始终是COUNT=1的记录?是否可以有多条记录具有有效的帐号?如果是,值是否可能不同?如果是,您希望使用哪一个?每个URN组中填充的帐号应始终为计数1。可能有这样一个例子,其中2/3的帐户有一个填充的帐号并共享一个URN号码。因此,如果一个URN可以有两个帐号,那么您希望使用哪一个?你只需要使用COUNT=1的记录就可以得到一个。2/3的帐户应该是相同的数字。我可以按URN、COUNT、然后是帐户号排序,这应该总是有效的,对吗?我只是修改了代码,使每个URN处理两行以上的数据。假设具有有效inputAcctNumber的URN位于零之前,则它将显示work。它对您显示的示例数据起作用。这将使它适用于计数为NE 1的任意数量的观测值?它将获取InputActNumber的第一个值,并将其复制到该值URN的所有记录上。因此,是的,它将处理每个URN的任意数量的记录(即任何计数值)。这段代码的哪一部分实际上在第二、第三、第n次观察中创建Acct_Num?我看到first.urn然后new=acctnumb,但这只能满足count=0的观察,因为它是第一个。retain new语句是否在urn的一个迭代到下一个迭代之间保存acctnumb的值?是。retain语句的目的是防止SAS在数据步骤的下一次迭代开始时将变量重置为缺失。因此,在“URN”组中的下一个“URN”值开始时,其中一个URN可以大于1?
proc sort; by URN count;

data test_output (drop=replacement);
 length replacement $50;
 retain replacement;
 set test_input;
 if trim(inputAcctNumber) = '0' then inputAcctNumber=replacement;
 output;
 if trim(inputAcctNumber) ne '0' then replacement=inputAcctNumber;
run;