【问题标题】:How to insert new rows and values for each ID in SAS如何在 SAS 中为每个 ID 插入新行和新值
【发布时间】:2019-08-12 19:14:02
【问题描述】:

我有 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

但不知何故,我仍在尝试更改旧数据。任何帮助将不胜感激。谢谢

【问题讨论】:

  • 您实际上是在修改记录,而不是在两条记录之间插入多条记录。您也有语法错误。请参阅我的答案,了解实现您想要的一种可能的方法。
  • 对于气候数据,假设 LOCF 不适合填补缺失数据。我希望这是一个生成的用例。
  • 为什么要将 ID=1001 记录从其最后一个日期扩展到下一个 ID 的第一个日期?那没有意义。身份证是什么意思?

标签: loops sas retain


【解决方案1】:

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

以自我 1:1 的示例与从 obs=2 开始的第二个自我合并,以提供 next 行中的 lead 值。使用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;

【讨论】:

  • 在这里我想我是唯一一个在我的代码中拆分字符串 ERROR: 的人。 =)
  • 哈哈,我从你那里得到的!在日志中搜索实际的 ERROR: 时肯定会有所帮助
  • 不错!很高兴我能回馈一些东西……这些年来我偷了很多你的宏……
【解决方案2】:

下面的代码应该可以得到你想要的,除了最后一个看起来与你的逻辑不一致的条目:

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;

【讨论】:

  • 这行得通。非常感谢您的回复。你说得对,最后应该是 20。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-31
  • 2017-12-26
相关资源
最近更新 更多