BookmarkSubscribeRSS Feed
Jack2012
Obsidian | Level 7

I put a macro from one PharmaSUG paper here to seek you help to resovle the issue that : ERROR: Invalid reference value for _group.

/*
Data requirements:
 1. Input dataset assumed to be one record per subject.
 2. Stratification (macro var _stratavar) needs a numeric variable.
 Data need another variable <_stratavar>_c has corresponding label for
 proc format. e.g. TRTPN/TRTPN_C: 1/Drug A, 2/Placebo.
*/
%macro mKMplot ( _indata= /*Required.Input dataset assumed to be one record per
 subject*/
 ,_timevar= /*Required. Time variable*/
 ,_censorvar= /*Required. Censoring variable, should include value
 to identify a censored observation e.g: HYPER(0),
 0 is censor*/
 ,_stratavar= /*Permissible. Analysis stratification for KM,
 usually treatment group.*/
 ,_stratalis= /*Permissible. Study stratification groups*/
 ,_datafl= /*Permissible. Data filter for LIFETEST and PHREG
 (where=(&datafl)), please use SAS logic. e.g.
 GROUP=1*/
 ,_tinterval= /*Permissible. Time interval for displaying.
 Default =3*/
 ,_header= /*Permissible. The header of the figure*/
 ,_Xlabel= /*Permissible. The label of X-axis (Time interval)*/
 ,_Ylabel= /*Permissible. The label of Y-axis (Survival)*/
 ,_ARtitle= /*Permissible. The label of Number of subjects at
 risk*/
 ,_Refline= /*Permissible. Present reference line for median
 survival rate. Default=N.*/
 ,_ref= /*Permissible. Study reference group*/
 ,_fnmed= /*Permissible. The footnote shows survival median or
 not. Default=N.*/
 ,_fnhr= /*Permissible. The footnote shows hazard ratio or
 not. Default=N.*/
 ,_fnp= /*Permissible. The footnote shows pvalue for hazard
 ratio or not. Default=N.*/
 ,_outtype= rtf /*Permissible. Output document type. Default=rtf.*/ );

/*-----------------------*/
/* ticks for X-axis */
/*-----------------------*/
%if &_TINTERVAL = %then %let _TINTERVAL = 3; /*default=3*/
proc sql noprint;
 select &_TINTERVAL.*ceil((max(&_TIMEVAR.)/&_TINTERVAL.)) into: _maxi
 from &_INDATA.
 ;
quit;

%put &_maxi.;

/*-----------------------*/
/* strata */
/*-----------------------*/
%if &_STRATAVAR.= %then %do;
 data &_INDATA.;
 set &_INDATA.;
 DMY = 1;
 DMY_C = "All Subjects";
 run;
 %let _STRATAVAR = DMY;
%end;
/*-----------------------------*/
/* label for strata: STRATA */
/*-----------------------------*/
proc sort data= &_INDATA out = fmt nodupkey;
 by &_STRATAVAR.;
 run;
%let _STRATAVAR_C = %sysfunc(cats(%scan(&_STRATAVAR.,1),_C));

%put &_STRATAVAR_C;

data fmt (keep=fmtname type start label &_STRATAVAR.);
 set fmt end=eos;
 by &_STRATAVAR.;

 retain fmtname "STRATA" type "N";
 length start end $8. label $40.;
 start = strip(put(_N_,best.));
 end = strip(put(_N_,best.));
 label = "&_STRATAVAR_C.";
 if eos then call symputx ('_Nstrata', _N_);
run;
proc format library=work cntlin=fmt;
run;
/*-------------------------------------------------------------------------------*/
/*PROC LIFETEST for KM-plot, subject at risk, survival rate median, event numbers*/
/*-------------------------------------------------------------------------------*/
ods graphics / reset;
ods exclude all;
ods trace on;
ods output survivalplot=zz_plotdata CensoredSummary=zz_esum Quartiles=zz_qtp
 %if &_Nstrata.>= 2 %then HomTests=zz_htest ;;
proc lifetest data=&_INDATA %if %bquote(&_DATAFL.) ne %then %do; %str((where=(&_DATAFL.))) %end;
 method=pl
 plots=survival(atrisk(outside)=0 to &_maxi. by &_TINTERVAL.);;
 ods select SurvivalPlot CensoredSummary Quartiles %if &_Nstrata.>= 2 %then Homtests;;
 time &_TIMEVAR. * &_CENSORVAR.;
 strata &_STRATAVAR.;;
run;
data zz_plotdata;
 set zz_plotdata;
 by STRATUM;
 retain CUMEVENT SURVPROB;
 if first.STRATUM then do;
 CUMEVENT=0;
 SURVPROB=1;
 end;
 else do;
 if EVENT ^= . then CUMEVENT=CUMEVENT+EVENT;
 if SURVIVAL ^= . then SURVPROB=SURVIVAL;
 end;
run;
/*-----------------------*/
/* Data for plot */
/*-----------------------*/
data fSURVIVAL;
 set zz_plotdata;
 format STRATUMNUM strata.;
run;
/*------------------------*/
/* footnote event/ median */
/*------------------------*/
proc sql;
 create table fn1_0 as
 select a.&_STRATAVAR., a.STRATUM, a.TOTAL, a.FAILED, b.ESTIMATE, b.LOWERLIMIT, b.UPPERLIMIT
 from zz_esum as a
 left join zz_qtp (where=(PERCENT=50)) as b
 on a.&_STRATAVAR.=b.&_STRATAVAR.
 having ^missing(&_STRATAVAR.)
 
  order by STRATUM
 ;
quit;
%if &_REF= %then %do;
 data _null_;
 set fmt end=eos;
 by START;
 if eos then call symputx ('_REF', input(&_STRATAVAR.,best.));
 run;
%end;
proc sql;
 select LABEL into: _REFGP
 from fmt
 where &_STRATAVAR. = &_REF
 ;
quit;
data fn1;
 set fn1_0;
 by STRATUM;
 /*length setting- for output space*/
 %if &_fnmed=Y %then %do; length x $100.; %end;
 %else %do; length x $120.; %end;

 if missing(TOTAL) then TOTAL=0;
 if missing(FAILED) then FAILED=0;

 array zero1(*) ESTIMATE LOWERLIMIT UPPERLIMIT;
 array zero2(*) $8. ESTIMATE_ LOWERLIMIT_ UPPERLIMIT_;
 do i=1 to dim(zero1);
 if missing(zero1(i)) then zero2(i)="NA";
 else zero2(i) = strip(put(zero1(i),5.1));
 end;

 x1 = cats("Events : ", put(FAILED,best.) , "/", put(TOTAL,best.));
 x2 = cats("Median : ", ESTIMATE_, " (", LOWERLIMIT_, ",", UPPERLIMIT_, ")" );
 %if &_fnmed=Y %then %do; x = catx(", ", x1, x2); %end;
 %else %do; x = x1; %end;
 if &_stratavar = &_ref then call symputx ('_FAILED', FAILED); /*Failed - event number of ref
group*/
run;
/* depends on statification numbers */
%do i=1 %to &_Nstrata.;
 %global _event_&i;
 data _null_;
 set fn1;
 if _n_=&i. then call symput("_event_&i.",x);
 run;
%end;
/*footnote HR and P, at least Straum >1*/
%if &_Nstrata.>= 2 %then %do;
ods output ParameterEstimates=zz_hazard;
proc phreg data=&_INDATA. %if %bquote(&_DATAFL.) ne %then %str((where=(&_DATAFL.)));;
 ods select ParameterEstimates;
 class &_STRATAVAR. (ref="&_REF.") &_STRATALIS.;
 model &_TIMEVAR.* &_CENSORVAR.=&_STRATAVAR./ties=EXACT risklimits alpha=0.05 ;
 strata &_STRATALIS.;
run;
ods exclude none;
proc sql;
 create table fn2_0 as
 select a.*,b.LABEL as _STRATANAME, monotonic() as _N_ 
 from zz_hazard as a
 left join FMT as b
 on input(a.CLASSVAL0,best.)=b.&_STRATAVAR.
 ;;
quit;
%do i=1 %to %eval(&_Nstrata.-1);
 proc sql;
 select _STRATANAME into: _STRATANAME_&i
 from fn2_0
 where _N_ = &i.
 ;
 quit;
 %put &&_STRATANAME_&i ;
%end;
data fn2;
 set fn2_0;
 array zero1(*) HAZARDRATIO HRLOWERCL HRUPPERCL PROBCHISQ;
 array zero2(*) $8. HAZARDRATIO_ HRLOWERCL_ HRUPPERCL_ PROBCHISQ_;
 do k=1 to dim(zero1);
 %if &_FAILED. ^= 0 %then %do;
 if missing(zero1(k)) then zero2(k)="NA";
 else zero2(k) = strip(put(zero1(k),5.2));
 %end;
 end;
 if . < PROBCHISQ < 0.001 then PROBCHISQ_ = "<0.001";
 else if PROBCHISQ > 0.999 then PROBCHISQ_ = ">0.999";
 %if &_fnhr=Y %then %do;

 %do i=1 %to %eval(&_Nstrata.-1);
 %global _hr1_&i _hr2_&i _hr3_&i _hr4_&i;
 if _n_ = &i then do;
 %if &_Nstrata. = 2 %then
 %let _hr1_&i = %str(Hazard ratio (reference=%trim(&_REFGP.)) : );
 %if &_Nstrata. > 2 %then
 %let _hr1_&i = %str(Hazard ratio for %trim(&&_STRATANAME_&i)
(reference=%trim(&_REFGP.)) : );
 %if &_FAILED. = 0 %then %do;
 %let _hr2_&i = {unicode '221e'x};
 call symput ("_hr3_&i" , " (NA,NA)");
 %end;
 %else %do;
 call symput ("_hr2_&i" , cats(HAZARDRATIO_));
 call symput ("_hr3_&i" , " (" || cats(HRLOWERCL_, ",",
HRUPPERCL_, ")"));
 %end;
 %if &_fnp=Y %then call symput ("_hr4_&i" , cats(", p-value : ", PROBCHISQ_));;
 end;
 %put &&_hr1_&i &&_hr2_&i &&_hr3_&i &&_hr4_&i;
 %end;
 %end;
run;
%end;
/*------------------------*/
/* for output */
/*------------------------*/
%let _lev2=%sysevalf((%sysevalf(&_Nstrata)*.04)+.01);
%let _lev3=%sysevalf(&_lev2);
%let _lev4=%sysevalf((%sysevalf(&_Nstrata-1)*.04)+.01);
%let _lev1=%sysevalf(1-&_lev2-&_lev3-&_lev4);
%put &_lev1 &_lev2 &_lev3 &_lev4; 
%macro temp;
proc template;
 define statgraph f_SURVIVAL;
 dynamic TOTAL FAILED ;
 mvar _Nstrata _ARtitle _Ylabel _Xlabel _header _lev1 _lev2 _lev3 _lev4;
 begingraph / border=FALSE designwidth=20cm designheight=14cm;
 layout lattice / rows=4 rowweights=(&_lev1 &_lev2 &_lev3 &_lev4) rowgutter=0
columndatarange=union ;

 /*1st cell- KM plot*/
 cell;
 layout overlay / border=false
 yaxisopts=(offsetmin=0 linearopts=(thresholdmin=0 viewmin=0
 tickvaluesequence=(start=0 end=1 increment=.1))
 %if &_Ylabel^= %then %do; label=&_Ylabel. labelattrs=(size=9pt) %end;)
 xaxisopts=(offsetmin=0 display=(line label ticks tickvalues)
 %if &_Xlabel^= %then %do; label=&_Xlabel. labelattrs=(size=9pt) %end;
 linearopts=(thresholdmin=0 tickvaluesequence=(start=0 end=%eval(&_maxi)
increment=%eval(&_tinterval) )));
 scatterplot x=TIME y=CENSORED / group=STRATUMNUM name="scat";
 stepplot x=TIME y=SURVIVAL / group=STRATUMNUM name="step";
 %if &_Refline=Y %then %do; referenceline y=0.5 / lineattrs=(color=lightgray); %end;
 endlayout;
 endcell;

 /*2nd cell- AT Risk*/
 cell;
 %if &_ARtitle^= %then %do;
 cellheader;
 entry halign=left textattrs=(size=8pt weight=bold) &_ARtitle. / border=FALSE;
 endcellheader;
 %end;
 layout overlay/ walldisplay=none xaxisopts=(display=none);
 blockplot x=TATRISK block=ATRISK / class=STRATUMNUM blockindex=STRATUMNUM
 repeatedvalues=true display=(label values)
 valuehalign=start valuefitpolicy=truncate
valueattrs=graphdatatext(size=8pt)
 labelposition=left labelattrs=graphvaluetext
labelattrs=(size=8pt) includemissingclass=false;
 endlayout;
 endcell;
 /*3rd cell- Event Number*/
 cell;
 layout overlay/ walldisplay=none xaxisopts=(display=none) pad=(top=0 left=5 bottom=0);
 discretelegend "step" / valueattrs=(size=8pt) border=false displayclipped=true halign=left;
 layout gridded / rows=&_Nstrata. border=false;
 %do i=1 %to &_Nstrata.;
 entry halign=left textattrs=(size=8pt) "%nrbquote(&&&_event_&i)" ;
 %end;
 endlayout;
 endlayout;
 endcell;
 /*4th cell- Hazard Ratio*/
 %if &_Nstrata. >=2 %then %do;
 cell;
 layout overlay/ walldisplay=none xaxisopts=(display=none);
 layout gridded / rows=%eval(&_Nstrata.-1) border=false halign=left;
 %do i=1 %to %eval(&_Nstrata.-1);
 %if &_FAILED. ^= 0 %then %do; entry halign=left textattrs=(size=8pt) " " "&&_hr1_&i"
"&&_hr2_&i" "&&_hr3_&i" "&&_hr4_&i"; %end;
 %else %if &_FAILED. = 0 %then %do; entry halign=left textattrs=(size=8pt) " "
"&&_hr1_&i" &&_hr2_&i "&&_hr3_&i" "&&_hr4_&i"; %end;
 %end;
 endlayout;
 endlayout;
 endcell; 
 
 %end;
 endlayout;
 endgraph;
 end;
run;
quit;
%mend temp;

%temp;
options orientation=landscape papersize=letter nodate nonumber;
ods noproctitle escapechar="`";
ods listing style=listing;
ods graphics / reset noborder imagename="fSURVIVAL" ;
ods listing gpath="&_outputPath\";
ods &_OutType file ="&_outputPath\survival.&_outtype"
 style=listing nogfootnote nogtitle bodytitle toc_data headery=720 footery=720;
proc sgrender data=fSURVIVAL template=f_SURVIVAL
 %if &_HEADER^= %then description=&_HEADER.;;
run;
ods &_OutType close;
ods listing ;
%mend mKMplot; 


data bmt;
	set sashelp.bmt;
	T_M=T/30.4375;/*Time from Unit of Days to Month*/
	if group="ALL" then _group=1;
	else if group = "AML-Low Risk" then _group=2;
	else if group="AML-High Risk" then _group=3;
    
run;
PROC FORMAT;
 VALUE STRATA 1="ALL"
              2="AML-Low Risk"
			  3="AML-High Risk";
RUN;

proc lifetest data=bmt method=pl alpha=.05 outsurv=ci95 plots=survival;
 time T_M*STATUS(1);
 strata GROUP;
run;
%let outputpath=D:;
/*===By use of the above macro to generate enhanced K=M Plot===*/
%mKMplot ( _indata= BMT
,_timevar= T_M
,_censorvar= STATUS(1)
,_stratavar= GROUP
,_tinterval= 10
,_ref= 0
,_stratalis=
,_datafl=
,_header= "Figure 1: Kaplan-Meier Plot of Median Follow-up"
,_Xlabel= "Time (Month)"
,_Ylabel= "Probability of follow-up"
,_ARtitle="Number of Subjects of at risk"
,_Refline= Y
,_fnmed= Y
,_fnhr= N
,_fnp= N
,_outtype=rtf);


 

3 REPLIES 3
japelin
Rhodochrosite | Level 12

Have you checked with the authors of the PharmaSUG paper?
Have you narrowed down which data/proc step has the problem?

 

Try submitting with

options mprint mlogic;
Jack2012
Obsidian | Level 7
Thank you. Actually, I have tried the code seem problematic from below snippet:
/*footnote HR and P, at least Straum >1*/
%if &_Nstrata.>= 2 %then %do;
ods output ParameterEstimates=zz_hazard;
proc phreg data=&_INDATA. %if %bquote(&_DATAFL.) ne %then %str((where=(&_DATAFL.)));;
ods select ParameterEstimates;
class &_STRATAVAR. (ref="&_REF.") &_STRATALIS.;
model &_TIMEVAR.* &_CENSORVAR.=&_STRATAVAR./ties=EXACT risklimits alpha=0.05 ;
strata &_STRATALIS.;
run;
FreelanceReinh
Jade | Level 19

Hi @Jack2012,


@Jack2012 wrote:

ERROR: Invalid reference value for _group.


You specified

,_stratavar= GROUP
...
,_ref= 0

in the macro call, but neither variable GROUP nor variable _GROUP (which must have been used when the error message occurred) have a (formatted) value of "0". I think you really should use variable _GROUP. Then parameter _ref must get one of the values of _GROUP, i.e., 1, 2 or 3 (your choice):

,_stratavar= _GROUP
...
,_ref= 1

 

There also seem to be other issues. One is easy to correct: You define a macro variable OUTPUTPATH (in a %LET statement), but the macro uses _OUTPUTPATH.

 

sas-innovate-white.png

🚨 Early Bird Rate Extended!

Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9.

 

Lock in the best rate now before the price increases on April 1.

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 3 replies
  • 929 views
  • 0 likes
  • 3 in conversation