具有滞后值的条件IF语句

时间:2017-03-19 09:30:55

标签: if-statement sas row datastep

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

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,那么它就是第一行:
  2. 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并且它不是第一行,那么:
    2. 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_值。
      2. 我需要在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;
        

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

        是否有办法克服此类问题,以便只有在NEWVAR_3等于1时才能让SAS达到FLAG的延迟?

        希望我在问题中已经足够清楚了,感谢所有人提前帮助!

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

LAG()返回上次运行时的值。如果您有条件地呼叫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确实是一个“新”变量,那么每次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;