BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
HEB1
Calcite | Level 5

I have the following data :

gvkey fyear ac_choice

a         1990       0

a          1991       0

a           1992       0

a          1993        1

a           1994        0

a             1995       0

a             1996           1

a              1997        0

a            1998           0

b              2000          0

b              2001           0

b              2002           1

b               2003          0

b               2004           1

b               2005            0

I want to create a new variable that counts backswords from ac_choice=0 by gvkey- so data will look like that: 

 

gvkey fyear ac_choice     before                          

a         1990       0                 -3

a          1991       0                  -2

a           1992       0               -1

a          1993        1               0

a           1994        0                  -2

a             1995       0                -1

a             1996           1             0

a              1997        0                0

a            1998           0                0

b              2000          0                 -2

b              2001           0                  -1

b              2002           1                0

b               2003          0                    -1

b               2004           1                  0

b               2005            0                           0

1 ACCEPTED SOLUTION

Accepted Solutions
Ksharp
Super User
data have;
input gvkey $ fyear ac_choice;
cards;
a         1990       0
a          1991       0
a           1992       0
a          1993        1
a           1994        0
a             1995       0
a             1996           1
a              1997        0
a            1998           0
b              2000          0
b              2001           0
b              2002           1
b               2003          0
b               2004           1
b               2005            0
;

proc sort data=have out=temp;
by gvkey descending fyear ;
run;
data temp2;
 set temp;
 by gvkey;
 if first.gvkey or ac_choice then group+1;
run;
data temp3;
 set temp2;
 by group;
 retain first;
 if first.group then do;n=-1;first=ac_choice;end;
 n+1;
 if first then before=-n;
  else before=.;
drop first group n;
run;
proc sort data=temp3 out=want;
by gvkey  fyear ;
run;

View solution in original post

3 REPLIES 3
HEB1
Calcite | Level 5

Sorry, I want to create a new variable that counts backswords from ac_choice=0 by gvkey- so data will look like that: 

 

gvkey fyear ac_choice     before                          

a         1990       0                 -3

a          1991       0                  -2

a           1992       0               -1

a          1993        1               0

a           1994        0                  -2

a             1995       0                -1

a             1996           1             0

a              1997        0                .

a            1998           0              .

b              2000          0                 -2

b              2001           0                  -1

b              2002           1                0

b               2003          0                    -1

b               2004           1                  0

b               2005            0                           .

ballardw
Super User

See if this gets you started.

First, please provide data in the form of a data step into a text box opened on the forum with the </> icon above the message window. Stuff pasted into the main message window is likely to acquire all sorts of strange characters because of the behavior of the main message windows with this forum software.

 

 

data have;
  input gvkey $ fyear ac_choice;
datalines;
a 1990 0
a 1991 0
a 1992 0
a 1993 1
a 1994 0
a 1995 0
a 1996 1
a 1997 0
a 1998 0
b 2000 0
b 2001 0
b 2002 1
b 2003 0
b 2004 1
b 2005 0
;

proc sort data=have;
   by gvkey descending fyear;
run;

data want;
   set have;
   by gvkey;
   retain before;
   if first.gvkey then before=.;
   if ac_choice=1 then before=0;
   else if ac_choice=0 then before=before - 1;
run;

proc sort data=want;
   by gvkey fyear;
run;

SAS provides Retain to keep values across the data step boundary. Since you are "counting backward" then sort to make the data "backward" and we can use the Retain to keep the values as we count "down".

When you use a BY statement to process groups of records SAS provides automatic variables First. and Last. that are numeric 1/0 which are treated as true/false so you can conditionally execute code when true, in this case reset the Retained variable to missing for the "first" (was the Last) year for each Gvkey group. Until a 1 is encountered for ac_choice the values will be missing as missing -1 is missing. There will be notes in the log about missing values generated. Then after that -1 is subtracted for each 0.

Then sort back to the original order.

 

Note: Your problem descriptions need to include rules such as "when ac_choice=1 reset the counter to 0". I have to guess that from the shown data and more complex issues I may well be wrong. Any exceptions to the rule should be stated as well. Such as "Subtract 1 from the counter only after a 1 has been encountered in ac_choice".

Ksharp
Super User
data have;
input gvkey $ fyear ac_choice;
cards;
a         1990       0
a          1991       0
a           1992       0
a          1993        1
a           1994        0
a             1995       0
a             1996           1
a              1997        0
a            1998           0
b              2000          0
b              2001           0
b              2002           1
b               2003          0
b               2004           1
b               2005            0
;

proc sort data=have out=temp;
by gvkey descending fyear ;
run;
data temp2;
 set temp;
 by gvkey;
 if first.gvkey or ac_choice then group+1;
run;
data temp3;
 set temp2;
 by group;
 retain first;
 if first.group then do;n=-1;first=ac_choice;end;
 n+1;
 if first then before=-n;
  else before=.;
drop first group n;
run;
proc sort data=temp3 out=want;
by gvkey  fyear ;
run;

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 3 replies
  • 555 views
  • 0 likes
  • 3 in conversation