BookmarkSubscribeRSS Feed
kc001
Fluorite | Level 6

 

options symbolgen;
%macro mac01(data=prac.mac01);
data _NULL_;
set &data(keep=Make);
%local first_make;
%IF _N_ = 1 %THEN %DO;
&first_make = Make;
call symput("First", &first_make);
%END;
%put &First;
run;

proc print data=&data(firstobs=1 obs=5 keep=Make) noobs;
run;
%mend mac01;

%scoreit(program=mac01)
options nosymbolgen;
 139        options symbolgen;
 140        %macro mac01(data=prac.mac01);
 141        data _NULL_;
 142        set &data(keep=Make);
 143        %local first_make;
 144        %IF _N_ = 1 %THEN %DO;
 145        &first_make = Make
 146        call symput("First", &first_make);
 147        %END;
 148        %put &First;
 149        run;
 150        
 151        proc print data=&data(firstobs=1 obs=5 keep=Make) noobs;
 152        run;
 153        %mend mac01;
 154        
 155        %scoreit(program=mac01)
 SYMBOLGEN:  Macro variable PROGRAM resolves to mac01
 SYMBOLGEN:  Macro variable DATA resolves to prac.mac01
 WARNING: Apparent symbolic reference FIRST not resolved.
 &First
 
 NOTE: There were 428 observations read from the data set PRAC.MAC01.
 NOTE: DATA statement used (Total process time):
       real time           0.00 seconds
       cpu time            0.00 seconds
       
 
 SYMBOLGEN:  Macro variable DATA resolves to prac.mac01
 
 NOTE: There were 5 observations read from the data set PRAC.MAC01.
 NOTE: PROCEDURE PRINT used (Total process time):
       real time           0.05 seconds
       cpu time            0.06 seconds
       
 
 156        options nosymbolgen;
 157        
 158        
 159        OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
 171        

 

I cannot resolve the First macro variable, can anyone help me with that? The data is from sashelp.cars and the task is to write a macro to extract the first make value which is character.

 

9 REPLIES 9
Sajid01
Meteorite | Level 14

Hello
I have made changes to the code as follows:-

%macro mac01(data=prac.mac01);
data _NULL_;
set &data(keep=Make);
%local first_make;
%IF _N_ = 1 %THEN %DO;
%let first_make = Make
call symput("First", &first_make);
%END;
run;
%put &First;
proc print data=&data(firstobs=1 obs=5 keep=Make) noobs;
run;
%mend mac01;

Have a look at this article
https://support.sas.com/resources/papers/proceedings/proceedings/sugi29/243-29.pdf 

and this

https://support.sas.com/resources/papers/proceedings17/1516-2017.pdf 

kc001
Fluorite | Level 6
The code still does not work. Does the code work on you side? Thanks
Kurt_Bremser
Super User

Your data step should be this:

data _null_;
set &data (keep=make);
call symput("first",make);
stop;
run;

It will execute the CALL SYMPUT once and immediately terminate, so you avoid reading the whole dataset for nothing.

Tom
Super User Tom
Super User

The question does not make much sense.

The data is from sashelp.cars and the task is to write a macro to extract the first make value which is character.

What does "make value which is character" mean?  The variable MAKE in SASHELP.CARS is a character variable. So all of the values are character by definition.  Do you mean look for character strings that cannot be converted into a number?  None of the values of MAKE in SASHELP.CARS can be converted into a number.

 

 

 

kc001
Fluorite | Level 6
I just want to clarify that the variable type of Make is character, there is no any conversion.
Tom
Super User Tom
Super User

Forget about macro code or macro variables.  Figure out what SAS code you need.  There are a lot of ways to check the type of a variable.  There is the VTYPE() function for example.

data _null_;
  if 0 then set sashelp.cars ;
  call symputx('type',vtype(make));
run;
%put &=type ;

You could use PROC CONTENTS to get all of the variables and check the TYPE variable in that.

proc contents data=sashelp.cars noprint out=contents; run;
proc print data=contents;
 where upcase(name)='MAKE';
 var name type;
run;
Kurt_Bremser
Super User

To the macro language, everything is text. So

%IF _N_ = 1 %THEN %DO;

compares the text "_N_" with the text "1", which are obviously not equal, so the code between the %DO and %END is not created.

I suggest you use data step language there.

sbxkoenk
SAS Super FREQ

Here's the data step language @Kurt_Bremser is talking about.

No idea why you make the detour via &first_make so I skipped that.

 

I suggest you also make use of the mprint option.

 

options mprint symbolgen;
%macro mac01(data=);
%GLOBAL First;
data _NULL_;
 set &data(keep=Make);
 if _N_=1 then 
  call symput("First", strip(Make));
run;
%mend mac01;
%mac01(data=sashelp.cars)
%PUT &=First;
/* end of program */

You can drop the "if _N_=1 then" (part of the programming statement where the macro var First is created)

if you only read in the first observation

set &data(keep=Make obs=1);

The latter solution is also much faster when the input dataset is BIG!

 

I hope this is what you are looking for because I'm also distracted by your "first MAKE value which is character".

Maybe you want to use the ANYALPHA Function or the NOTALPHA function??

 

Cheers,

Koen

Sajid01
Meteorite | Level 14

I agree with @sbxkoenk .
It is better to drop if_N_=1 and use set &data(keep=Make obs=1);
This will only read only one observation and the program will execute faster

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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
  • 9 replies
  • 999 views
  • 7 likes
  • 5 in conversation