Macro %dayder

1. Description

The macro DAYDER will derive all _DY variables. The macro uses character date variables (_DTC) to derive the day (_DY) variables within the input SDTM dataset.

2. Dependencies

2.1 Global Macro Variables - N/A

2.2 Global Macros - N/A

3. Macro Parameters

Macro parameter Description Example
INDAT (R) The name of the input dataset from which the day derivation needs to be computed. INDAT=AE Default value: None
OUTDAT (R) The name of the output dataset. OUTDAT=AE2 , Default value: None
LIB (O) The name of the library which contains the DM dataset. LIB=DSDTM , Default value: SDTM

(R): Required (O): Optional

4. Assumptions

  1. The date variables (_DTC) used to derive the day variables (_DY) should be of character type.
  2. The date variables should end with DTC for computing the day variables.
  3. SDTM.DM dataset with RFSTDTC variable is assumed to be present if the LIB parameter value is missing.

5. Sample Call

  1. %DAYDER(INDAT=AE,
             OUTDAT=AE5);

  2. %DAYDER(INDAT=AE,
             OUTDAT=AE5,
             LIB=DSDTM);

6. Macro Code

    %macro dayder(indat=,outdat=,lib=sdtm);
      *Custom  message when Input dataset is missing in macro call;
      %if &indat eq %then %do;
        %put ERROR: Input dataset is missing in macro call;
        %return;
      %end;
        %else %do;
          *Custom  message when Input dataset is invalid;
          %if %sysfunc(exist(&indat)) ne 1 %then %do;
            %put ERROR: Invalid dataset;
            %return;
          %end;
          *Custom  message when __DTC variable is missing in the input dataset;
          proc sql noprint;
            select count(distinct(name))
            into: nd separated by " "
            from sashelp.vcolumn
            where libname="WORK" and memname=upcase("&indat") and find(upcase(name),"DTC     ")>0 ;
          quit; 
            %if &nd=0 %then %do;
              %put ERROR: Input dataset doesnot have date variable ending with DTC ;
              %return;
            %end;
              %else %do;
                *Custom  message when __DTC numeric variable is present in the input     dataset;
                proc sql noprint;
                  select count(distinct(name))
                  into: daten separated by " "
                  from sashelp.vcolumn
                  where libname="WORK" and memname=upcase("&indat") and     find(upcase(name),"DTC ")>0 and type="num";
                quit; 
                  %if &daten=1 %then %do;
                    %put ERROR: Input dataset have numeric date variable ending with DTC     ;
                    %return;
                  %end;
                    %else %do;
                      *For assigning the __DTC variables as macro variables;
                      proc sql noprint;
                        select     distinct(name),strip(name)||"_",strip(tranwrd(upcase(name),"DTC ","DY")),
                        varnum  into: ndt separated by " ",
                        :ndt1 separated by " " ,
                        :dy separated by " ",
                        :vnum
                        from sashelp.vcolumn
                        where libname="WORK" and memname=upcase("&indat") and     find(upcase(name),"DTC ")>0 and type="char"
                        order by varnum;
                      quit;
                        %let cnt=%sysfunc(countw(&ndt));
                        *Custom  message when Output dataset is missing in macro call;
                        %if &outdat eq %then %do;
                          %put ERROR: Output dataset is missing in macro call;
                          %return;
                        %end;
                        %else %do;
                          *RFSTDTC from DM domain;
                          proc sort data=&lib..dm out=dm1(keep=usubjid rfstdtc);
                            by usubjid;
                          run;
                          
                          proc sort data=&indat;
                            by usubjid;
                          run;
    
                          *Applying the conditions;
                          data &outdat;
                            merge &indat(in=a) dm1;
                            by usubjid;
                            if a;
                            if ~cmiss(rfstdtc) and length(rfstdtc)>=10 then     rfstdt=input(scan(rfstdtc,1,"T"),is8601da.);
                            array invar {&cnt} $ &ndt;
                            array daten {&cnt} &ndt1 ;
                            array dayn {&cnt} &dy;
                            do i=1 to dim(invar);
                            if ~cmiss(invar(i)) and length(invar(i))>=10 then     daten(i)=input(scan(invar(i),1,"T"),is8601da.);
                            if ~cmiss(daten(i)) and ~cmiss(rfstdt) and  daten(i) ge     rfstdt  then dayn(i)=daten(i)-rfstdt+1;
                               else if ~cmiss(daten(i)) and ~cmiss(rfstdt) and     daten(i) lt rfstdt then dayn(i)=daten(i)-rfstdt;
                            end;
                            drop &ndt1 rfstdt i;
                          run;  
                          proc delete data=dm1;
                          quit;
                        %end;
                   %end;
              %end;
         %end;
    %mend dayder;

Back