Hello SAS community,
Everyone in my dataset has an outcome date (and some people have two outcome dates). In the code below (where the line starts with "if tv_outcome=1 then do..."), SAS is not processing the statements. For those people who have two outcomes, SAS processes the statements when tv_outcome=0 and tv_outcome=1, but then doesn't process the last set of statements that begin with "if tv_outcome=2 then do...". For example, there are people who have missing date_of_event and missing second_outcome_date, but instead of calculating time_to_event as obs_end-date_of_outcome, it just sets it to missing. So the data look something like this:
id obs_beg obs_end tv_outcome date_of_outcome date_of_event time_to_event
1 14MAR2010 31OCT2015 0 12APR2012 . 760
1 14MAR2010 31OCT2015 1 12APR2012 . .
This is how I need it to look:
id obs_beg obs_end tv_outcome date_of_outcome date_of_event time_to_event
1 14MAR2010 31OCT2015 0 12APR2012 . 760
1 14MAR2010 31OCT2015 1 12APR2012 . 1297
Code:
data event_time (keep = id obs_end death_dt date_of_outcome date_of_event
second_outcome_date time_to_event tv_outcome event_ind);
set eventression;
format obs_end date9.;
obs_end = '30sep2015'd;
if death_dt ne . then do;
obs_end = death_dt;
end;
if tv_outcome=0 then do;
if date_of_event = . then time_to_event=date_of_outcome-obs_beg;
else if date_of_event ne . and date_of_event gt date_of_outcome then time_to_event=date_of_outcome-obs_beg;
else time_to_event=date_of_event-obs_beg;
event_ind=0;
end;
if tv_outcome=1 then do;
if date_of_event = . and second_outcome_date = . then time_to_event=obs_end-date_of_outcome;
else if date_of_event = . and second_outcome_date ne . then time_to_event = second_outcome_date-date_of_outcome;
if date_of_event ne . and date_of_event lt date_of_outcome then time_to_event=.;
else if date_of_event ne . and second_outcome_date ne . and date_of_event gt second_outcome_date then time_to_event=second_outcome_date-date_of_outcome;
else time_to_event=date_of_event-date_of_outcome;
event_ind=1;
end;
if tv_outcome=2 then do;
if date_of_event = . and second_outcome_date ne . then time_to_event=obs_end-second_outcome_date;
if date_of_event ne . and date_of_event lt second_outcome_date then time_to_event=.;
else time_to_event=date_of_event-second_outcome_date;
event_ind=2;
end;
*if time_to_event<0 then time_to_event=0; *this will be negative values;
run;
proc sort data=event_time nodupkey out=event_time2; by id tv_outcome;
run;
Any help would be most appreciated!
None of your example data have TV_OUTCOME=2. Why would it execute those statements when none of your data match this pattern.
Hi Tom,
I provided a simple example to show that this doesn't execute where tv_outcome=1, I assumed I could figure it out for the other scenario once I get it to execute for the first set of statements. However, if you would like to see where the issue lies with tv_outcome=2, please see the example below.
id obs_beg obs_end tv_outcome date_of_outcome second_outcome_date date_of_event time_to_event
2 14MAR2010 31OCT2015 0 12APR2012 24Mar2014 . 760
2 14MAR2010 31OCT2015 1 12APR2012 24Mar2014 . .
2 14MAR2010 31OCT2015 2 12APR2012 24Mar2014 . .
This is what I need.
id obs_beg obs_end tv_outcome date_of_outcome second_outcome_date date_of_event time_to_event
2 14MAR2010 31OCT2015 0 12APR2012 24Mar2014 . 760
2 14MAR2010 31OCT2015 1 12APR2012 24Mar2014 . 711
2 14MAR2010 31OCT2015 2 12APR2012 24Mar2014 . 1297
Aren't you missing some else
data event_time ( keep = id obs_end death_dt date_of_outcome date_of_event second_outcome_date time_to_event tv_outcome event_ind); set eventression; format obs_end date9.; obs_end = '30sep2015'd; if death_dt ne . then do; obs_end = death_dt; end; if tv_outcome=0 then do; if date_of_event = . then time_to_event=date_of_outcome-obs_beg; else if date_of_event ne . and date_of_event gt date_of_outcome then time_to_event=date_of_outcome-obs_beg; else time_to_event=date_of_event-obs_beg; event_ind=0; end; if tv_outcome=1 then do; if date_of_event = . and second_outcome_date = . then time_to_event=obs_end-date_of_outcome; else if date_of_event = . and second_outcome_date ne . then time_to_event = second_outcome_date-date_of_outcome; else if date_of_event ne . and date_of_event lt date_of_outcome then time_to_event=.; else if date_of_event ne . and second_outcome_date ne . and date_of_event gt second_outcome_date then time_to_event=second_outcome_date-date_of_outcome; else time_to_event=date_of_event-date_of_outcome; event_ind=1; end; if tv_outcome=2 then do; if date_of_event = . and second_outcome_date ne . then time_to_event=obs_end-second_outcome_date; else if date_of_event ne . and date_of_event lt second_outcome_date then time_to_event=.; else time_to_event=date_of_event-second_outcome_date; event_ind=2; end; *if time_to_event<0 then time_to_event=0; *this will be negative values; run;
Without those, your second IF statement overwrites the first.
With spaghetti code like that, it is no miracle at all that you lose track of your functional blocks. Apply some visual formatting and see if it gives you a clue.
data event_time (
keep=
id obs_end death_dt date_of_outcome date_of_event
second_outcome_date time_to_event tv_outcome event_ind
);
set eventression;
format obs_end date9.;
obs_end = '30sep2015'd;
if death_dt ne .
then do;
obs_end = death_dt;
end;
if tv_outcome = 0
then do;
if date_of_event = .
then time_to_event = date_of_outcome - obs_beg;
else if date_of_event ne . and date_of_event gt date_of_outcome
then time_to_event = date_of_outcome - obs_beg;
else time_to_event = date_of_event - obs_beg;
event_ind = 0;
end;
if tv_outcome = 1
then do;
if date_of_event = . and second_outcome_date = .
then time_to_event = obs_end - date_of_outcome;
else if date_of_event = . and second_outcome_date ne .
then time_to_event = second_outcome_date - date_of_outcome;
if date_of_event ne . and date_of_event lt date_of_outcome
then time_to_event = .;
else if
date_of_event ne . and second_outcome_date ne . and
date_of_event gt second_outcome_date
then time_to_event = second_outcome_date - date_of_outcome;
else time_to_event = date_of_event - date_of_outcome;
event_ind = 1;
end;
if tv_outcome = 2
then do;
if date_of_event = . and second_outcome_date ne .
then time_to_event = obs_end - second_outcome_date;
if date_of_event ne . and date_of_event lt second_outcome_date
then time_to_event = .;
else time_to_event = date_of_event - second_outcome_date;
event_ind = 2;
end;
*if time_to_event < 0 then time_to_event = 0; *this will be negative values;
run;
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.