BookmarkSubscribeRSS Feed
Sam28041977
Calcite | Level 5

hello,

the algorithme that is described bellow. my full macro is bellow also. the input of the macro is a 2 columns datasets (lab and result). this algorithm detect labs with deviations. 

Capture.JPG

%macro prof(var=,data=);
data &data.;
set anadat.&data.;
if &var ne .;
run;
proc means data=&data.;
	where &var. ne .;
	var &var.;
	output out=a median=x;
run;

PROC SQL;
	SELECT x INTO:X0 FROM a;
QUIT;

PROC SQL;
	CREATE TABLE &var. AS SELECT Lab, &var. as &var.0, (ABS(&var.-&x0.)) AS DIFF0 FROM &data.;
QUIT;

proc means data=&var. median;
	var Diff0;
	output out=b median=s;
run;

PROC SQL;
	SELECT (S*1.483) INTO:S0 FROM B;
	SELECT (S*1.483*1.5) INTO:sigma0 FROM B;
QUIT;
DATA &var.S0;
ITER=0;X=ROUND(&X0.,.01);S=ROUND(&S0.,.01); Sigma=ROUND(&sigma0.,.01); 
X_=&X0;S_=&S0; Sigma_=&sigma0; OUTPUT;
RUN;

DATA &VAR.;
SET &VAR.;
DROP DIFF0;
RUN;

%do i=1 %to 100;
%put %cmpres(&&&&x%eval(&i.-1));
data &var.;
	SET &var.;
	if &var.0 ne . and &var.0<(%cmpres(&x%eval(&i.-1))-%cmpres(&sigma%eval(&i.-1))) then &var.&i.=(%cmpres(&x%eval(&i.-1))-%cmpres(&sigma%eval(&i.-1)));
	else if &var.0 ne . and &var.0>(%cmpres(&x%eval(&i.-1))+%cmpres(&sigma%eval(&i.-1))) then &var.&i.=(%cmpres(&x%eval(&i.-1))+%cmpres(&sigma%eval(&i.-1)));
	else if &var.0 ne . then &var.&i.=&var.0;
run;

PROC SQL;
	SELECT mean(&var.&i.) INTO: x&i. FROM &var.;
	SELECT (1.134*std(&var.&i.)) INTO: s&i. FROM &var.;
	SELECT (1.5*1.134*std(&var.&i.)) INTO: sigma&i. FROM &var.;
QUIT;
DATA &var.S&i.;
ITER=&i.;X=ROUND(&&X&i.,.01);S=ROUND(&&S&i.,.01); Sigma=ROUND(&&sigma&i.,.01);
X_=&&X&i.;S_=&&S&i.; Sigma_=&&sigma&i.;OUTPUT;
RUN;
%if &i.>1 %then %Do;
	DATA _NULL_;
		CALL symput ('x_',round(&&x&i.,.01));
		CALL symput ('x__',round(%cmpres(&x%eval(&i.-1)),.01));
		CALL symput ('x___',round(%cmpres(&x%eval(&i.-2)),.01));
		CALL symput ('s_',round(&&s&i.,.01));
		CALL symput ('s__',round(%cmpres(&s%eval(&i.-1)),.01));
		CALL symput ('s___',round(%cmpres(&s%eval(&i.-2)),.01));
	RUN;

	%if (&x_. eq &x__.) and (&s_. eq &s__.) and (&x_. eq &x___.) and (&s_. eq &s___.)%then %do;
	DATA &var._;
		SET &var.;
		FORMAT Z 5.2 Z_ $10. BIAS 5.2 BIAS_ $10. X S 5.2;
		X=&&x&i.;
		S=&&s&i.;
		IF &var.0 NE . THEN Z=(&var.0-&&x&i.)/&&s&i.;
		IF &var.0 NE . THEN BIAS=(&var.0-&&x&i.);
		if Z<-3 or z>3 then DO;
			IF Z NE . THEN Z_=compbl(put(Z,5.2)!!"A");
			IF BIAS NE . THEN BIAS_=compbl(put(BIAS,5.2)!!"A");
		end;
		else if Z<-2 or z>2 then DO;
			IF Z NE . THEN Z_=compbl(put(Z,5.2)!!"W");
			IF BIAS NE . THEN BIAS_=compbl(put(BIAS,5.2)!!"W");
		end;
		else DO;
			Z_=put(Z,5.2);
			BIAS_=put(BIAS,5.2);
		end;
		label Lab="Lab" X="Assigned value (Robust Estimate)" S="Standard Deviation (Robust Estimate)"
			  BIAS="Estimate of Lab Bias" BIAS_="Estimate of Lab Bias (With Flag)"
			  Z="Z Score" Z_="Z Score (With Flag)";
		KEEP Lab &VAR.0 X S BIAS BIAS_ Z Z_;
	run;
	proc sql;
	create table anadat.&var. as select Lab, &var.0, X, S, BIAS, BIAS_, Z, Z_
	from &var._;
	quit;
 
	DATA &var.S;
	SET &var.S0 %do g=1 %to &i.; &var.s&g. %end;;
	RUN;
	%goto exit;
	%end;
%end;
%end;
%exit:
/*proc datasets library=work;
	delete &var.S: S:;
quit; */
%mend prof;
%prof(var=WR10_S,data=%str(DATA));

 

 

Astounding
PROC Star

So in some cases, you fixed the problem, changing & to &&.  (In one place, you even used &&&& which doesn't hurt anything, since &&&& resolves to && anyway.)

 

In a bunch of other places you left a single & where you require &&.  So you are still getting the error message, but macro language is not that helpful in describing where the error occurs.  Do you need help in understanding when to change & to && so that the macro expressions resolve correctly?

Sam28041977
Calcite | Level 5

hello Astounding,

adding & or && or &&& don't resolved the problem.

But what I wanted to explain from the begining is that I don't understand the warning because the macros variable resolve correctly whatever the number of &.

I provided a small macro that show that the result is correct but I still have a warning.

krs

Tom
Super User Tom
Super User

@Sam28041977 wrote:

hello Astounding,

adding & or && or &&& don't resolved the problem.

But what I wanted to explain from the begining is that I don't understand the warning because the macros variable resolve correctly whatever the number of &.

I provided a small macro that show that the result is correct but I still have a warning.

krs


When the macro processor sees a macro variable reference it replaces the reference with the value of the macro variable.  But when you reference a macro variable that doesn't exist the macro processor generates a warning and then DOES NOTHING with the incoming text. 

 

Because you are then using the resulting text  in a place where the macro processor will re-process the resulting string is why it ultimately generates the desired result.  The second time it processes it the macro processor sees a valid macro variable reference.

 

You can see the same result with code like this.

%let x2=TWO;

%put &x%eval(1+1);
%Put %unquote(&x%eval(1+1));

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
  • 18 replies
  • 1035 views
  • 1 like
  • 6 in conversation