BookmarkSubscribeRSS Feed
marymarion
Obsidian | Level 7
%macro halfnorm(dsn,varname,n,cancel=);

/* Creates a half-normal plot
  ASSUMPTIONS
=============
Data is N(0,sigma**2)

INPUTS are the effects from a Yates analysis or an ANOVA
========================================================
dsn     = Datafile, this is called by yatesGunstAnova and must stay dsn
varname = variable to be plotted
n       = number of data points to be plotted
cancel  = controls the creation of a fitted regression line through (0,0)
          cancel=no draw
LVREF   = line-type for vertical ref line, 2=dashed line
*/

data halfnormal; set &dsn; 
abs_&varname=abs(&varname);
n=&n;

proc rank data=halfnormal out=ranks;
var abs_&varname;
ranks R;
run; quit; title;

data plotdata; set ranks;
 abs_&varname=abs(&varname);
 RSTAR = (R-.5)/n; 
 p= RSTAR/2 + .5; 
 v = probit(p);   
 run;
 proc print data=plotdata; run;

PROC GPLOT DATA=plotdata; 
plot v*p;
axis1 color=black label=(height=1.5 ) ;
axis2 color=black minor=none;
run cancel; quit; title;

%mysort(plotdata,abs_&varname);
proc gplot data=plotdata;
PLOT v*abs_&varname /VREF=1 LVREF=2 REGEQN haxis=axis1 vaxis=axis2;
SYMBOL V=DOT I=RL0 COLOR=grey height=1.3 pointlabel=(height=10pt '#source' nodropcollisions) ;
TITLE "HALF-NORMAL PLOT";
TITLE2 'FITTED LINE THROUGH THE ORIGIN';
run; quit; title;
 
options nocenter;
goptions reset=all;
ods graphics on;
%mend halfnorm;

%macro yatesGunstAnova(dsn,model,class,numBeta,numBeta2);

title 'GLM WITH CONTINUOUS PREDICTORS';
%glmTemplate;
proc glm data=&dsn;
model &model/ ss3 solution;
ods output OverallAnova=OverallAnova;
ods output ModelAnova=ModelAnova; 
ods output ParameterEstimates=ParameterEstimates;
run; quit;
/* %myprint(ModelAnova); */ 

data BetaEstimates; set ParameterEstimates; 
keep parameter source estimate RawEffect;
source=compress(parameter,'+'); 
source=compress(source,'*');
source=compress(source,'0');
source=compress(source,'-1');
RawEffect=2*estimate;
run; quit;
/* %myprint(BetaEstimates); */

/* Standardized DEJ Effects */
data ModelAnova2; set ModelAnova;
source=source;
source=compress(source,'*');
ms=ms;   
StdzEffect=sqrt(ms);
HypothesisType=HypothesisType;
keep source ms StdzEffect HypothesisType;
run; quit;

data df1; set &dsn; key=_n_; keep key conv; run;
data df2; set ModelAnova2; key=_n_+1; run;
data df3; set BetaEstimates; key=_n_; run;
data df; merge df1 df3 df2; by key; run;

/*
proc print data=df1; title 'df1'; run; quit;
proc print data=df2; title 'df2'; run; quit;
proc print data=df3; title 'df3'; run; quit;
proc print data=df;  title 'df';  run; quit;
*/

proc sort data=df out=df4; by HypothesisType; run; quit;
data df4; set df4;
   if HypothesisType=1 then delete; 
   if MS = . then delete; 
   drop parameter HypothesisType; 
   rename estimate=BetaEstimate;
   run; quit;
data df4;
  retain conv key source BetaEstimate RawEffect Hypothesis Test MS StdzEffect;
  set df4;
run;

proc sort data=df4 out=df4; key StdzEffect / descending; run; quit;
TITLE "df4"; proc print data=df4; run cancel; quit; 
proc sort data=df4 out=df5; key StdzEffect / ascending; run; quit;
title 'df5'; proc print data=df5; run cancel; quit;

%halfnorm(df4,RawEffect,&numBeta);
%halfnorm(df4,StdzEffect,&numBeta);
%halfnorm(df5,StdzEffect,&numBeta2);

%macro save_dataset(df5);
    proc datasets library=work nolist; save df5; 
    quit;
%mend;
%save_dataset(df5);

%mend yatesGunstAnova;

%macro yatesGunstAnova2;
data dsn2; set work.df5;
proc print data=dsn2; run; quit;
%mend;
%yatesGunstAnova2;

proc datasets library=work kill nolist; quit;
data NuclearPilotPlant;
input A B C D conv tc $ random;
A=A;
B=B;
AB=A*B;
C=C;
AC=A*C;
BC=B*C;
ABC=A*B*C;
D=D;
AD=A*D;
BD=B*D;
ABD=A*B*D;
CD=C*D;
ACD=A*C*D;
BCD=B*C*D;
ABCD=A*B*C*D;
StdOrder=_n_;
Total=1;
cards;
-1  -1  -1  -1 70 (1)   8
 1  -1  -1  -1 60  a    2
-1   1  -1  -1 89  b   10
 1   1  -1  -1 81  ab   4
-1  -1   1  -1 69  c   15
 1  -1   1  -1 62  ac   9
-1   1   1  -1 88  bc   1
 1   1   1  -1 81  abc 13
-1  -1  -1   1 60  d   16
 1  -1  -1   1 49  ad   5
-1   1  -1   1 88  bd  11
 1   1  -1   1 82  abd 14
-1  -1   1   1 60  cd   3
 1  -1   1   1 52  acd 12
-1   1   1   1 86  bcd  6
 1   1   1   1 79 abcd  7      
;

%yatesGunstAnova(dsn=NuclearPilotPlant,model=%str(conv=A B A*B C A*C B*C A*B*C D A*D B*D A*B*D C*D A*C*D B*C*D A*B*C*D),
                 class=A B C D,numBeta=15,numBeta2=10);
 
data dsn2; set work.dsn2(obs=10); run; 
proc print; run;


2 REPLIES 2
SASJedi
SAS Super FREQ

When I ran the code you posted, work.df5 was not empty:

conv key source BetaEstimate RawEffect Mean Square StdzEffect
49 10 AD 0.00000000 0 0.000000 0
69 5 C -0.12500000 -0.25 0.250000 0.5
60 13 CD -0.12500000 -0.25 0.250000 0.5
52 14 ACD -0.12500000 -0.25 0.250000 0.5
79 16 ABCD -0.12500000 -0.25 0.250000 0.5
82 12 ABD 0.25000000 0.5 1.000000 1
62 6 AC 0.37500000 0.75 2.250000 1.5
81 8 ABC -0.37500000 -0.75 2.250000 1.5
86 15 BCD -0.37500000 -0.75 2.250000 1.5
81 4 AB 0.50000000 1 4.000000 2
88 7 BC -0.62500000 -1.25 6.250000 2.5
88 11 BD 2.25000000 4.5 81.000000 9
60 9 D -2.75000000 -5.5 121.000000 11
60 2 A -4.00000000 -8 256.000000 16
89 3 B 12.00000000 24 2304.000000 48

 

but there were several problems with the code.

Within the halfnorm macro definition:

  • The PROC GPLOT step  (lined 35-39) closes with a RUN CANCEL, so the step never executes. Why include this code if you don't intend it to run?
  • Macro mysort gets called on line 41, but it was never defined. So, of course, it cannot execute...

On lines 119 to 123:

 

%macro save_dataset(df5);
    proc datasets library=work nolist; save df5; 
    quit;
%mend;
%save_dataset(df5);

 

The definition for macro savedataset will always delete everything from the WORK library except DF5. It's hard-coded - the parameter on the macro definition is totally useless.

Finally, at the end:

 

data dsn2; 
	set work.dsn2(obs=10); 
run; 
proc print; run;
Because you deleted everything from the WORK library except DF5, there is no work.dsn2 dataset for you to read here. And honestly, if you just wanted to print 10 observations, you shouldn't overwrite the original dataset - just use:

 

proc print data=work.dsn2(obs=10);
run;
I think that there are several macros defined here that would have been better written as plain SAS code. 
Check out my Jedi SAS Tricks for SAS Users

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