BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
ak2011
Fluorite | Level 6

 

 

 

 

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:

  1. For each id, to check if 1st job overlaps with 2nd job: if not do nothing. If yes, assign 1st job start year to 2nd job; and  record 1st job start and end years as missing, to avoid counting the same year as twice. Eg. for Osa73, jobyrout for job 1 is 31; same with jobyrin job 2.
  2. Repeat procedure with newly created 2nd job and 3rd job.
  3. Assign 0 to missing values  and calculate duration of each remaining job; Jobs with same start and end yrs are coded as 0.5 year
  4. Sum all durations to obtain final duration variable
  5. Create ever held job as plumber ie. if icdode 6191=plumber(1=yes).
 

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;


1 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
72
73 data small_data;
74 input id$ 1-6 job 7-8 jobyrin 9-11 jobyrout 18-20 icode$ 23-27 lung$ 29-35;
75 datalines;
 
NOTE: The data set WORK.SMALL_DATA has 15 observations and 6 variables.
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.02 seconds
 
 
91 ;
92 proc print data=small_data;
93
 
NOTE: There were 15 observations read from the data set WORK.SMALL_DATA.
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.22 seconds
cpu time 0.23 seconds
 
 
94 data jobd; set small_data; drop lung;
95
 
NOTE: There were 15 observations read from the data set WORK.SMALL_DATA.
NOTE: The data set WORK.JOBD has 15 observations and 5 variables.
NOTE: DATA statement used (Total process time):
real time 0.02 seconds
cpu time 0.02 seconds
 
 
96 proc freq data=jobd;
97 tables job; run;
 
NOTE: There were 15 observations read from the data set WORK.JOBD.
NOTE: PROCEDURE FREQ used (Total process time):
real time 0.12 seconds
cpu time 0.11 seconds
 
 
98
99
100 proc print data=jobd;
101 run;
 
NOTE: There were 15 observations read from the data set WORK.JOBD.
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.16 seconds
cpu time 0.16 seconds
 
 
102
103
104 /* MACRO TEST*/
105
106 *max 4 jobs per subject in multi dataset so macro will consider a maximum of 4 potential jobs;
107
108
109 %macro duration(database=small_data,icode=6191, Job_title=plumber);
110
111 *Creating a dataset containing all the jobs with the selected CCDO 4-digit code;
112
113 data &Job_title;
114 set &database;
115 if icode = &6191;
116 run;
117
118
119 *transposing dataset so that the YEARIN and YEAROUT of all jobs held by a subject are in the same row;
120
121
122 *YEARIN;
123
124 proc transpose data = &Job_title out = &Job_title._yearin prefix = YEARIN;
125 by ID;
126 var jobyrin;
127 run;
128
129 proc sort data = &Job_title._yearin;
130 by id;
131 run;
132
133 *YEAROUT;
134
135 proc transpose data = &Job_title out = &Job_title._yearout prefix = YEAROUT;
136 by ID;
137 var jobyrout;
138 run;
139
140 proc sort data = &Job_title._yearout;
141 by id;
142 run;
143
144
145
146 data &Job_title._final;
147 merge &Job_title._yearin &Job_title._yearout;
148 by ID;
149
150 array YEARIN (4) YEARIN1 YEARIN2 YEARIN3 YEARIN4;
151 array YEAROUT (4) YEAROUT1 YEAROUT2 YEAROUT3 YEAROUT4;
152 array YEARINv2 (4) YEARIN2 YEARIN3 YEARIN4 ;
153 array YEAROUTv2 (4) YEAROUT2 YEAROUT3 YEAROUT4;
154
155 array YEARIN_F (5) YEARIN1 YEARIN2 YEARIN3 YEARIN4 YEARIN5;
156 array YEAROUT_F (5) YEAROUT1 YEAROUT2 YEAROUT3 YEAROUT4 YEAROUT5;
157 Array duration (5) Dur1 Dur2 Dur3 Dur4 Dur5;
158
159
160
161 do i = 1 to 4;
162
163 if yearin(i) ne . and yearinv2(i) ne . and yearinv2(i) le yearout(i) and yearoutv2(i) ge yearout(i) then do; yearinv2(i)
163 ! = yearin(i); yearin(i) = .;yearout(i) = .;end;
164 else if yearin(i) ne . and yearinv2(i) ne . and yearinv2(i) le yearout(i) and yearoutv2(i) lt yearout(i) then do;
164 ! yearinv2(i) = yearin(i);yearoutv2(i) = yearout(i); yearin(i) = .;yearout(i) = .;end;
165
166 end;
167
168 do i = 1 to 5;
169
170 if YEARIN_F(i) = . then YEARIN_F(i) = 0;
171 if YEAROUT_F(i) = . then YEAROUT_F(i) = 0;
172
173 duration(i) = YEAROUT_F(i) - YEARIN_F(i);
174 if YEARIN_F(i) ne 0 and YEAROUT_F(i) = YEARIN_F(i) then duration(i) = 0.5;
175 end;
176
177 &Job_title._dur = Dur1 + Dur2 + Dur3 + Dur4 + Dur5;
178
179 &Job_title._ever = 1;
180
181 keep ID &Job_title._dur &Job_title._ever;
182 run;
183
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.
 
NOTE: The SAS System stopped processing this step because of errors.
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
 
189
190
191
192 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
204
 
Thanks in advance for your help.
ak.

 






 

1 ACCEPTED SOLUTION

Accepted Solutions
ballardw
Super User

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.

 

 

View solution in original post

2 REPLIES 2
Kurt_Bremser
Super User

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.

ballardw
Super User

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.

 

 

SAS Innovate 2025: Call for Content

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!

Submit your idea!

SAS Enterprise Guide vs. SAS Studio

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.

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
  • 2 replies
  • 593 views
  • 0 likes
  • 3 in conversation