具有滞后值的条件 IF 语句

Conditional IF statement with lagged values

我有以下数据集,结构如下:

DATE           PERCENTAGE    FLAG    VALUE1  
01JAN2017        0.21          1      1.50   
04JAN2017        0.05          0      2.43
09JAN2017        0.06          1      2.21
24JAN2017        0.15          1      1.13

我必须向数据集添加新变量,使这些变量满足以下条件:

  1. 如果 FLAG 等于 1,那么它是第一行:
NEW_VAR_1 is equal to 500 * PERCENTAGE;
NEW_VAR_2 is equal to NEWVAR_1 * (VALUE1 - 1);
NEW_VAR_3 is equal to 500 + NEWVAR_2;
  1. FLAG 等于 1 且不是第一行的情况下:
NEW_VAR_1 is equal to LAG(NEWVAR_3) * PERCENTAGE;
NEW_VAR_2 is equal to NEWVAR_1 * (VALUE1 - 1);
NEW_VAR_3 is equal to LAG(NEWVAR_3) + NEWVAR_2;
  1. FLAG 等于 0 的情况下,所有 NEWVAR_ 值都必须设置为缺失。

我需要在 SAS 上 运行 这个脚本,我写了下面的脚本来做到这一点:

DATA BACKTESTING;
    SET BACKTESTING;
    IF _N_ EQ 1 AND FLAG EQ 1 THEN DO;
        K = 500;
        NEWVAR_1 = PERCENTAGE * K;
        NEWVAR_2 = NEWVAR_1 * (VALUE_1 - 1);
        NEWVAR_3 = K + NEWVAR_2;
    END;
    ELSE IF _N_ GT 1 AND FLAG EQ 1 THEN DO;
        NEWVAR_1 = PERCENTAGE * LAG(NEWVAR_3);
        NEWVAR_2 = NEWVAR_1 * (VALUE_1 - 1);
        NEWVAR_3 = K + NEWVAR_2; 
        END;
    END;
RUN;

脚本工作正常,从某种意义上说,我没有在日志中看到错误或警告消息 window,但是,正如您通过阅读脚本可以注意到的那样,它 returns 缺少值 returns它在滞后变量中找到缺失值。

有没有什么办法可以克服这个问题,让SAS只在FLAG等于1的时候才延迟NEWVAR_3

希望我在问题中已经足够清楚,在此先感谢大家的帮助!

lag 的问题是它实际上并没有读取以前的值。相反,它会在每次调用时将当前值添加到隐藏数组中 - 然后在后续调用中检索。

所以 - 如果您不在每次迭代时调用 lag(或调用它两次),您将得到意想不到的结果。

避免这种情况的一种方法是使用简单的 retain,例如:

DATA BACKTESTING;
  SET BACKTESTING;
  IF _N_ EQ 1 AND FLAG EQ 1 THEN DO;
    K = 500;
    NEWVAR_1 = PERCENTAGE * K;
    NEWVAR_2 = NEWVAR_1 * (VALUE_1 - 1);
    NEWVAR_3 = K + NEWVAR_2;
  END;
  ELSE IF _N_ GT 1 AND FLAG EQ 1 THEN DO;
    NEWVAR_1 = PERCENTAGE * LAG_NEWVAR_3;
    NEWVAR_2 = NEWVAR_1 * (VALUE_1 - 1);
    NEWVAR_3 = K + NEWVAR_2; 
    END;
  END;
  /* create temp retain variable */
  retain LAG_NEWVAR_3 0;
  drop LAG_NEWVAR_3;
  LAG_NEWVAR_3=NEWVAR_3;
RUN;

滞后函数的文档:http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000212547.htm

LAG() returns 上一次的值 运行。如果您有条件地调用 LAG() 那么它将有一个发现的记录值列表。

你的逻辑可以简化很多。

DATA BACKTESTING;
  SET BACKTESTING;
  k = lag(newvar_3);
  IF _N_ EQ 1 then k=500 ;
  if FLAG EQ 1 THEN DO;
    NEWVAR_1 = PERCENTAGE * K;
    NEWVAR_2 = NEWVAR_1 * (VALUE_1 - 1);
    NEWVAR_3 = K + NEWVAR_2;
  END;
RUN;

但如果 NEWVAR_3 确实是一个 "new" 变量,那么每次 lag(newvar_3) 运行时它都会丢失,并且您的滞后值将始终丢失。在这种情况下,您需要保留之前观察到的值。

DATA BACKTESTING;
  SET BACKTESTING;
  retain k 500 ;
  if FLAG EQ 1 THEN DO;
    NEWVAR_1 = PERCENTAGE * K;
    NEWVAR_2 = NEWVAR_1 * (VALUE_1 - 1);
    NEWVAR_3 = K + NEWVAR_2;
    k = newvar_3 ;
  END;
RUN;