Sunday, March 01, 2015

Handling the Dates and Times in Clinical Trial Data Collection Using SAS

In clinical trials, we always need to deal with the dates and times in data collection. For example, we will need to record the date of signing the informed consent form, date/time of medical history events, date/time of study drug administration, date/time of adverse events and concomitant medications. We also have to perform checks to make sure that these dates are in chronicle logic order, for example, the an event stop date/time must be after the event start date/time.

These date/time variables may be recorded in different ways and different formats. There may be partial (incomplete) dates recorded. An analysis may require the comparison of a date variable with a cut off date for the purpose of the annual safety report and for interim analysis. All of these will require good handling of the date / time variables. SAS software provides sufficient functions and formats for us to handle the dates/times. Here are some of the most commonly used date/time handling techniques with example codes.  

*Convert the date in character format to numeric format;
data test;
  date='05/04/00';
  time='10:05';
run;

data new; set test;
  sasdate1=input(date, mmddyy8.);
  sasdate2=sasdate1;
  sastime1=input(time, time5.);
  sastime2=sastime1;
  datetim1=input(put(sasdate1,date7.)||':'||time,datetime16.);
  datetim2=datetim1;
  ** created sasdate2, sastime2, datetim2 for display purposes only **;
run;

proc print data=new;
  var sasdate1 sasdate2 sastime1 sastime2 datetim1 datetim2;
  format sasdate2 mmddyy8.
         sastime2 hhmm5.
         datetim2 datetime16.;
run;


*Convert the time in character format to numeric format;
data c_time;
input c_time $;
n_time=input(c_time, time5.);
cards;
07:33
11:32
07:29
07:10
07:15
00:11
10:29
;
proc print;
     format n_time time5.;
run;

*Convert the time in Character format (without leading zero) to numeric format;
data have;
input raw_time $;
cards;
0733
1132
0729
710
715
11
1029
;
data want;
   set have;
    if length(raw_time)=2 then time=input(('0'||':'||raw_time),time5.);
     else
     time = input(substr(raw_time,1,length(raw_time)-2)||':'||substr(raw_time,length(raw_time)-1),time5.);
    format time time5.;
proc print;
run;


*Retrieve Date or Time from Datetime field
in the examples below, it does not matter if it ":", "T", or '' between date and time part in datetime field. 

data temp;
  date_time1 = "19DEC2010:20:10:10"dt;
  date_time2 = "19DEC2010T20:10:10"dt;
  date_part1 = datepart(date_time1);
  time_part1 = timepart(date_time1);
  date_part2 = datepart(date_time2);
  time_part2 = timepart(date_time2);
run;

proc print;
   format date_time1 date_time2 datetime25.6 
             date_part1 date_part2 date9. 
             time_part1 time_part2 time.;
run;


*Compare a Date Variable with a Fixed Date;
data temp;
  date_time = "19DEC2010:20:10:10"dt;
  date_part = datepart(date_time);
  if date_part >'01OCT2014'd then flag=1;
  else if date_part <= '01OCT2014'd then flag=0;
run;

*Handling the partial dates;

*Reading in the date and partial dates; AEDate is character;
data partialdate;
 input @1 Id @4 AEdate $10. @15 AEdate_p $10.;
datalines;
01 12/23/1964
02 11/22/1975    
03            11/UN/1980
04 08/15/1987
;
*Combine the full date and particial date variables;
data partialdate;
  set partialdate;
  If AEDATE ne '' then DISPLAYDATE=AEdate; 
  else displaydate=aedate_p;
run;
proc print;
run;


*Display the date in date9. format with partial date; AEdate variable is numeric;
data partialdate;
 input @1 Id @4 AEdate mmddyy10. @15 AEdate_p $10.;
datalines;
01 12/23/1964
02 11/22/1975    
03            11/UN/1980
04 08/15/1987
;
proc format ;  
  value $valmn '01'='JAN' '02'='FEB' '03'='MAR' '04'='APR'                      '05'='MAY' '06'='JUN' '07'='JUL'
               '08'='AUG' '09'='SEP' '10'='OCT' '11'='NOV'                      '12'='DEC'  'UN'='' ;
quit ;

data newdate;
  set partialdate;
  If AEDATE ne . then DISPLAYDATE=put(aedate,date9.) ;
  else if aedate_p ne '' then 
       DISPLAYDATE= trim(  substr(aedate_p,4,2)||put( substr(aedate_p,1,2), $valmn.)||substr(aedate_p,7) ) ;
  if displaydate=:'UN' then displaydate=trim(substr(displaydate,3)) ;
run;

proc print;
  format aedate mmddyy10.;
run;

data partialdate;
 input @1 Id @4 AEdate mmddyy10. @15 AEdate_p $10.;
datalines;
01 12/23/1964
02 11/22/1975    
03            UN-JUL-1980
04 08/15/1987
;

data partialdate;
  set partialdate;
  If aedate ne . then displaydate=put(aedate, date9.) ;
  else if aedate_p ne '' then displaydate= compress(aedate_p,'-') ;
  if displaydate=:'UN' then displaydate=substr(displaydate,3) ;
   displaydate=upcase(displaydate) ;
run;
proc print;
  format aedate mmddyy10.;
run;

*Dynamic Date Format;
proc format;
      value readdate 1='date7.'
                     2='mmddyy8.';
   run;

   options yearcutoff=1920;

   data fixdates;
      length jobdesc $12;
      input source id lname $ jobdesc $ start $;
      dateinformat=put(source, readdate.);
      newdate = inputn(start, dateinformat);
      datalines;
   1 1604 Ziminski writer 09aug90
   1 2010 Clavell editor 26jan95
   2 1833 Rivera writer 10/25/92
   2 2222 Barnes proofreader 3/26/98
   ;
proc print;
 format  newdate mmddyy8.;
run;


*Deal with time variable in SAS/Graph;
data one;
   input startime time5. count;
   if startime gt '12:00't then date='30sep92'd;
      else date='01oct92'd;
   datetime=dhms(date,hour(startime),minute(startime),
            second(startime));
   cards;
16:00 12.3
17:00 5.7
18:00 8.6
19:00 9.0
20:00 15.7
21:00 10.5
22:00 8.1
23:00 1.5
0:00  11.3
1:00  6.6
2:00  3.5
3:00  7.6
4:00  2.4
5:00  13.8
6:00  14.0
7:00  4.9
8:00  5.0
run;

proc print;
   var startime datetime;
run;

proc gplot data=one;
   plot count*datetime
        / haxis='30sep92:16:00'dt to '01oct92:08:00'dt
                by hour2;
   format datetime tod5.;
run;


*Working with time variable;
*randtime is a Character time variable with letter 'T'
*c_time is a character variable with T removed or compressed
*T_time is a numeric time variable. to display, the time. format is needed. 
data randtime;
  randtime = 'T20:10:10';
  C_time=compress(randtime, 'T');
  T_time=input(C_time,time.);
run;

proc print;
  format t_time time.;
run;

References: 




No comments: