Home > other >  Filling up values within a group
Filling up values within a group

Time:06-24

I have a SAS table like below

ID Grp Month
A 202201
A 202203
1234 A 202204
B 202201
B 202203
AB1234 B 202204
C 202201
C 202203
3333 C 202204
3333 C 202205
4444 C 202206
T 202204
T 202205
T 202206
D 202201
D 202203
A555 D 202204
D 202205
6666 D 202206

I required the output SAS dataset as :

ID Grp Month
1234 A 202201
1234 A 202203
1234 A 202204
AB1234 B 202201
AB1234 B 202203
AB1234 B 202204
3333 C 202201
3333 C 202203
3333 C 202204
3333 C 202205
4444 C 202206
T 202204
T 202205
T 202206
A555 D 202201
A555 D 202203
A555 D 202204
6666 D 202205
6666 D 202206

Can someone please help??

Thanks in advance

CodePudding user response:

If the data was sorted by descending MONTH values it would be lot easier. It is much easier to remember a value you have already seen than to predict what value you might see in the future.

First let's convert your listing into an actual dataset we can use to work with.

data have ;
  input ID $ Grp $ Month ;
cards;
. A 202201
. A 202203
1234 A 202204
. B 202201
. B 202203
AB1234 B 202204
. C 202201
. C 202203
3333 C 202204
3333 C 202205
4444 C 202206
. T 202204
. T 202205
. T 202206
. D 202201
. D 202203
A555 D 202204
. D 202205
6666 D 202206
;

Now sort it by GRP and descending MONTH and you can use the UPDATE statement to do a last observation carried forward.

proc sort data=have;
  by grp descending month;
run;

data want;
  update have(obs=0) have;
  by grp;
  output;
run;

If you want you can resort to have ascending month values.

proc sort data=want;
  by grp month;
run;

Results:

Obs      ID      Grp     Month

  1    1234       A     202201
  2    1234       A     202203
  3    1234       A     202204
  4    AB1234     B     202201
  5    AB1234     B     202203
  6    AB1234     B     202204
  7    3333       C     202201
  8    3333       C     202203
  9    3333       C     202204
 10    3333       C     202205
 11    4444       C     202206
 12    A555       D     202201
 13    A555       D     202203
 14    A555       D     202204
 15    6666       D     202205
 16    6666       D     202206
 17               T     202204
 18               T     202205
 19               T     202206

If you really have to deal with the data in the order shown then you could use a double DOW loop. The first loop to find the next non missing ID value. And the second to re-read the observations and update the ID value and write them out.

data want;
  if 0 then set have;
  do _n_=1 by 1 until(last.grp or not missing(id));
    set have ;
    by grp notsorted;
  end;
  _id = id;
  do _n_=1 to _n_;
    set have;
    id = _id;
    output;
  end;
  drop _id;
run;
  • Related