【问题标题】:Average/Count of a varying number of observations until a condition is met在满足条件之前,不同数量的观察的平均值/计数
【发布时间】:2018-07-19 15:21:35
【问题描述】:

我有一个具有以下结构的数据集:

ID  Date&Time   var1    var2
1   1/11        1       yes
1   3/11        3       no
1   3/11        2       no
1   5/11        5       yes
1   10/11       2       no
2   3/11        0       yes
2   12/11       1       no
2   23/11       2       yes
2   24/11       0       yes
3   5/11        1       yes
3   6/11        2       no
3   8/11        5       yes
3   9/11        4       no

这是一个日志文件,其中包含我的分析所依据的观察结果。现在我想考虑一个移动平均线,例如上周(以及月份、年份等)的所有观测值,即我想要如下结构:

ID  Date&Time   var1    var2    week_avg    week_count
1   1/11        1       yes     .           .
1   3/11        3       no      1           1
1   3/11        2       no      2           1
1   5/11        5       yes     2           1
1   10/11       2       no      3.33        1
2   3/11        0       yes     .           .
2   12/11       1       no      .           .
2   23/11       2       yes     .           .
2   24/11       0       yes     2           1
3   5/11        1       yes     .           .
3   6/11        2       no      1           1
3   8/11        5       yes     1.5         1
3   9/11        4       no      2.66        2

有没有办法在do-until 循环中使用lag 函数? 或者PROC EXPAND 是否能够通过指定时间窗口而不是观察次数来执行移动平均?

【问题讨论】:

  • 你能澄清一下你在做什么吗?您是说您想要使用您拥有的数据在一周内进行观察的移动平均值吗?如果是这样,您首先需要将数据累积到您感兴趣的时间间隔内的时间序列中。这可以通过数据步骤和proc timeseries 来实现
  • 您是否有任何机会获得 SAS-ETS 许可?
  • proc timeseries 只适用于一次转换,对吧?例如,几周或几个月?
  • 我确实有企业指南和企业矿工可用。实际上,我什至不知道特定的时间序列 SAS 工具
  • SAS/ETS 是单独许可的 SAS 程序集。就像 SAS/Stat 与 Base SAS 是分开的。运行 proc setinit;run; 以查看您已获得许可。

标签: sas


【解决方案1】:

您可以通过副处理来完成,首先创建相应的周期值:

proc sort data=have ; by id date ; run ;

data periods ;
  set have ;
  year  = put(date,year4.) ;
  month = put(date,yymmn6.) ;
  week  = put(date,weeku5.) ;
run ;

data groups ;
  set periods ;
  retain week_tot week_cnt month_tot month_cnt year_tot year_cnt 0 ;
  /* For the first value in each period, set count & total values to . */
  if first.year then call missing(of year_:) ;
  if first.month then call missing(of month_:) ;
  if first.week then call missing(of week_:) ;

  /* Increment count by 1, total by var1, calculate average */
  /* Add any conditional logic on which to increment the running values */
  week_cnt  + 1 ; week_tot  + var1 ; week_avg  = week_tot  / week_cnt ;
  month_cnt + 1 ; month_tot + var1 ; month_avg = month_tot / month_cnt ;
  year_cnt  + 1 ; year_tot  + var1 ; year_avg  = year_tot  / year_cnt ;
run ;

如果你愿意,你可以将上面的内容抽象成一个宏

%MACRO PERIOD_CALC(PD) ;
  retain &PD._cnt &PD._tot ;
  if first.&PD then call missing(of &PD._:) ;
  &PD._cnt + 1 ;
  &PD._tot + var1 ;
  &PD._avg = &PD._tot / &PD._cnt ;
%MEND ;

data groups ;
  set periods ;
  %PERIOD_CALC(week) ;
  %PERIOD_CALC(month) ;
  %PERIOD_CALC(year) ;
run ;

【讨论】:

  • 感谢您的帮助,很抱歉我的回复晚了。它并没有完全按照我的意愿工作,我自己构建了一个繁琐的解决方案。我对你的提议有两个问题: - 调用 missing() 不起作用。周、月或年的所有值都相同。 - 而且,最重要的是:您的解决方案确实会处理每一个问题,例如周以独特的方式。但是,我不想在每周开始时从 0 开始,而只考虑当前日期之前的最后 7 天,无论它们属于哪一周
猜你喜欢
  • 1970-01-01
  • 2018-10-24
  • 1970-01-01
  • 1970-01-01
  • 2021-05-15
  • 2016-01-29
  • 2017-01-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多