BookmarkSubscribeRSS Feed
RAVI2000
Lapis Lazuli | Level 10

I was trying for a Cumulative Incidence graph. Please correct me.

 


options nodate nonumber; 
data sj.data;
infile datalines dsd truncover;                                                                                                                                                          
input @1 SEQ 2. @4 ARMS $6. @10 armcode 2. @12 event 1. @14  mon 15. ;
datalines;					
01 Dose1 1 0 3.8107752956636
02 Dose1 1 0 2.66097240473062
03 Dose1 1 0 2.43101182654402
04 Dose1 1 0 2.20105124835742
05 Dose1 1 0 1.44546649145861
;

ods output survivalplot = kmdata;
proc lifetest data = test;
	time mon * event(1);
	strata arms;
run;

data kmdata2;
	set kmdata;
	survival2 = (1-survival);
	censor2 = (1-censored);
run;

proc template;
	define statgraph SurvivalPlot;
	begingraph / designwidth=8in designheight=5in;
	entrytitle 'Cumulative Incidence Graph'/ textattrs=(size=12);
	layout lattice;
	layout overlay / xaxisopts =(Label = "Months (Time)" type=linear labelattrs=(size=8pt weight=bold) tickvalueattrs=(size=9pt weight=bold) linearopts=(viewmin=0 viewmax=12 tickvaluelist=(0 2 4 6 8 10 12)))
		yaxisopts=(Label = "Cumulative Incidence" linearopts=(viewmin=0 viewmax=100) labelattrs=(size=8pt weight=bold) tickvalueattrs=(size=9pt weight=bold) linearopts=(viewmin=0 viewmax = 1.0 tickvaluelist=( 0.0 0.2 0.4 0.6 0.8 1.0)));
	stepplot x=mon y = survival2 / group=stratum  lineattrs=(thickness = 3.0 pattern=solid color = orange) name='s';
	scatterplot x=mon y = censor2 / GROUP=stratum name='c' markerattrs=(symbol=plus size=8);
	mergedlegend "c" "s" / location=inside halign=right valign=top order=columnmajor down=2 border=false valueattrs=(size=8pt) pad=(top=5 bottom=5);
	endlayout;
	layout overlay;
	entry halign=left 'N at Risk' /pad=(left=0 ) valign=bottom textattrs=(size=8pt);
	endlayout;
	blockplot x=tatrisk block=atrisk / class=stratum display=(values label) valuehalign=start valueattrs=(size=8) labelattrs=(size=8);
	endlayout;
	endgraph;
	end;
run;

proc sgrender data = kmdata2 template = survivalplot;
run;

Here are warnings which are shown when I run my codes.

376        options nodate nonumber;
377        ods graphics on / noborder;
378        ods output survivalplot = kmdata;

381        proc lifetest data = test;
382        	time prog_mon * prog_event(1);
383        	strata arms;
384        run;

NOTE: The LOGLOG transform is used to compute the confidence limits for the 
      quartiles of the survivor distribution. To suppress using this transform, 
      specify CONFTYPE=LINEAR in the PROC LIFETEST statement.
NOTE: Variable Stratum already exists on file KMDATA, using Stratum2 instead.
NOTE: The homogeneity tests across strata were omitted since there is only one 
      stratum.
NOTE: The data set KMDATA has 6 observations and 8 variables.
NOTE: The PROCEDURE LIFETEST printed page 1.
NOTE: PROCEDURE LIFETEST used (Total process time):
      real time           2.41 seconds
      cpu time            0.11 seconds
      

385        
386        data kmdata2;
387        	set kmdata;
388        	survival2 = (1-survival);
389        	censor2 = (1-censored);
390        run;

NOTE: Missing values were generated as a result of performing an operation on 
      missing values.
      Each place is given by: (Number of times) at (Line):(Column).
      6 at 389:14   
NOTE: There were 6 observations read from the data set KMDATA.
NOTE: The data set KMDATA2 has 6 observations and 10 variables.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds
      

391        
392        proc template;
393        	define statgraph SurvivalPlot;
394        	begingraph / designwidth=8in designheight=5in;
395        	entrytitle 'Cumulative Incidence Graph'/
395      ! textattrs=(size=12);
396        	layout lattice;
397        	layout overlay / xaxisopts =(Label = "Months (Time)"
397      ! type=linear labelattrs=(size=8pt weight=bold)
397      ! tickvalueattrs=(size=9pt weight=bold) linearopts=(viewmin=0
397      ! viewmax=12 tickvaluelist=(0 2 4 6 8 10 12)))
398        		yaxisopts=(Label = "Cumulative Incidence" linearopts=(viewmin=0
398      ! viewmax=100) labelattrs=(size=8pt weight=bold)
398      ! tickvalueattrs=(size=9pt weight=bold) linearopts=(viewmin=0 viewmax =
398      !  1.0 tickvaluelist=( 0.0 0.2 0.4 0.6 0.8 1.0)));
399        	stepplot x=mon y = survival2 / group=stratum
The SAS System

399      ! lineattrs=(thickness = 3.0 pattern=solid color = orange) name='s';
400        	scatterplot x=mon y = censor2 / GROUP=stratum name='c'
400      ! markerattrs=(symbol=plus size=8);
401        	mergedlegend "c" "s" / location=inside halign=right valign=top
401      ! order=columnmajor down=2 border=false valueattrs=(size=8pt)
401      ! pad=(top=5 bottom=5);
402        	endlayout;
403        	layout overlay;
404        	entry halign=left 'N at Risk' /pad=(left=0 ) valign=bottom
404      ! textattrs=(size=8pt);
405        	endlayout;
406        	blockplot x=tatrisk block=atrisk / class=stratum display=(values
406      ! label) valuehalign=start valueattrs=(size=8) labelattrs=(size=8);
407        	endlayout;
408        	endgraph;
409        	end;
NOTE: Overwriting existing template/link: SurvivalPlot
NOTE: STATGRAPH 'SurvivalPlot' has been saved to: SASUSER.TEMPLAT
410        run;
NOTE: PROCEDURE TEMPLATE used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds
      

411        
412        proc sgrender data = kmdata2 template = survivalplot;
413        run;

WARNING: The stepplot statement named 's' will not be drawn because one or more 
         of the required arguments were not supplied.
WARNING: The scatterplot statement named 'c' will not be drawn because one or 
         more of the required arguments were not supplied.
WARNING: The blockplot statement will not be drawn because one or more of the 
         required arguments were not supplied.

WARNING: The stepplot statement named 's' will not be drawn because one or more 
         of the required arguments were not supplied.
WARNING: The scatterplot statement named 'c' will not be drawn because one or 
         more of the required arguments were not supplied.
WARNING: The blockplot statement will not be drawn because one or more of the 
         required arguments were not supplied.
NOTE: There were 6 observations read from the data set KMDATA2.
NOTE: PROCEDURE SGRENDER used (Total process time):
      real time           0.19 seconds
      cpu time            0.06 seconds
      

Currently I am not getting anything in my graph. 

Please let me know what exactly I am missing here

9 REPLIES 9
ballardw
Super User

I think that you want to repost the data step with the data.

Apparently some line feeds were dropped and the step 1) cannot be run as posted and 2) may have commingled the values of the first and last variables.

 

The key bit I think is here

 proc sgrender data = sj.kmdata2

You use a data set in the SJ library but your code above does not create it. So you are likely using a data set missing the variables you think you created to plot with. Try removing the SJ. from the data=.

 

Then go back to your Lifetest output and see if it is correct. The bit about the variable already existing may mean the lifetest added a different strata variable and you may want to use that one in the plots.

JeffMeyers
Barite | Level 11

Your template code is referring to variables that don't exist in your dataset (TATRISK, MON) so it cannot make the graphs the way the template has them laid out.

 

 proc template;
    define statgraph SurvivalPlot;
    begingraph / designwidth=8in designheight=5in;
    entrytitle 'Cumulative Incidence Graph'/ textattrs=(size=12);
    layout lattice;
    layout overlay / xaxisopts =(Label = "Months (Time)" type=linear labelattrs=(size=8pt weight=bold) tickvalueattrs=(size=9pt weight=bold) linearopts=(viewmin=0 viewmax=12 tickvaluelist=(0 2 4 6 8 10 12)))
        yaxisopts=(Label = "Cumulative Incidence" linearopts=(viewmin=0 viewmax=100) labelattrs=(size=8pt weight=bold) tickvalueattrs=(size=9pt weight=bold) linearopts=(viewmin=0 viewmax = 1.0 tickvaluelist=( 0.0 0.2 0.4 0.6 0.8 1.0)));
    stepplot x=time y = survival2 / group=stratum  lineattrs=(thickness = 3.0 pattern=solid color = orange) name='s';
    scatterplot x=time y = censor2 / GROUP=stratum name='c' markerattrs=(symbol=plus size=8);
    mergedlegend "c" "s" / location=inside halign=right valign=top order=columnmajor down=2 border=false valueattrs=(size=8pt) pad=(top=5 bottom=5);
    endlayout;
    layout overlay;
    entry halign=left 'N at Risk' /pad=(left=0 ) valign=bottom textattrs=(size=8pt);
    endlayout;
    blockplot x=time block=atrisk / class=stratum display=(values label) valuehalign=start valueattrs=(size=8) labelattrs=(size=8);
    endlayout;
    endgraph;
    end;
run;

proc sgrender data = kmdata2 template = survivalplot;
run;

I would like to add that you are not currently making a cumulative incidence plot however, but a 1-survival (failure rate) plot.  There are options in PROC LIFETEST to generate actual CIF function output (EVENTCODE option in the TIME statement).

 

Also, obligatory link to my NEWSURV macro that I've shared that can do all of these kinds of graphs if you would like to try it:  NEWSURV Link 

RAVI2000
Lapis Lazuli | Level 10
I see the failure rate and cumulative Incidence values are same. Can't I use the 1-survival for cumulative Incidence?
JeffMeyers
Barite | Level 11
They are only the same when you have one event and a censor value. If your event variable ever has competing risks (e.g. has values of 0, 1, 2, 3 or something) then they will be very different.
RAVI2000
Lapis Lazuli | Level 10
My event variable has 0 - censored,1- progression, 2- death values
RAVI2000
Lapis Lazuli | Level 10
So what option do I have to use for obtaining Atrisk?
JeffMeyers
Barite | Level 11

This is how different 1-KM vs CIF can be.  The top is 1-KM the bottom is CIF:

 

_surv.png

 

 

RAVI2000
Lapis Lazuli | Level 10
I have used eventcode and plot=cif options in my proclifetest but how do I get my N AT risk ? Since for survival we have used atrisk option. But for CI what options can be used to obtain atrisk values?
JeffMeyers
Barite | Level 11

The macro (%newsurv) will do them for you if you want to have them with a macro call like:

data BMT;
        input DIAGNOSIS Ftime Status Gender@@;
        label Ftime="Days";
        format Diagnosis grpLabel.;
datalines;
1       2081       0       1       1       1602    0       1
1       1496       0       1       1       1462    0       0
1       1433       0       1       1       1377    0       1
1       1330       0       1       1       996     0       1
1       226        0       0       1       1199    0       1
1       1111       0       1       1       530     0       1
1       1182       0       0       1       1167    0       0
1       418        2       1       1       383     1       1
1       276        2       0       1       104     1       1
1       609        1       1       1       172     2       0
1       487        2       1       1       662     1       1
1       194        2       0       1       230     1       0
1       526        2       1       1       122     2       1
1       129        1       0       1       74      1       1
1       122        1       0       1       86      2       1
1       466        2       1       1       192     1       1
1       109        1       1       1       55      1       0
1       1          2       1       1       107     2       1
1       110        1       0       1       332     2       1
2       2569       0       1       2       2506    0       1
2       2409       0       1       2       2218    0       1
2       1857       0       0       2       1829    0       1
2       1562       0       1       2       1470    0       1
2       1363       0       1       2       1030    0       0
2       860        0       0       2       1258    0       0
2       2246       0       0       2       1870    0       0
2       1799       0       1       2       1709    0       0
2       1674       0       1       2       1568    0       1
2       1527       0       0       2       1324    0       1
2       957        0       1       2       932     0       0
2       847        0       1       2       848     0       1
2       1850       0       0       2       1843    0       0
2       1535       0       0       2       1447    0       0
2       1384       0       0       2       414     2       1
2       2204       2       0       2       1063    2       1
2       481        2       1       2       105     2       1
2       641        2       1       2       390     2       1
2       288        2       1       2       421     1       1
2       79         2       0       2       748     1       1
2       486        1       0       2       48      2       0
2       272        1       0       2       1074    2       1
2       381        1       0       2       10      2       1
2       53         2       0       2       80      2       0
2       35         2       0       2       248     1       1
2       704        2       0       2       211     1       1
2       219        1       1       2       606     1       1
3       2640       0       1       3       2430    0       1
3       2252       0       1       3       2140    0       1
3       2133       0       0       3       1238    0       1
3       1631       0       1       3       2024    0       0
3       1345       0       1       3       1136    0       1
3       845        0       0       3       422     1       0
3       162        2       1       3       84      1       0
3       100        1       1       3       2       2       1
3       47         1       1       3       242     1       1
3       456        1       1       3       268     1       0
3       318        2       0       3       32      1       1
3       467        1       0       3       47      1       1
3       390        1       1       3       183     2       0
3       105        2       1       3       115     1       0
3       164        2       0       3       93      1       0
3       120        1       0       3       80      2       1
3       677        2       1       3       64      1       0
3       168        2       0       3       74      2       0
3       16         2       0       3       157     1       0
3       625        1       0       3       48      1       0
3       273        1       1       3       63      2       1
3       76         1       1       3       113     1       0
3       363        2       1
;
run;

%newsurv(data=bmt,time=ftime,cens=status,class=diagnosis, method=cif,ev_vl=1, summary=0, gpath=~/ibm/,
    risklist=0 to 2500 by 500);

_surv.png

 

The code that runs in the background would look something like this (it calculates the N at risk manually):

proc lifetest data=bmt alpha=0.05 alphaqt=0.05 cifvar error=aalen 
        outcif=_surv (where=((event>. or t1=0 or c1=1)) 
                      rename=(stratum=stratumnum ftime=t1 cif=s1 censored=c1 cif_lcl=lcl1 cif_ucl=ucl1 variance=vcif) 
                      keep=cif ftime censored event atrisk cif_lcl cif_ucl variance stratum) 
        conftype=LOG;
    strata diagnosis;
    time ftime * status(0) / failcode=1;
run;

data _splot;
    set _surv;
    by stratumnum;
    array _risktimes_ {6} (0, 500, 1000, 1500, 2000, 2500);
    retain _ncens _nevents _lagncens _lagnevents;

    if first.stratumnum then do;
        _ncens=0;
        _nevents=0;
        _lagncens=0;
        _lagnevents=0;
        _count_=1;
    end;

    if _count_ le dim(_risktimes_) then do;
        if t1 <=_risktimes_{_count_} then do;
            if event>. then _nevents=_nevents+event;

            if c1>. then _ncens=_ncens+c1;
        end;
        else do;
            if event>. then _lagnevents=_lagnevents+event;

            if c1>. then _lagncens=_lagncens+c1;
        end;
    end;

    if _count_ le dim(_risktimes_) then do;
        if t1 >=_risktimes_(_count_) then do until(x=1);
            tatrisk=_risktimes_(_count_);
            time=tatrisk;
            call missing(event, c1);
            output;
            _nevents=_nevents+_lagnevents;
            _ncens=_lagncens+_ncens;
            _lagnevents=0;
            _lagncens=0;
            _count_+1;

            if _count_>dim(_risktimes_) then x=1;
            else if t1 < _risktimes_(_count_) then x=1;
            else x=0;
        end;

        if last.stratumnum then do i=_count_ to dim(_risktimes_);
            tatrisk=_risktimes_(_count_);
            time=tatrisk;
            atrisk=0;
            call missing(event, c1);
            output;
            _nevents=_nevents+_lagnevents;
            _ncens=_lagncens+_ncens;
            _lagnevents=0;
            _lagncens=0;
        end;
    end;
    keep tatrisk time stratumnum atrisk event c1 t1 _count_ _nevents  _ncens _lagnevents _lagncens;
    rename c1=censored;
run;

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
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
  • 9 replies
  • 3770 views
  • 2 likes
  • 3 in conversation