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

Current table

patientidEvent typedatetimepoint1timepoint2timepoint3timepoint4
1Baseline1/28/202012006001200 
1Daily1/28/20201211 1211 
1Daily1/29/2020122110001221 
2Baseline11/21/20191011135912001200
2Daily11/21/20191011135912001200
2Daily11/21/20191643164516451644
2Daily11/21/20192225222522252225
3Baseline11/25/20191440144014401440
3Daily11/25/20191520152015201520
4Baseline11/11/20191259130013011300
4Daily11/11/20191259130013011300
4Daily11/11/20191845184718451845

 

within each same patient group, i would like to create a flag if date equals to next date within each patient AND all time points match, then baseline = 1 or 0

 

patientidEvent typedatetimepoint1timepoint2timepoint3timepoint4baseline
1Baseline1/28/202012006001200 1
1Daily1/28/20201211 1211 0
1Daily1/29/2020122110001221 0
2Baseline11/21/201910111359120012001
2Daily11/21/201910111359120012001
2Daily11/21/201916431645164516440
2Daily11/21/201922252225222522250
3Baseline11/25/201914401440144014401
3Daily11/25/201915201520152015200
4Baseline11/11/201912591300130113001
4Daily11/11/201912591300130113001
4Daily11/11/201918451847184518450

 

I tried to divide daily and baseline tables into TWO different tables

 

and left join by date and then timepoints. i am really stuck

1 ACCEPTED SOLUTION

Accepted Solutions
unison
Lapis Lazuli | Level 10

Maybe I'm mis-understanding but your written logic doesn't line up with what you've flagged as baseline=1.

If you are flagging for removal, does this remove the records you want out?

 

 

data have;
	input patientid Event_type :$15. date :mmddyy10. timepoint1 timepoint2 
		timepoint3 timepoint4;
	format date mmddyy10.;
	datalines;
1 Baseline 01/28/2020 1200 600 1200 .
1 Daily 01/28/2020 1211 . 1211 .
1 Daily 01/29/2020 1221 1000 1221 .
2 Baseline 11/21/2019 1011 1359 1200 1200
2 Daily 11/21/2019 1011 1359 1200 1200
2 Daily 11/21/2019 1643 1645 1645 1644
2 Daily 11/21/2019 2225 2225 2225 2225
3 Baseline 11/25/2019 1440 1440 1440 1440
3 Daily 11/25/2019 1520 1520 1520 1520
4 Baseline 11/11/2019 1259 1300 1301 1300
4 Daily 11/11/2019 1259 1300 1301 1300
4 Daily 11/11/2019 1845 1847 1845 1845
;
run;

proc sort data=have nodupkey out=want dupout=checkdups;
by patientid date timepoint:;
run;

 

Duplicates Removed:

patientid Event_type date timepoint1 timepoint2 timepoint3 timepoint4
2 Daily 11/21/2019 1011 1359 1200 1200
4 Daily 11/11/2019 1259 1300 1301 1300

 

 

Want:

patientid Event_type date timepoint1 timepoint2 timepoint3 timepoint4
1 Baseline 01/28/2020 1200 600 1200 .
1 Daily 01/28/2020 1211 . 1211 .
1 Daily 01/29/2020 1221 1000 1221 .
2 Baseline 11/21/2019 1011 1359 1200 1200
2 Daily 11/21/2019 1643 1645 1645 1644
2 Daily 11/21/2019 2225 2225 2225 2225
3 Baseline 11/25/2019 1440 1440 1440 1440
3 Daily 11/25/2019 1520 1520 1520 1520
4 Baseline 11/11/2019 1259 1300 1301 1300
4 Daily 11/11/2019 1845 1847 1845 1845
-unison

View solution in original post

6 REPLIES 6
ChrisNZ
Tourmaline | Level 20

Only one row matches your criteria

 

patientid Event type date timepoint1 timepoint2 timepoint3 timepoint4
1 Baseline 1/28/2020 1200 600 1200  
1 Daily 1/28/2020 1211   1211  
1 Daily 1/29/2020 1221 1000 1221  
2 Baseline 11/21/2019 1011 1359 1200 1200
2 Daily 11/21/2019 1011 1359 1200 1200
2 Daily 11/21/2019 1643 1645 1645 1644
2 Daily 11/21/2019 2225 2225 2225 2225
3 Baseline 11/25/2019 1440 1440 1440 1440
3 Daily 11/25/2019 1520 1520 1520 1520
4 Baseline 11/11/2019 1259 1300 1301 1300
4 Daily 11/11/2019 1259 1300 1301 1300
4 Daily 11/11/2019 1845 1847 1845 1845

 

within each same patient group, i would like to create a flag if date equals to next date within each patient AND all time points match

 

monday89
Fluorite | Level 6

Sorry I meant as in if group is Baseline or Daily (consequential) for the same patient AND all time points and dates match then baseline = 1 

 

ChrisNZ
Tourmaline | Level 20

> I meant as in if group is Baseline or Daily (consequential) for the same patient AND all time points and dates match then baseline = 1

This still doesn't make match your result.

mkeintz
PROC Star

It appears to me that:

  1. Every ID begins with a baseline record, each ID has only one baseline record, and each baseline record has (unsurprisingly) the baseline flag set to one.  The programs below assumes so.

  2. But for DAILY records, baseline=1 ONLY if all the timepoint values match the preceding record.  In your example the only daily records that fill this condition are the records immediate following the baseline record.  Is that true for your data?   Or can there be any other daily record that gets baseline=1 because its timepoint values match the preceding daily record?  If so, this program will flag such baseline records. 

 

The program below is untested (I'm not bothering to put your data into a DATA step):

 

data want;
  set have;
  by patientid;
  array tp timepoint: ;     /* Editted */
  baseline=1;                  /* Default to 1                              */
  do over tp;                  /* If any timepoint difference, convert to 0 */
    if lag(tp) ^= tp then baseline=0;
  end;
  if first.patientid=1 then baseline=1;
run;

If, however, the only daily records actually eligible for baseline=1 are the 2nd records of each patientid, whose timepoints match the baseline timepoints, then this more compact program will do:

 

data want;
  set have ;
  by patientid timepoint1 timepoint2 timepoint3 notsorted;
  baseline=0;                /* Editted additional statement */
  if first.patientid=1 then baseline=1;
  if lag(first.patientid)=1 and first.patientid=0 and first.timepoint3=0 then baseline=1;
run;

Notes:

  1. The "notsorted" keyword at the end of the BY statement tells sas that the data are grouped, but not necessarily in ascending order for all the by-variables.
  2. The "if first.patientid=1" test for whether the record-in-hand is the start of a patientid (which this program assumes is a baseline type of record).
  3. The "if lag(first.patientid)=1 and first.patientid=0"  condition is true only for the 2nd record of each patientid  (Note the "and first.patientid=0" part is required in case the preceding record was the only record for the preceding patientid).
       and
    the "and first.timepoint3=0" condition is true only when all the by-variables in the current record match their values in the following record.
--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
Ksharp
Super User
You need explain more details about your question.



data have; infile cards expandtabs truncover; input patientid Eventtype $ date : $20. timepoint1 timepoint2 timepoint3 timepoint4; cards; 1 Baseline 1/28/2020 1200 600 1200 1 Daily 1/28/2020 1211 1211 1 Daily 1/29/2020 1221 1000 1221 2 Baseline 11/21/2019 1011 1359 1200 1200 2 Daily 11/21/2019 1011 1359 1200 1200 2 Daily 11/21/2019 1643 1645 1645 1644 2 Daily 11/21/2019 2225 2225 2225 2225 3 Baseline 11/25/2019 1440 1440 1440 1440 3 Daily 11/25/2019 1520 1520 1520 1520 4 Baseline 11/11/2019 1259 1300 1301 1300 4 Daily 11/11/2019 1259 1300 1301 1300 4 Daily 11/11/2019 1845 1847 1845 1845 ; data want; set have; by patientid; retain _d _t1-_t4 .; baseline=0; if first.patientid then do; call missing(of _:); if Eventtype='Baseline' then do; baseline=1; _d=date;_t1=timepoint1;_t2=timepoint2; _t3=timepoint3;_t4=timepoint4; end; end; if patientid=lag(patientid) and _d=date and _t1=timepoint1 and _t2=timepoint2 and _t3=timepoint3 and _t4=timepoint4 then baseline=1; drop _:; run; proc print;run;
unison
Lapis Lazuli | Level 10

Maybe I'm mis-understanding but your written logic doesn't line up with what you've flagged as baseline=1.

If you are flagging for removal, does this remove the records you want out?

 

 

data have;
	input patientid Event_type :$15. date :mmddyy10. timepoint1 timepoint2 
		timepoint3 timepoint4;
	format date mmddyy10.;
	datalines;
1 Baseline 01/28/2020 1200 600 1200 .
1 Daily 01/28/2020 1211 . 1211 .
1 Daily 01/29/2020 1221 1000 1221 .
2 Baseline 11/21/2019 1011 1359 1200 1200
2 Daily 11/21/2019 1011 1359 1200 1200
2 Daily 11/21/2019 1643 1645 1645 1644
2 Daily 11/21/2019 2225 2225 2225 2225
3 Baseline 11/25/2019 1440 1440 1440 1440
3 Daily 11/25/2019 1520 1520 1520 1520
4 Baseline 11/11/2019 1259 1300 1301 1300
4 Daily 11/11/2019 1259 1300 1301 1300
4 Daily 11/11/2019 1845 1847 1845 1845
;
run;

proc sort data=have nodupkey out=want dupout=checkdups;
by patientid date timepoint:;
run;

 

Duplicates Removed:

patientid Event_type date timepoint1 timepoint2 timepoint3 timepoint4
2 Daily 11/21/2019 1011 1359 1200 1200
4 Daily 11/11/2019 1259 1300 1301 1300

 

 

Want:

patientid Event_type date timepoint1 timepoint2 timepoint3 timepoint4
1 Baseline 01/28/2020 1200 600 1200 .
1 Daily 01/28/2020 1211 . 1211 .
1 Daily 01/29/2020 1221 1000 1221 .
2 Baseline 11/21/2019 1011 1359 1200 1200
2 Daily 11/21/2019 1643 1645 1645 1644
2 Daily 11/21/2019 2225 2225 2225 2225
3 Baseline 11/25/2019 1440 1440 1440 1440
3 Daily 11/25/2019 1520 1520 1520 1520
4 Baseline 11/11/2019 1259 1300 1301 1300
4 Daily 11/11/2019 1845 1847 1845 1845
-unison

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
  • 6 replies
  • 1836 views
  • 1 like
  • 5 in conversation