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-wordmark-2025-midnight.png

Register Today!

Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.


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
  • 854 views
  • 0 likes
  • 3 in conversation