BookmarkSubscribeRSS Feed
Ronein
Meteorite | Level 14

Hello

I have a raw data that contain follow up information for each customer.

Each customer has one row with 17 follow up columns (of grade).

The name of follow up columns are: gk1,gk2,gk3.........gk17

(For example:

gk1 is grade one month after entering the population

gk2 is grade two months after entering the population

gk3 is grade one month after entering the population

and so on).

There is also information of number of months that the customer was expose to illness.

I want to create a macro that convert values into 999  if the customer is not exposed any more.

IF Number_Months_Expose=16 then do;gk17=999;end;

IF Number_Months_Expose=15 then do;gk17=999 ;gk16=999;end;

IF Number_Months_Expose=14 then do;gk17=999 ;gk16=999;gk15=999;end;

and so on

IF Number_Months_Expose=1 then do;gk17=999 ;gk16=999;gk15=999;and so on  gk2=999;end;

What is the way to write it in macro please?

Here is the direction that I think should be done but still don't know how to do it.

 

%let n=17;/*Number of follow up variables*/

 

%macro g;

%DO i=%EVAL(&n.-1) %TO  1  %BY -1;

%DO k=&i %TO &n. %BY 1;

HERE need to write  IF statements

%end;

%end;

%mend g;

 

Data wanted;

set Rawtbl;

%g;

Run;

 

 

Data Rawtbl;
input ID Number_Months_Expose gk1 gk2 gk3 gk4 gk5 gk6 gk7 gk8 gk9 gk10 gk11 gk12 gk13 gk14 gk15 gk16 gk17;
cards;
DATA FOR example
Run;

 

 

 

5 REPLIES 5
PaigeMiller
Diamond | Level 26

Use ARRAYs, macro not needed.

--
Paige Miller
Reeza
Super User

Why not use arrays here? What's the benefit of a macro? Is there any reason you're going backwards instead of forwards as well?

 

data want;
set have;
array gk(17) gk1-gk17;

do i=number_months_expose+1 to dim(gk);
gk(i) = 999;
end;

run;

@Ronein wrote:

Hello

I have a raw data that contain follow up information for each customer.

Each customer has one row with 17 follow up columns (of grade).

The name of follow up columns are: gk1,gk2,gk3.........gk17

(For example:

gk1 is grade one month after entering the population

gk2 is grade two months after entering the population

gk3 is grade one month after entering the population

and so on).

There is also information of number of months that the customer was expose to illness.

I want to create a macro that convert values into 999  if the customer is not exposed any more.

IF Number_Months_Expose=16 then do;gk17=999;end;

IF Number_Months_Expose=15 then do;gk17=999 ;gk16=999;end;

IF Number_Months_Expose=14 then do;gk17=999 ;gk16=999;gk15=999;end;

and so on

IF Number_Months_Expose=1 then do;gk17=999 ;gk16=999;gk15=999;and so on  gk2=999;end;

What is the way to write it in macro please?

Here is the direction that I think should be done but still don't know how to do it.

 

%let n=17;/*Number of follow up variables*/

 

%macro g;

%DO i=%EVAL(&n.-1) %TO  1  %BY -1;

%DO k=&i %TO &n. %BY 1;

HERE need to write  IF statements

%end;

%end;

%mend g;

 

Data wanted;

set Rawtbl;

%g;

Run;

 

 

Data Rawtbl;
input ID Number_Months_Expose gk1 gk2 gk3 gk4 gk5 gk6 gk7 gk8 gk9 gk10 gk11 gk12 gk13 gk14 gk15 gk16 gk17;
cards;
DATA FOR example
Run;

 

 

 


Here's a tutorial on using Arrays in SAS
https://stats.idre.ucla.edu/sas/seminars/sas-arrays/

biopharma
Quartz | Level 8

Agree with others that this does not need a macro. My solution is similar to Reeza's except that I have taken the precaution to account when someone has had the max exposure of 17 months. In that case the array will try to initialize the 18th element which doesn't exist and will result in an error.

 

*rawdata* ;
data raw ;
   array gk (17) ;
   do id = 1 to 5 ;
      number_months_exposed = 17 - id ;
      do _n_ = 1 to dim(gk) ;
         gk(_n_) = 3 ;
      end ;
      output ;
   end ;
run ;

data want ;
   set raw ;
   array gk (17) ;
   if number_months_exposed<17 then
   do _n_ = number_months_exposed+1 to dim(gk) ;
      gk(_n_) = 999 ;
   end ;
run ;
Kurt_Bremser
Super User

Just to illustrate what an advantage you gain by having intelligent data structures:

Data Rawtbl;
input ID Number_Months_Expose gk1 gk2 gk3 gk4 gk5 gk6 gk7 gk8 gk9 gk10 gk11 gk12 gk13 gk14 gk15 gk16 gk17;
cards;
A 14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
;

proc transpose data=rawtbl out=trans (rename=(col1=grade));
var gk:;
by id;
run;

/* the following create your datasets as they should look like */ 
data have_patient;
set rawtbl;
keep id Number_Months_Expose;
run;

data have_grade;
set trans;
period = input(substr(_name_,3),2.);
run;

Up to here, we've only converted your data to a structure it should have from the beginning; if your data arrives in SAS in the wide format, this code is what you need to do on import.

 

Your wanted code then looks like this:

data want_grade;
merge
  have_grade
  have_patient
;
by id;
if period > Number_Months_Expose then grade = 999;
drop Number_Months_Expose; /* we don't want redundant information to clutter up the dataset */
run;

No arrays, no macros, dead simple.

 

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 5 replies
  • 446 views
  • 0 likes
  • 5 in conversation