我一直在尝试使用SAS根据现有字段计算新字段。我试过滞后功能,但没有工作。以下是我尝试过的数据和程序。
原始数据:
Cust_ID Prdct_No no_of_mnths Actual_Shp_Dt计数
x 12 2 8/1/2014 10
x 12 1 8/11/2014 10
x 12 0 8/23/2014 10
y 13 2 8/1/2014 10
y 13 1 8/11/2014 10
y 14a 2 8/1/2014 10
y 14a 1 8/11/2014 10
y 14a 0 8/21/2014 10
z 15 3 9/1/2014 20
z 15 2 9/15/2014 20
要求的结果:
Target_Ship_Dt是由Cust_ID和Prdct_No分组的(滞后(Actual_Shp_Dt)和滞后(Count))的总和。如果Actual_Shp_Dt晚于或早于target_shp_Dt,则Target_Shp_Dt为SUM(滞后(Target_Shp_Dt)和滞后(Count))。
Cust_ID Prdct_No no_of_mnths Actual_Shp_Dt Count Target_Ship_Dt
x 12 2 8/1/2014 10
x 12 1 8/11/2014 10 8/11/2014
x 12 0 8/23/2014 10 8/21/2014
y 13 2 8/1/2014 10
y 13 1 8/11/2014 10 8/11/2014
y 14a 2 8/1/2014 10
y 14a 1 8/11/2014 10 8/11/2014
y 14a 0 8/21/2014 10 8/21/2014
z 15 3 9/1/2014 20
z 15 2 9/15/2014 20 9/21/2014
我试过的代码:
Data Raw_Data(drop = Prdct_ID_lag Actual_Shp_Dt_lag Count_Lag Target_Shp_Dt1);
设置Raw_Data;
按Cust_ID Prdct_ID;
Prdct_ID_lag = lag(Prdct_ID);
格式Actual_Shp_Dt_lag date9。;
Actual_Shp_Dt_lag = lag(Actual_Shp_Dt);
Count_Lag = lag(Count);
格式化Target_Shp_dt date9。;
如果Prdct_ID~ = Prdct_ID_lag则Actual_Shp_Dt_lag =。;
如果Prdct_ID~ = Prdct_ID_lag则Count_Lag =。;
Target_Shp_Dt1 = Actual_Shp_Dt_lag + Count_Lag;
Target_Shp_Dt = Target_Shp_Dt1;
如果Actual_Shp_Dt> Target_Shp_Dt1然后Target_Shp_Dt = Target_Shp_Dt1 + Count_lag;
如果Actual_Shp_Dt< Target_Shp_Dt1然后Target_Shp_Dt = Target_Shp_Dt1 + Count_lag;
跑;
但是这段代码并没有给我正确的结果。
任何帮助都将不胜感激。
尝试新代码后: 数据有:
Cust_ID Prdct_No no_of_mnths Actual_Shp_Dt Count Target_Ship_Dt
x 12 2 8/1/2014 10
x 12 1 8/11/2014 10 8/11/2014
x 12 0 8/23/2014 10
y 13 2 8/1/2014 10
y 13 1 8/11/2014 10 8/11/2014
y 14a 2 8/1/2014 10
y 14a 1 8/11/2014 10 8/11/2014
y 14a 0 8/21/2014 10 8/21/2014
z 15 3 9/1/2014 20
z 15 2 9/15/2014 20
有效的代码:
Data Raw_Data(drop = Prdct_ID_lag Actual_Shp_Dt_lag Count_Lag Target_Shp_Dt1);
设置Raw_Data;
按Cust_ID Prdct_ID;
Cust_ID_lag = lag(Cust_ID);
Prdct_ID_lag = lag(Prdct_ID);
格式Actual_Shp_Dt_lag Target_Shp_Dt date9。;
Actual_Shp_Dt_lag = lag(Actual_Shp_Dt);
Count_Lag = lag(Count);
保留target_shp_dt_lag;
如果Cust_ID = Cust_ID_lag且Prdct_ID = Prdct_ID_lag且target_shp_dt_lag =。
然后Target_Shp_Dt = Actual_Shp_Dt_lag + Count_Lag;
ELSE IF Cust_ID = Cust_ID_lag和Prdct_ID = Prdct_ID_lag
然后Target_Shp_Dt = target_shp_dt_lag + Count_Lag;
ELSE Target_Shp_Dt =。;
target_shp_dt_lag = Target_Shp_Dt;
跑;
答案 0 :(得分:0)
您的定义说如果初始target_ship_dt不等于actual_shp_dt,则需要使用lag(target_shp_dt),但您的代码实际上从未执行过此操作。
更新:
似乎lag
对于在同一数据步骤中创建的变量不起作用,但使用retain
确实存在,这就是为什么Target_Shp_Dt_lag
最初缺少所有值的原因。
另外,您确定示例数据集中的最后一行吗?它似乎与您的规则不一致:滞后(计数)+滞后(actual_shp_dt)= 9/21/2014,但是9/21/2014> 2014年9月15日,这意味着您需要采用滞后(计数)+滞后(target_shp_dt),这会导致缺少滞后值(target_shp_date)。以下代码适用于所有其他情况。
data raw_data;
input Cust_ID :$1. Prdct_No :$3. no_of_mnths :3. Actual_Shp_Dt :mmddyy10. Count :3.;
format actual_shp_dt yymmdd10.;
cards;
x 12 2 8/1/2014 10
x 12 1 8/11/2014 10
x 12 0 8/23/2014 10
y 13 2 8/1/2014 10
y 13 1 8/11/2014 10
y 14a 2 8/1/2014 10
y 14a 1 8/11/2014 10
y 14a 0 8/21/2014 10
z 15 3 9/1/2014 20
z 15 2 9/15/2014 20
;
run;
data want;
input Cust_ID :$1. Prdct_No :$3. no_of_mnths :3. Actual_Shp_Dt :mmddyy10. Count :3. Target_ship_dt :mmddyy10.;
format actual_shp_dt Target_ship_dt yymmdd10.;
infile cards missover;
cards;
x 12 2 8/1/2014 10
x 12 1 8/11/2014 10 8/11/2014
x 12 0 8/23/2014 10 8/21/2014
y 13 2 8/1/2014 10
y 13 1 8/11/2014 10 8/11/2014
y 14a 2 8/1/2014 10
y 14a 1 8/11/2014 10 8/11/2014
y 14a 0 8/21/2014 10 8/21/2014
z 15 3 9/1/2014 20
z 15 2 9/15/2014 20 9/21/2014
;
run;
Data have(drop = Prdct_no_lag Actual_Shp_Dt_lag Count_Lag Target_Shp_Dt1 Target_Shp_Dt_lag) ;
Set raw_data;
By Cust_ID Prdct_no;
Prdct_no_lag = lag(Prdct_no);
Actual_Shp_Dt_lag = lag(Actual_Shp_Dt);
Count_Lag = lag(Count);
retain target_shp_dt_lag;
if first.prdct_no then call missing(Actual_Shp_Dt_lag, count_lag, prdct_no_lag, target_shp_dt_lag);
Target_Shp_Dt1 = Actual_Shp_Dt_lag + Count_Lag;
Target_Shp_Dt = Target_Shp_Dt1;
If Actual_Shp_Dt ne Target_Shp_Dt1 Then Target_Shp_Dt = Target_Shp_Dt_lag + Count_lag;
Target_Shp_Dt_lag = Target_Shp_Dt;
format Actual_Shp_Dt_lag Target_Shp_dt: yymmdd10.;
Run;
proc compare base = want compare = have;
var Target_Shp_Dt;
run;