Hello,
I would appreciate if someone could check my macro code below to see how best I can display the results of the written macro. Thanks.
My main objectives:
My code and log are found below:
I have tried many code to display/view the macros results but none of them worked.[I checked SAS forum and documentation too, but no solution found].
Help needed, please.
Thanks.
Ak.
data small_data;
input id$ 1-6 job 7-8 jobyrin 9-11 jobyrout 18-20 icode$ 23-27 lung$ 29-35;
datalines;
OSa13 3 73 78 6191 cacase
OSa30 1 39 46 7181 cacase
OSa30 3 56 64 6191 cacase
OSa73 1 23 31 7181 popcon
OSa73 2 31 42 5130 popcon
OSa86 3 46 60 6198 cacon
OSa86 4 60 70 5130 cacon
OSa93 3 68 72 6121 popcon
OSf26 1 54 54 6198 popcon
OSf26 2 70 70 6191 popcon
OSh77 1 63 66 6121 cacon
OSh77 2 66 70 6121 cacon
OSh77 3 70 71 6121 cacon
OSi84 1 67 75 6191 cacase
OSi84 2 75 81 6191 cacase
;
proc print data=small_data;
data jobd; set small_data; drop lung;
proc freq data=jobd;
tables job; run;
proc print data=jobd;
run;
/* MACRO TEST*/
*max 4 jobs per subject in multi dataset so macro will consider a maximum of 4 potential jobs;
%macro duration(database=small_data,icode=6191, Job_title=plumber);
*Creating a dataset containing all the jobs with the selected CCDO 4-digit code;
data &Job_title;
set &database;
if icode = &6191;
run;
*transposing dataset so that the YEARIN and YEAROUT of all jobs held by a subject are in the same row;
*YEARIN;
proc transpose data = &Job_title out = &Job_title._yearin prefix = YEARIN;
by ID;
var jobyrin;
run;
proc sort data = &Job_title._yearin;
by id;
run;
*YEAROUT;
proc transpose data = &Job_title out = &Job_title._yearout prefix = YEAROUT;
by ID;
var jobyrout;
run;
proc sort data = &Job_title._yearout;
by id;
run;
data &Job_title._final;
merge &Job_title._yearin &Job_title._yearout;
by ID;
array YEARIN (4) YEARIN1 YEARIN2 YEARIN3 YEARIN4;
array YEAROUT (4) YEAROUT1 YEAROUT2 YEAROUT3 YEAROUT4;
array YEARINv2 (4) YEARIN2 YEARIN3 YEARIN4 ;
array YEAROUTv2 (4) YEAROUT2 YEAROUT3 YEAROUT4;
array YEARIN_F (5) YEARIN1 YEARIN2 YEARIN3 YEARIN4 YEARIN5;
array YEAROUT_F (5) YEAROUT1 YEAROUT2 YEAROUT3 YEAROUT4 YEAROUT5;
Array duration (5) Dur1 Dur2 Dur3 Dur4 Dur5;
do i = 1 to 4;
if yearin(i) ne . and yearinv2(i) ne . and yearinv2(i) le yearout(i) and yearoutv2(i) ge yearout(i) then do; yearinv2(i) = yearin(i); yearin(i) = .;yearout(i) = .;end;
else if yearin(i) ne . and yearinv2(i) ne . and yearinv2(i) le yearout(i) and yearoutv2(i) lt yearout(i) then do; yearinv2(i) = yearin(i);yearoutv2(i) = yearout(i); yearin(i) = .;yearout(i) = .;end;
end;
do i = 1 to 5;
if YEARIN_F(i) = . then YEARIN_F(i) = 0;
if YEAROUT_F(i) = . then YEAROUT_F(i) = 0;
duration(i) = YEAROUT_F(i) - YEARIN_F(i);
if YEARIN_F(i) ne 0 and YEAROUT_F(i) = YEARIN_F(i) then duration(i) = 0.5;
end;
&Job_title._dur = Dur1 + Dur2 + Dur3 + Dur4 + Dur5;
&Job_title._ever = 1;
keep ID &Job_title._dur &Job_title._ever;
run;
%MEND duration;
/* Display the macro results*//*????? I am stuck here*/
proc print data=Job_title._final; run;
Some other issues starting with
data &Job_title;
set &database;
if icode = &6191;
run;
&6191 is not a valid macro reference. Very certain you wanted to use the macro parameter &icode.
Second, is the value of Icode numeric or character? If character, you would need to provide quotes around the macro variable i.e. "&icode."
184 %MEND duration; 185 186 /* Display the macro results*//*????? I am stuck here*/ 187 188 proc print data=Job_title._final; run; ERROR: Libref 'Job_title' exceeds 8 characters.
Has several issues.
First, as @Kurt_Bremser says, you did not attempt to execute the macro.
As a minimum you would have to have something like
%duration
Before the Proc print.
Second if you intend to use the macro parameter in the Proc Print data= then you need to 1) use the proper reference &job_title and 2) it has to be where the macro variable is defined. Currently the macro variable does not exist outside of the macro %duration. OR 3) use the actual name of the created data set would would be Plumber_final if the macro runs and the data set is created.
Be aware that if you make the variable &job_title a global variable so it is available after the execution of the macro Duration then only the LAST value used from the last macro call will be available. So if you do something like
%duration(job_title=plumber, icode=123) %duration(job_title=butcher, icode=456) %duration(job_title=baker, icode=999)
Your proc print outside of the macro could only see &job_title as baker.
If you always want to print the data set then move the Proc print to inside the macro where the parameter would be valid.
Or you need to keep track of the data set name as created an print the one you want.
Since it is a macro parameter, &JOB_TITLE is local to your macro and not available in the global symbol table.
But you never actually called your macro, so no result will be created anyway.
Some other issues starting with
data &Job_title;
set &database;
if icode = &6191;
run;
&6191 is not a valid macro reference. Very certain you wanted to use the macro parameter &icode.
Second, is the value of Icode numeric or character? If character, you would need to provide quotes around the macro variable i.e. "&icode."
184 %MEND duration; 185 186 /* Display the macro results*//*????? I am stuck here*/ 187 188 proc print data=Job_title._final; run; ERROR: Libref 'Job_title' exceeds 8 characters.
Has several issues.
First, as @Kurt_Bremser says, you did not attempt to execute the macro.
As a minimum you would have to have something like
%duration
Before the Proc print.
Second if you intend to use the macro parameter in the Proc Print data= then you need to 1) use the proper reference &job_title and 2) it has to be where the macro variable is defined. Currently the macro variable does not exist outside of the macro %duration. OR 3) use the actual name of the created data set would would be Plumber_final if the macro runs and the data set is created.
Be aware that if you make the variable &job_title a global variable so it is available after the execution of the macro Duration then only the LAST value used from the last macro call will be available. So if you do something like
%duration(job_title=plumber, icode=123) %duration(job_title=butcher, icode=456) %duration(job_title=baker, icode=999)
Your proc print outside of the macro could only see &job_title as baker.
If you always want to print the data set then move the Proc print to inside the macro where the parameter would be valid.
Or you need to keep track of the data set name as created an print the one you want.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!
What’s the difference between SAS Enterprise Guide and SAS Studio? How are they similar? Just ask SAS’ Danny Modlin.
Find more tutorials on the SAS Users YouTube channel.