使用数据步骤生成下一个观察

use data step generate next observation

案例一

假设数据按年排序然后按月排序(数据中总是有 3 个观测值)。

Year Month Index
2014 11    1.1
2014 12    1.5
2015 1     1.2

我需要将上个月的Index复制到新观察

Year Month Index
2014 11    1.1
2014 12    1.5
2015 1     1.2
2015 2     1.2 

案例二

Year 已从数据中删除。所以我们只有 MonthIndex.

Month Index
1     1.2
11    1.1
12    1.5

数据总是从连续 3 个月开始收集。所以1是最后一个月。

不过,理想的输出是

Month Index
1     1.2
2     1.2
11    1.1
12    1.5

我通过创建另一个仅包含 Month (1,2...12) 的数据集来解决它。然后右加入原始数据集两次。但我认为有更优雅的方式来处理这个问题。

案例 1 可以是直接的数据步骤。将end=eof添加到set语句中,以在数据步骤读取数据集的最后一行时初始化一个变量eof,使returns值为1。数据步骤中的输出语句在每次迭代期间输出一行。如果 eof=1,则运行一个 do 块,将月份递增 1 并输出另一行。

data want;
  set have end=eof;
  output;
  if eof then do;
    month=mod(month+1,12);
    output;
  end;
run;

对于情况 2,我将切换到 sql 解决方案。自加入 table 到自己的月份,在第二个 table 中增加 1。使用 coalesce 函数保留现有 table 中的值(如果存在)。如果不是,请使用第二个 table 中的值。由于跨越 12 月到 1 月的个案将产生 5 个月,因此使用 proc sql 中的 outobs= 选项将输出限制为四行,以排除不需要的第二个 1 月。

proc sql outobs=4;
create table want as
select
  coalesce(t1.month,mod(t2.month+1,12)) as month,
  coalesce(t1.index,t2.index) as index
from
  have t1
  full outer join have t2
  on t1.month = t2.month+1
order by
  coalesce(t1.month,t2.month+1)
;
quit;