【问题标题】:Retained variable not being retained未保留的保留变量
【发布时间】:2023-12-28 04:49:01
【问题描述】:

我正在尝试根据某些条件使用保留来总结一个变量。我有这些字段 account_id、date、transaction、value 和 transaction_type。

数据按account_id和日期排序

我想总结价值,直到第一个 transaction_type 不在 ('A') 中

我有这个

data dset; 
    set dset;
    by account_id;
    retain sum_flag sum;
    if first.account_id then do;
        sum_flag = 1;
        sum=0;
    end;
    if transaction_type not in ('A') then sum_flag = 0;
    if sum_flag = 1 then sum=sum +value;
run;

我的问题是,如果 A 中的第一个 transaction_type 可以正常工作,但如果下一个 transaction_type 也是 A sum_flag 设置为 .而不是保持为 1。为什么会这样?

我认为这与 如果 transaction_type 不在 ('A') 中,则 sum_flag = 0; 没有它,如果事务在“A”中,变量 sum_flag 不会被重置为缺失,但我只希望该值保留到第一个非“A”事务。

【问题讨论】:

  • 发布演示问题的示例数据。另外,由于您要覆盖输入数据集,您确定 SUM 和 SUM_FLAG 还不是输入数据中的变量吗?如果是这样,那么 RETAIN 就没有用了,因为在 SET 语句运行时这些值将被覆盖。
  • 我看不出它们被设置为丢失的原因。我在一些虚拟数据上测试了你的代码,结果很好。

标签: sas retain


【解决方案1】:

这里可能会发生两件事。

  1. 您的输出数据集名称与您的输入数据集名称相同(不好的做法 - 不要这样做)。如果您错误地运行它一次,它可能已将表中的值更改为意外的值,这会使更正后的代码看起来像是失败了。要解决此问题,只需从头开始重新运行并将输出数据集名称更改为其他名称。
  2. 您的value 字段有时可能包含空值?如果是这样,+ 运算符会导致您的问题。 + 运算符将始终返回 NULL 如果它的参数之一为空。而是使用sum() 函数。即if sum_flag = 1 then sum=sum(sum,value);

【讨论】:

    【解决方案2】:

    Tom 可能是正确的,即入站 dset 在您尝试解决此问题时的早期迭代中具有额外的变量。

    DOW 循环方法也有效,不需要保留或初始化 if。

    data dset;
    input group type $ value;
    datalines;
    1 A 1
    1 A 2
    1 A 3
    1 A 4
    1 B -5
    1 A 8
    2 A 0
    2 A 9
    2 A 33
    3 B 9
    ;
    run;
    
    data dset;
      sum = .; _summing=1;
      do until (last.group);
        set dset;
        by group;
    
        _summing = _summing and (type = 'A');
        if _summing then sum + value;
    
        output;
      end;
      drop _:; * dont keep state variables;
    run;
    

    【讨论】: