我有以下数据集,结构如下:
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
我必须向数据集中添加新变量,以便这些变量满足以下条件:
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;
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;
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;
该脚本正常工作,从某种意义上说,我没有在日志窗口中看到错误或警告消息,但是,正如您可以通过阅读脚本注意到的那样,它会在滞后变量中找到缺失值时返回缺失值。
是否有办法克服此类问题,以便只有在NEWVAR_3
等于1时才能让SAS达到FLAG
的延迟?
希望我在问题中已经足够清楚了,感谢所有人提前帮助!
答案 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;