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

Hi!

 

I would like some help trouble shooting a macro.  I found this  macro online for range checking my variables.  I know there are a lot of ways to range check, but I am hoping to be abl eto build a spreadsheet to not values outside of my acceptable ranges.  This one seems to work with that concepts, but I cannot get the macro to work with my sample data.  I've also attached the pdf with the macro explained by the author.  Any help is greatly appreciated!!

 

data rangetbl;
input @1 errorid $2.
	@3 errorvar $12.
	@15 errorsas $40.;
datalines;
1  usmil	  not(usmil in: (0,1))
2  usciv 	  not(usciv in: (0,1))
3  nonusmil   not(nonusmil in: (0,1))
4  nonusciv   not(nonusciv in: (0,1))
5  EPW 	      not (EPW in: (0,1))
;
run;

data dataset;
input
@1 medid 3.
@4 usmil 3.
@7 usciv 3.
@10 nonusmil 3.
@13 nonusciv 3.
@16 EPW 3.;
datalines;
1	0	0	1	1	2
2	1	0	1	0	0
3	3	1	2	0	0
4	0	2	1	0	0
;
run;

proc sort data=dataset;
by medid;
run;



data _null_;
set rangetbl end=last;
retain count;
	if _n_=1 then count=0;
	count=count+1;
	call symput ('id'||left (trim(put(count,5.))),
		trim (errorid));
	call symput ('var'||left (trim(put(count,5.))),
		trim (errorvar));
	call symput ('code'||left (trim(put(count,5.))),
		trim (errorsas));
if last then call symput
	('checkct',left(trim(put(count,8.))));
run;


%macro checkvar (id, var, check);
if &check then do;
	errorid="&id.";
	errorvar="&var.";
	errorval=&var;
	output;
	end;
%mend checkvar;

data error_ds (keep=medid errorid errorvar errorval);
set dataset;
length errorid errorvar $8 errorval 8.;
%macro runcheck;
	%do j=1 %to &checkct;
	%checkvar (%str (&&id&j),
				%str (&&var&j)
				%str (&&code&j));
			%end;
	%mend runcheck;
	%runcheck;
	run;

 

1 ACCEPTED SOLUTION

Accepted Solutions
ballardw
Super User

Have you looked at the dataset rangetble? There is a chance that the forum has reformatted you text but when I run the code as copy and pasted from the window I get a value of "usmil not" for the first errorvar. I don't have the option expandtabs set and it appears that you have some tabs in the line so that may be a minor bit.

 

You may also want to consider using some of the features that have appeared since 1999 such as Call symputx which removes leading and trailing blanks of the value so you can reduce the trim(left( code.

Also insted of || there is a nice selection of concatenation functions. and Since Count = _n_ in the data _null_ for creating the macro variables as used why add the variable? That approach might be needed if you were doing something with repeaded values but not here.

 

data _null_;
set work.rangetbl end=last;
retain count;
	if _n_=1 then count=0;
	count=count+1;
	call symputx (cats('id',_n_),errorid);
	call symputx (cats('var',_n_),errorvar);
	call symputx (cats('code',_n_),errorsas);
   if last then call symputx('checkct',_n_);
run;

If you are interested in seeing what the macro variables look like use: %put _user_; to see all of your created variables in the current scope.

 

 

Also when you do this:

data error_ds (keep=medid errorid errorvar errorval);
set dataset;
length errorid errorvar $8 errorval 8.;
%macro runcheck; /* <= %macro ends the previously started data set*/
	%do j=1 %to &checkct;
	%checkvar (%str (&&id&j),
				%str (&&var&j)    /*<=missing ,*/
				%str (&&code&j));
			%end;
	%mend runcheck;

the macro definition ends the data step as a boundary like a Run statement or a Proc.

 

Define the macro before the data step that wants to use it. AND heres likely the fatal part: you are missing a , after the VAR parameter call to %checkvar

 

Try

%macro runcheck;
	%do j=1 %to &checkct;
	%checkvar (%str (&&id&j),
				 %str (&&var&j),
				%str (&&code&j));
   %end;
%mend runcheck;

data error_ds (keep=medid errorid errorvar errorval);
   set dataset;
   length errorid errorvar $8 errorval 8.;
	%runcheck;
run;

View solution in original post

2 REPLIES 2
ballardw
Super User

Have you looked at the dataset rangetble? There is a chance that the forum has reformatted you text but when I run the code as copy and pasted from the window I get a value of "usmil not" for the first errorvar. I don't have the option expandtabs set and it appears that you have some tabs in the line so that may be a minor bit.

 

You may also want to consider using some of the features that have appeared since 1999 such as Call symputx which removes leading and trailing blanks of the value so you can reduce the trim(left( code.

Also insted of || there is a nice selection of concatenation functions. and Since Count = _n_ in the data _null_ for creating the macro variables as used why add the variable? That approach might be needed if you were doing something with repeaded values but not here.

 

data _null_;
set work.rangetbl end=last;
retain count;
	if _n_=1 then count=0;
	count=count+1;
	call symputx (cats('id',_n_),errorid);
	call symputx (cats('var',_n_),errorvar);
	call symputx (cats('code',_n_),errorsas);
   if last then call symputx('checkct',_n_);
run;

If you are interested in seeing what the macro variables look like use: %put _user_; to see all of your created variables in the current scope.

 

 

Also when you do this:

data error_ds (keep=medid errorid errorvar errorval);
set dataset;
length errorid errorvar $8 errorval 8.;
%macro runcheck; /* <= %macro ends the previously started data set*/
	%do j=1 %to &checkct;
	%checkvar (%str (&&id&j),
				%str (&&var&j)    /*<=missing ,*/
				%str (&&code&j));
			%end;
	%mend runcheck;

the macro definition ends the data step as a boundary like a Run statement or a Proc.

 

Define the macro before the data step that wants to use it. AND heres likely the fatal part: you are missing a , after the VAR parameter call to %checkvar

 

Try

%macro runcheck;
	%do j=1 %to &checkct;
	%checkvar (%str (&&id&j),
				 %str (&&var&j),
				%str (&&code&j));
   %end;
%mend runcheck;

data error_ds (keep=medid errorid errorvar errorval);
   set dataset;
   length errorid errorvar $8 errorval 8.;
	%runcheck;
run;
jenim514
Pyrite | Level 9
@ballardw THANK YOU so much! It worked perfectly with your suggestions!

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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