如何在 SAS 中为每个 ID 插入新行和值

How to insert new rows and values for each ID in SAS

我有 3 个变量:ID、天数和温度。对于每个条目,我需要为每个 ID 插入额外天数的行,并且我需要温度在这些行之间进行传递。

目标是让每个 ID 都有完整的连续几天具有相同的温度。这是我的:

ID             day               temp 
1001            68                16
1001            73                14
1002            85                17
1002            89                15
1003            91                18
1004            97                19
1004            99                20
1004           106                12
1005           109                15
1006           111                18
1006           115                19
1006           120                20
1006           122                21

这就是我想要的:

ID             day               temp 
1001            68                16
1001            69                16
1001            70                16
1001            71                16
1001            72                16
1001            73                14
1001            74                14
1001            75                14
1001            76                14
1001            77                14
1001            78                14
1001            79                14
1001            80                14
1001            81                14
1001            82                14
1001            83                14
1001            84                14
1002            85                17
1002            86                17
1002            87                17
1002            88                17
1002            89                15
1002            90                15
1003            91                18
1003            92                18
1003            93                18
1003            94                18
1003            95                18
1003            96                18
1004            97                19
1004            98                19
1004            99                19
proc sort data=have;
by ID;
run;

data want;
set have;
retain temp ID;
day=day +1;
if first.day then temp= temp+0;
end;
run;

我希望结果是这样的:

ID             day               temp 
1001            68                16
1001            69                16
1001            70                16
1001            71                16
1001            72                16
1001            73                14
1001            74                14
1001            75                14
1001            76                14
1001            77                14
1001            78                14
1001            79                14
1001            80                14
1001            81                14
1001            82                14
1001            83                14
1001            84                14
1002            85                17
1002            86                17
1002            87                17
1002            88                17
1002            89                15
1002            90                15
1003            91                18
1003            92                18
1003            93                18
1003            94                18
1003            95                18
1003            96                18
1004            97                19
1004            98                19
1004            99                19

但不知何故,我仍然得到我试图更改的旧数据。任何帮助将不胜感激。谢谢

除了最后一个条目似乎与您的逻辑不一致外,以下代码应该可以满足您的需求:

1004            99                19

结果是:

1004            99                20

根据你的逻辑。

proc sort data=have;
by ID day;
run;

data want;
 merge have have (firstobs=2 rename=(id=id2 day=day2 temp=temp2));

 output;

 if (day2 > day) then do;
   do while (day < day2 - 1);
     day + 1; output;
   end;
 end;

 keep id day temp;
run;

一个稳健的解决方案将在每个 id 组的开始重置迭代。您的示例数据不显示连续组的开始日期早于前一组的情况。如果不测试 id 组的开始(或在组内),结果可能与预期不同。

示例 1:1 与从 obs=2 开始的第二个自我合并,以提供来自 nextlead 值排。数据已用组 id=1007id=1009 进行了修改,因此需要 重置 。组within-ness条件用id=lead_id

测试
data have; input
ID     day  temp; datalines;
1001    68   16
1001    73   14
1002    85   17
1002    89   15
1003    91   18
1004    97   19
1004    99   20
1004   106   12
1005   109   15
1006   111   18
1006   115   19
1006   120   20
1006   122   21
1007     1    1
1007    15    0
1007    16    2
1007    20    5
1008    35   12
1008    37   14
1008    45   20
run;

data want (drop=lead:);
  merge have have(keep=day id rename=(id=lead_id day=lead_day) firstobs=2);
  * by is not used for a 1:1 merge;

  if id=lag(id) and day < lag(day) then do;
    put "ERR" "OR: Stopping because days are not ordered within " ID= "at " day= ;
    stop;
  end;    

  if (id=lead_id) then do day=day to lead_day-1;
    output; * fill-in rows with same temp;
  end;
  else 
    output; * final row of group;
run;