我有月度退货数据Return
,日期变量Price_Date
和公司标识变量Firm_ID
。
多家公司有多年的退货数据。
完全缺少几个月(没有任何变量的值,包括日期)。
或者对于确实存在的某些月份(即日期变量存在),return
变量和/或Firm_ID
变量具有缺失值(即.
)。
我想计算一个新变量,即滚动的X月(例如3个月,12个月)回报总和(连续月份)。
新变量Rolling_Sum应该等于当前月份的回报加上之前的(X-1)个月回报(总共X个月的回报)。
但是,我还想考虑缺失的观察结果,以便当任何特定月份的滚动金额中的任何一个回报丢失时,那个月的滚动金额也应该返回一个缺失值。
我怎样才能做到这一点?
例如,如果我找到3个月的滚动返回,那么变量,Date,Firm_ID,Returns和Rolling_Sum的数据可能如下所示。
31JAN2014 FirmA 10 .
28Feb2014 FirmA 11 .
31Mar2014 FirmA 12 33
30Apr2014 FirmA . .
31May2013 FirmA 10 .
30Jun2014 FirmA 10 .
31Aug2014 FirmA 12 .
30Sep2014 FirmA 11 .
31Oct2014 FirmA 50 73
31Jan2014 FirmB 20 .
28Feb2014 FirmB 70 .
31Mar2014 FirmB 40 130
注意,如果在3个月的总和中缺少一个值,则Rolling_Sum也返回为缺失(即“。”)(例如数据的第1行和第2行,以及第4行,第5行和第6行)。此外,如果缺少观察,则无法获得连续3个月的滚动总和,因此我也会得到一个缺失值作为输出(例如,自7月以来第7和第8行缺失)。 那是我追求的理想输出。
编辑:所有回报都已计算为整月的回报。
澄清:我连续几个月都没有连续观察。
答案 0 :(得分:0)
我试图了解目标。
假设您的数据如下所示:
data _t1;
input Price_date date9. Firm_ID $6. Return 4.;
format Price_date date9.;
cards;
01JAN2014 FirmA 200
02Feb2014 FirmA 220
03Mar2014 FirmA 250
17Apr2014 FirmA .
20May2014 FirmA 300
23Jun2014 FirmA 180
17Jul2014 FirmA 460
27Aug2014 FirmA 300
14Sep2014 FirmA 50
31Oct2014 FirmA 20
30Nov2014 FirmA 780
03Dec2014 FirmA 420
;
run;
data _t2;
set _t1;
Firm_ID = 'FirmB';
Return = coalesce(Return + 20,100);
if mod(_n_,5) = 0 then call missing(Return);
run;
data sample;
set _t1 _t2;
run;
proc print data=sample;run;
首先按Firm_ID
然后按price_date
排序。
proc sort data=sample;by Firm_ID Price_date;run;
/* rolling 3 mths */
data want;
set sample;
Rolling_Sum = Return + lag1(Return) + lag2(Return);
if first.Firm_ID then call missing(Rolling_Sum);
by Firm_ID Price_date;
run;
答案 1 :(得分:0)
proc expand
是一个非常强大且方便的工具,用于从混乱的输入数据创建干净的时间序列输出。我将您的示例数据读入一个名为returns的数据集,其中包含变量date,firm_id,returns和desired_roll3。使用proc expand
,将创建缺少值的缺失日期和名为calc_roll3的新变量,该变量与desired_roll3匹配。希望代码中的注释能够提供足够的注释来理解它是如何工作的。
proc expand
data=returns /* input dataset */
out=returns2 /* output dataset */
from=month /* input timeframe - monthly */
align=end /* alignment of timeframe - end of month */
;
by firm_id; * each time series is grouped by firm_id;
id date; * specify time series variable;
convert returns / method=none; * do not interpolate missing values;
* calculate 3-period moving sum without missing values, and set the first 2 values at ;
* beginning of each by-group to missing;
convert returns=calc_roll3 / method=none transformout=(nomiss movsum 3 trimleft 2);
run;
这是新数据集。