使用SAS根据现有变量计算新变量

时间:2014-10-26 03:05:02

标签: sas lag sas-macro

我一直在尝试使用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;
跑;

1 个答案:

答案 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;