【问题标题】:Calculating correlation and covariance for a event window in SAS计算 SAS 中事件窗口的相关性和协方差
【发布时间】:2026-01-22 07:30:01
【问题描述】:

我必须计算事件窗口的每日销售值的相关性和协方差。事件窗口的期限为 45 天,我的数据看起来像 -

store_id    date       sales
5927    12-Jan-07    3,714.00
5927    12-Jan-07    3,259.00
5927    14-Jan-07    3,787.00
5927    14-Jan-07    3,480.00
5927    17-Jan-07    3,646.00
5927    17-Jan-07    3,316.00
4978    18-Jan-07    3,530.00
4978    18-Jan-07    3,103.00
4978    18-Jan-07    3,026.00
4978    21-Jan-07    3,448.00

现在,对于每个 store_id、日期组合,我需要返回 45 天(我的原始数据集中每个组合都有更多数据)计算销售额和滞后(销售额)之间的相关性,即一级自相关。如您所见,日期列不是连续的。所以像 (date - 45) 这样的东西是行不通的。

我已经到了这部分 -

data ds1;
  set ds;
  by store_id;
  LAG_SALE = lag(sales);
      IF FIRST.store_idTHEN DO;
      LAG_SALE = .;
      END;
run;

用于计算相关性和协方差 -

proc corr data=ds1 outp=Corr
by store_id date;
      cov;   /**  include covariances **/
var sales lag_sale;
run;

但是如何为每个日期、store_id 组合插入事件窗口?我的最终输出应该是这样的 -

id    date     corr cov
5927 12-Jan-07 ... ...
5927 14-Jan-07 ... ...

【问题讨论】:

  • 你有 SAS/ETS 许可吗?
  • 对于每个 store_id/date 组合,您希望数据与该 store_id 和日期的协方差和相关性,还是与该 store_id 的日期和最近 45 个不同日期内的日期的协方差和相关性?您的问题建议第二个,但您的 proc corr 建议第一个。
  • 我想要每个 store_id/date 组合的销售和销售滞后的相关性和 cov。是的,我已获得许可。
  • 嗯,在那种情况下我很困惑;如果对每个 store_id/date 组合分别计算相关性和协方差,那么 45 天的意义何在?
  • 对于每个 store_id 和 date,我返回 45 天以获得两个系列销售额和 45 个观察值的 lag_sales,即 (-45, 0)。我不想计算所有数据的协方差,只是在有限的时间内,看看它是如何变化的。

标签: sas covariance correlation


【解决方案1】:

这是我想出的:

首先我将日期转换为 SAS 日期,即自 1960 年 1 月 1 日以来的天数:

data ds;
    set ds (rename=(date=old_date));
    date = input(old_date, date11.);
    drop old_date;
run;

然后计算 lag_sale (我使用的是您在问题中使用的相同计算,但请确保这是您想要做的。对于某些观察,滞后销售是之前记录的日期,但对于某些它是相同的 store_id和日期,只是不同的观察结果。):

proc sort data=ds; by store_id; run;

data ds;
    set ds;
    by store_id;
    lag_sale = lag(sales);
    if first.store_id then lag_sale = .;
run;

然后设置最终的数据集:

data final;
    length store_id 8 date 8 cov 8 corr 8;
    if _n_ = 0;
run;

然后创建一个宏,它接受 store_id 和日期并运行 proc corr。宏的第一部分仅选择具有该 store_id 且在该日期过去 45 天内的数据。然后它运行proc corr。然后它将 proc corr 格式化为您想要的格式,并将结果附加到“最终”数据集。

%macro corr(store_id, date);
data ds2;
    set ds;
    where store_id = &store_id and %eval(&date-45) <= date <=&date 
        and lag_sale ne .;
run;

proc corr noprint data=ds2 cov outp=corr;
    by store_id;
    var sales lag_sale;
run;

data corr2;
    set corr;
    where _type_ in ('CORR', 'COV') and _name_ = 'sales';
    retain cov;
    date = &date;
    if _type_ = 'COV' then cov = lag_sale;
    else do;
        corr = lag_sale;
        output;
    end;
    keep store_id date corr cov;
run;

proc append base=final data=corr2 force; run;

%mend corr;

最后为每个 store_id/date 组合运行宏。

proc sort data=ds out=ds3 nodupkey;
    by store_id date;
run;

data _null_;
    set ds3;
    call execute('%corr('||store_id||','||date||');');
run;

proc sort data=final;
    by store_id date;
run;

【讨论】:

  • 哇!谢谢!这很有帮助。我写了一个类似的宏。但是需要很多时间来运行。我一定会试试的!谢谢!
  • 此代码的一个问题是%eval(&amp;date-45) 语句。这不会回到 45 天,因为我的时间序列不是连续的。无论如何,我可以将其更改为在我的数据系列中包含最后 45 个日期)