If statement 具有滞后值的条件IF语句

If statement 具有滞后值的条件IF语句,if-statement,sas,row,datastep,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 DATA BACKTESTI

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

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
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;
我必须向数据集中添加新变量,以便这些变量满足以下条件:

  • 标志
    等于1的情况下,它是第一行,然后:
  • 如果
    标志
    等于1且不是第一行,则:
  • 如果
    标志
    等于0,则必须将所有
    NEWVAR_uu
    值设置为缺失
  • 我需要在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;
    
    脚本工作正常,从某种意义上说,我没有在日志窗口中看到错误或警告消息,但是,正如您通过读取脚本所注意到的,当它在滞后变量中找到缺失值时,它返回缺失值

    有没有办法克服这样的问题,以便只有当
    FLAG
    等于1时,SAS才能接受
    NEWVAR_3
    的滞后


    希望我的问题已经很清楚了,提前谢谢大家的帮助

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

    所以-如果你不在每次迭代中调用
    lag
    (或者调用两次),你会得到意想不到的结果

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

    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
    
    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;
    
    lag函数的文档:

    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;
    

    感谢@Tom提供的解释和脚本示例。