BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
songsujing
Fluorite | Level 6

I use two methods to do time-dependent using proc phreg, the first one is counting process, the second one programing statement, there is a little bit difference from two results, basically they are same. I would like to know if I do correctly these two methods should generate exactly same results

Icu_1 is time-dependent, it's value is 0 if patient is not admitted to ICU or before icu_admission date if icu admitted

icu_admission, provenance2, age_catn, sex are all numeric variables but with 2 or 3 distinct value. 

 

My two method code is: 

data co2;
set co1;
start=0;
if icu_admission = 0 then do; 
   stop = time_to_death; icu_1 = icu_admission;status_death1=status_death; output;
   end;
else if icu_admission = 1 and time_to_icu < time_to_death then do;
  stop = time_to_icu; icu_1 =0; status_death1=0;  output;
  start=time_to_icu; icu_1=1; stop=time_to_death; status_death1=status_death; output;
end;
else if icu_admission = 1 and time_to_icu = time_to_death then do;
stop=time_to_death; icu_1=1;status_death1=status_death;output;
end;
run;

proc phreg data = co2;
class Provenance2 (ref=first)  age_cat3n (ref=first) sex (ref=first)    comorbidity_catn (ref=first)            ;
model (start,stop)*status_death1(0) =age_cat3n sex comorbidity_catn provenance2 icu_1  /rl ; 
run;

proc phreg data = co1;
class Provenance2 (ref=first) age_cat3n (ref=first) sex (ref=first)    comorbidity_catn (ref=first) ;
model time_to_death*status_death(0) =age_cat3n sex comorbidity_catn provenance2 icu_1 /rl; 
if icu_admission = 0 then icu_1 = 0;
else if  icu_admission=1 and time_to_death < time_to_icu  then icu_1 =0;
else if icu_admission=1 and time_to_death >= time_to_icu then icu_1=1;
run;

 

 

 
1 ACCEPTED SOLUTION

Accepted Solutions
MarcHuber
SAS Employee

I see.  That is a conceptually different situation than it looked like before. 

 

In your special case, you want the risk of death to change immediately as a person enters the icu.  My assumption was that those things cannot happen at the same time.  In fact, I would guess that you don't believe that a person can die at the exact instant that they cross the threshold to the icu.  So, we need to break the tie.  Your change in the programming statements would necessitate a change in the data step code as well.

 

I don't really know what the actual time values are in your data.  I was under the assumption that time was always recorded in non-negative positive integers.  Therefore, in this modified code, I made a slight adjustment to the time_to_icu value.  I subtracted 0.0005 from all value to reflect the fact that going to the icu always precedes dying, even if by a tiny amount.  Note that the actual value of 0.0005 is not magical.  It could have been 0.00001 or 0.00000004536.  The important thing is that it is smaller than the gap between any two actual times.  So, if your times are 0, 0.00001, 0.00002...1.0, then you might subtract 0.000005 from the time_to_icu value.  Time order is the only thing that matters in Cox PH models, not actual times.  

 

Here is the slightly modified code:

 

data co2;
	set co1;
	status=status_death;
    time_to_icu = time_to_icu - 0.0005;

	/* Assuming missing on time_to_icu means no icu admissions. */
	if time_to_icu=. then
		do;
			start=0;
			stop=time_to_death;
			icu_1=0;
			output;
		end;

	/* Generate two records if there was an icu visit. It is presumed that time_to_icu */
	/* can never be greater than time_to_death. */
	else if time_to_icu < time_to_death then
		do;

			/* first record */
			start=0;
			stop=time_to_icu;
			icu_1=0;
			status_death=0;
			output;

			/* second record */
			start=time_to_icu;
			stop=time_to_death;
			icu_1=1;
			status_death=status;
			output;
		end;
	drop icu_admission status time_to_icu time_to_death;
run;

proc phreg data=co2;
	class Provenance2 (ref=first) age_cat3n (ref=first) sex (ref=first) 
		comorbidity_catn (ref=first);
	model (start, stop)*status_death1(0)=age_cat3n sex comorbidity_catn 
		provenance2 icu_1 /rl;
run;

proc phreg data=co1;
	class Provenance2 (ref=first) age_cat3n (ref=first) sex (ref=first) 
		comorbidity_catn (ref=first);
	model time_to_death*status_death(0)=age_cat3n sex comorbidity_catn provenance2 
		icu_1 /rl;

	/* This is the key */
	icu_1=(0 <=time_to_icu <= time_to_death);
run;

 

View solution in original post

6 REPLIES 6
MarcHuber
SAS Employee

I was looking at your code.  The way you created the multiple records data set was fine.  The problem was with your creation of icu_1 in the programming code in PROC PHREG.

 

I'm assuming that if icu_admission in the co1 data set is 0 then the the time_to_icu variable will be missing.  I'm not sure what else you might have coded there, but assuming that it is indeed missing, you can simplify not only your DATA step code for creating the counting process data set (although, as I said, yours appears to work just fine), but also correct and simplify the programming code in PROC PHREG.  I am including such coding and if you do this.  If you use this code, then both forms of specifying the model should come out the same - not just close, but the same.

 

Note that I didn't rename status_death to status_death1 variable in the multiple records data.  It is called status_death in both data sets. 

 

data co2;
set co1;
status=status_death;

/* Assuming missing on time_to_icu means no icu admissions. */

if time_to_icu = . then do;
start=0;
stop=time_to_death;
icu_1=0;
output;
end;

/* Generate two records if there was an icu visit. It is presumed that time_to_icu */
/* can never be greater than time_to_death. */

else do;
if time_to_icu < time_to_death then do;
/* first record */
start=0;
stop=time_to_icu;
icu_1=0;
status_death=0;
output;

/* second record */
start=time_to_icu;
stop=time_to_death;
icu_1=1;
status_death=status;
output;
end;
end;
drop icu_admission status time_to_icu time_to_death;
run;

 

proc phreg data = co2;
class Provenance2 (ref=first) age_cat3n (ref=first) sex (ref=first) comorbidity_catn (ref=first) ;
model (start,stop)*status_death1(0) =age_cat3n sex comorbidity_catn provenance2 icu_1 /rl ;
run;

 

proc phreg data = co1;
class Provenance2 (ref=first) age_cat3n (ref=first) sex (ref=first) comorbidity_catn (ref=first) ;
model time_to_death*status_death(0) =age_cat3n sex comorbidity_catn provenance2 icu_1 /rl;
/* This is the key */
icu_1=(0 <= time_to_icu < time_to_death);

 

run;

 

 

 

songsujing
Fluorite | Level 6

Thanks Archerbum, there is special record in my data, where their time_to_icu = time_to_death, if I remove this record, your two methods generate exact results, with this record in , results still a little bit different.  

Here is one special record: (this patient died the same day he went to ICU)

time_to_Icu Time_to_Death icu_admission status_death

1111

 I tried to modify the your code in programming statement

from 

icu_1=(0 <= time_to_icu < time_to_death)

to

icu_1=(0 <= time_to_icu <= time_to_death)

your counting process for this record to:

start=0; stop=0.9; icu_1=0; status_death=0;

start=0.9, stop=1;icu_1=1;status_death=1;

but still I can't get exact same results.

 

Thanks a lot in advance

 

MarcHuber
SAS Employee

I see.  That is a conceptually different situation than it looked like before. 

 

In your special case, you want the risk of death to change immediately as a person enters the icu.  My assumption was that those things cannot happen at the same time.  In fact, I would guess that you don't believe that a person can die at the exact instant that they cross the threshold to the icu.  So, we need to break the tie.  Your change in the programming statements would necessitate a change in the data step code as well.

 

I don't really know what the actual time values are in your data.  I was under the assumption that time was always recorded in non-negative positive integers.  Therefore, in this modified code, I made a slight adjustment to the time_to_icu value.  I subtracted 0.0005 from all value to reflect the fact that going to the icu always precedes dying, even if by a tiny amount.  Note that the actual value of 0.0005 is not magical.  It could have been 0.00001 or 0.00000004536.  The important thing is that it is smaller than the gap between any two actual times.  So, if your times are 0, 0.00001, 0.00002...1.0, then you might subtract 0.000005 from the time_to_icu value.  Time order is the only thing that matters in Cox PH models, not actual times.  

 

Here is the slightly modified code:

 

data co2;
	set co1;
	status=status_death;
    time_to_icu = time_to_icu - 0.0005;

	/* Assuming missing on time_to_icu means no icu admissions. */
	if time_to_icu=. then
		do;
			start=0;
			stop=time_to_death;
			icu_1=0;
			output;
		end;

	/* Generate two records if there was an icu visit. It is presumed that time_to_icu */
	/* can never be greater than time_to_death. */
	else if time_to_icu < time_to_death then
		do;

			/* first record */
			start=0;
			stop=time_to_icu;
			icu_1=0;
			status_death=0;
			output;

			/* second record */
			start=time_to_icu;
			stop=time_to_death;
			icu_1=1;
			status_death=status;
			output;
		end;
	drop icu_admission status time_to_icu time_to_death;
run;

proc phreg data=co2;
	class Provenance2 (ref=first) age_cat3n (ref=first) sex (ref=first) 
		comorbidity_catn (ref=first);
	model (start, stop)*status_death1(0)=age_cat3n sex comorbidity_catn 
		provenance2 icu_1 /rl;
run;

proc phreg data=co1;
	class Provenance2 (ref=first) age_cat3n (ref=first) sex (ref=first) 
		comorbidity_catn (ref=first);
	model time_to_death*status_death(0)=age_cat3n sex comorbidity_catn provenance2 
		icu_1 /rl;

	/* This is the key */
	icu_1=(0 <=time_to_icu <= time_to_death);
run;

 

songsujing
Fluorite | Level 6

@MarcHuber  Thanks a lot ! two methods generate exact same results

FreelanceReinh
Jade | Level 19

Hello @songsujing,

 

Glad to see that @MarcHuber's replies resolved your issue. Then it would be fair and help later readers if you marked the most helpful reply as the accepted solution, not your own "thank you" post. Could you please change that? It's very easy: Select a different post as the solution after clicking "Not the Solution" in the option menu (see icon below) of the current solution.
show_option_menu.png

songsujing
Fluorite | Level 6

@FreelanceReinh 

Sorry for that, I did it not on purpose, just because this is the first time I did it and don't know how, I have followed your instruction and redo it. Next time I will do it correctly

 

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

What is ANOVA?

ANOVA, or Analysis Of Variance, is used to compare the averages or means of two or more populations to better understand how they differ. Watch this tutorial for more.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 6 replies
  • 1042 views
  • 2 likes
  • 3 in conversation