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

Hi Team,

 

How to flag last hour records by group vars for below data.

 

In below data sort by AVISIT ATPTN ADT ADTM then need to flag new var where last hour records by AVISIT and ATPTN 

 

SUBJID PARAMCDAVISITATPTADTM ADT NEWFLAG
3002ALTScreening 01JAN2024:13:58:1501-Jan-24 N
3002ALTScreening 01JAN2024:13:58:5601-Jan-24 N
3002ALTScreening 01JAN2024:13:53:3901-Jan-24 N
3002ALTScreening 01JAN2024:13:56:0501-Jan-24 N
3002ALTScreening 01JAN2024:13:57:3701-Jan-24 N
3002ALTScreening 01JAN2024:14:05:3101-Jan-24 Y
3002ALTScreening 01JAN2024:14:06:1301-Jan-24 Y
3002ALTScreening 01JAN2024:14:06:5301-Jan-24 Y
3002ALTCycle Day 1PreDose13JAN2024:10:20:1013-Jan-24 Y
3002ALTCycle Day 1PreDose13JAN2024:10:22:2013-Jan-24 Y
3002ALTCycle Day 1PreDose13JAN2024:10:23:3013-Jan-24 Y
3002ALTCycle Day 1 1Hour13JAN2024:13:26:2113-Jan-24 Y
3002ALTCycle Day 1 1Hour13JAN2024:13:27:1813-Jan-24 Y
3002ALTCycle Day 1 1Hour13JAN2024:13:28:2913-Jan-24 Y
3002ALTCycle Day 1 1Hour13JAN2024:13:45:0513-Jan-24 Y
3002ALTCycle Day 1 1Hour13JAN2024:13:46:3213-Jan-24 Y
3002ALTCycle Day 1 1Hour13JAN2024:13:47:4513-Jan-24 Y

 

Thank you,

Raja

 

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

First let's convert your sample listing into an actual dataset.  Let's make sure the ADTM variable is an actual DATETIME variable and eliminate that extra empty column.  let's rename your provide results as EXPECT so we can compare whether our code works.

data have;
  infile datalines dsd truncover ;
  input SUBJID $ PARAMCD $ AVISIT :$20. ATPT $ ADTM :datetime. ADT :date. extra $ EXPECT $;
  format ADTM datetime19. ADT date9.;
  drop extra ;
datalines;
3002,ALT,Screening, ,01JAN2024:13:58:15,01-Jan-24, ,N
3002,ALT,Screening, ,01JAN2024:13:58:56,01-Jan-24, ,N
3002,ALT,Screening, ,01JAN2024:13:53:39,01-Jan-24, ,N
3002,ALT,Screening, ,01JAN2024:13:56:05,01-Jan-24, ,N
3002,ALT,Screening, ,01JAN2024:13:57:37,01-Jan-24, ,N
3002,ALT,Screening, ,01JAN2024:14:05:31,01-Jan-24, ,Y
3002,ALT,Screening, ,01JAN2024:14:06:13,01-Jan-24, ,Y
3002,ALT,Screening, ,01JAN2024:14:06:53,01-Jan-24, ,Y
3002,ALT,Cycle Day 1,PreDose,13JAN2024:10:20:10,13-Jan-24, ,Y
3002,ALT,Cycle Day 1,PreDose,13JAN2024:10:22:20,13-Jan-24, ,Y
3002,ALT,Cycle Day 1,PreDose,13JAN2024:10:23:30,13-Jan-24, ,Y
3002,ALT,Cycle Day 1, 1Hour,13JAN2024:13:26:21,13-Jan-24, ,Y
3002,ALT,Cycle Day 1, 1Hour,13JAN2024:13:27:18,13-Jan-24, ,Y
3002,ALT,Cycle Day 1, 1Hour,13JAN2024:13:28:29,13-Jan-24, ,Y
3002,ALT,Cycle Day 1, 1Hour,13JAN2024:13:45:05,13-Jan-24, ,Y
3002,ALT,Cycle Day 1, 1Hour,13JAN2024:13:46:32,13-Jan-24, ,Y
3002,ALT,Cycle Day 1, 1Hour,13JAN2024:13:47:45,13-Jan-24, ,Y
;

Your data is not actually sorted by the grouping variables.  So you will probably need to sort it first.  Since it is much easier to remember the last hour than to have to look into the future to find it we should sort by descending datetime.

proc sort data=have;
  by SUBJID PARAMCD AVISIT ATPT descending ADTM;
run;

Now you just need to remember what hour it was on the first observation for the group and then compare that to the current hour to make you new flag variable.  

data want;
  set have;
  by SUBJID PARAMCD AVISIT ATPT descending ADTM;
  if first.atpt then firsthr = intnx('dthour',adtm,0);
  format firsthr datetime19.;
  retain firsthr ;
  flag = (intnx('dthour',adtm,0)=firsthr);
  drop firsthr;
run;

Result

Tom_1-1740428259858.png

If you really want that character variable instead of the easier boolean numeric variable then just use some IF/THEN logic instead of the simple assignment statement.

  if (intnx('dthour',adtm,0)=firsthr) then flag='Y' ;
  else flag='N';

View solution in original post

3 REPLIES 3
Tom
Super User Tom
Super User

Is that last YN variable what you want to get?  If not can you provide the output data for this input?

If it is then explain in more detail the logic used to create it.  

Let's assume you meant that the data is grouped by the first four variables:

SUBJID PARAMCD AVISIT ATPT 

If so then why do you flag THREE of the observations as being the LAST for for the first group?

Is it because they appear on the same date?

Tom
Super User Tom
Super User

First let's convert your sample listing into an actual dataset.  Let's make sure the ADTM variable is an actual DATETIME variable and eliminate that extra empty column.  let's rename your provide results as EXPECT so we can compare whether our code works.

data have;
  infile datalines dsd truncover ;
  input SUBJID $ PARAMCD $ AVISIT :$20. ATPT $ ADTM :datetime. ADT :date. extra $ EXPECT $;
  format ADTM datetime19. ADT date9.;
  drop extra ;
datalines;
3002,ALT,Screening, ,01JAN2024:13:58:15,01-Jan-24, ,N
3002,ALT,Screening, ,01JAN2024:13:58:56,01-Jan-24, ,N
3002,ALT,Screening, ,01JAN2024:13:53:39,01-Jan-24, ,N
3002,ALT,Screening, ,01JAN2024:13:56:05,01-Jan-24, ,N
3002,ALT,Screening, ,01JAN2024:13:57:37,01-Jan-24, ,N
3002,ALT,Screening, ,01JAN2024:14:05:31,01-Jan-24, ,Y
3002,ALT,Screening, ,01JAN2024:14:06:13,01-Jan-24, ,Y
3002,ALT,Screening, ,01JAN2024:14:06:53,01-Jan-24, ,Y
3002,ALT,Cycle Day 1,PreDose,13JAN2024:10:20:10,13-Jan-24, ,Y
3002,ALT,Cycle Day 1,PreDose,13JAN2024:10:22:20,13-Jan-24, ,Y
3002,ALT,Cycle Day 1,PreDose,13JAN2024:10:23:30,13-Jan-24, ,Y
3002,ALT,Cycle Day 1, 1Hour,13JAN2024:13:26:21,13-Jan-24, ,Y
3002,ALT,Cycle Day 1, 1Hour,13JAN2024:13:27:18,13-Jan-24, ,Y
3002,ALT,Cycle Day 1, 1Hour,13JAN2024:13:28:29,13-Jan-24, ,Y
3002,ALT,Cycle Day 1, 1Hour,13JAN2024:13:45:05,13-Jan-24, ,Y
3002,ALT,Cycle Day 1, 1Hour,13JAN2024:13:46:32,13-Jan-24, ,Y
3002,ALT,Cycle Day 1, 1Hour,13JAN2024:13:47:45,13-Jan-24, ,Y
;

Your data is not actually sorted by the grouping variables.  So you will probably need to sort it first.  Since it is much easier to remember the last hour than to have to look into the future to find it we should sort by descending datetime.

proc sort data=have;
  by SUBJID PARAMCD AVISIT ATPT descending ADTM;
run;

Now you just need to remember what hour it was on the first observation for the group and then compare that to the current hour to make you new flag variable.  

data want;
  set have;
  by SUBJID PARAMCD AVISIT ATPT descending ADTM;
  if first.atpt then firsthr = intnx('dthour',adtm,0);
  format firsthr datetime19.;
  retain firsthr ;
  flag = (intnx('dthour',adtm,0)=firsthr);
  drop firsthr;
run;

Result

Tom_1-1740428259858.png

If you really want that character variable instead of the easier boolean numeric variable then just use some IF/THEN logic instead of the simple assignment statement.

  if (intnx('dthour',adtm,0)=firsthr) then flag='Y' ;
  else flag='N';
mkeintz
PROC Star

I think you want to construct a cutoff time exactly 1 hour (3600 seconds) prior to the last ADTM for each SUBJID AVISIT, yes?  Then keep all cases on or after the cutoff.

 

This is untested in the absence of sample data in the form of a working DATA step:

 

data need  /view=need;
  set have (keep=subjid avisit atptn adtm);
  by subjid avsit atptn;
  if last.atptn; 
  adtm_cutoff=atptn-3600;
  drop adtm;
run;

data want (drop=adtm_cutoff);
  merge have need;
  by subjid avisit atptn;
  if adtm>=adtm_cutoff;
run;

You see two DATA steps, but they will process the data as one step, since NEED is a data set VIEW, not a data set FILE.

--------------------------
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

--------------------------

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

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
  • 878 views
  • 4 likes
  • 3 in conversation