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.
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
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.
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.
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;
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.
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
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
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.