BookmarkSubscribeRSS Feed
ssv
Fluorite | Level 6 ssv
Fluorite | Level 6

Hi Everyone,

 

I am trying to merge SDTM parent domain with supp domain by using macro. Each time I call the macro I need to pass one SDTM domain name and create a New dataset which is the merged dataset(Parent and Supp), Which is making me to call the macro multiple times and which is not dynamic. I need some help to make this macro dynamic which will automatically check and call all the domains available in my library and check if that domain has a SUPP domain or not, If there is a SUPP domain, then I want to merge Parent and SUPP domains and if there is no SUPP domain, it will keep the Parent domain as is.

 

For Example: if I have DM, SE, SV, AE,  DS domains in my library. Macro need to dynamically call all these 5 available domains one by one automatically available in that library. As DM, AE, DS will have SUPP domains, then it should merge Parent domain (Ex: DM) with SUPP domain (Ex: SUPPDM) into a new dataset named XX_MERG (Ex: DM_MERG). If domain doesn't have SUPP domain (Ex: SE, SV), it should leave as is. 

 

Please find my macro below and help to make it dynamic.

 

%macro combine(in=, out=, dst=);

        proc sort data=&in.         out=&in.;
                  by usubjid &in.seq;
         run;

         proc sort data=supp&in.  out=supp&in.;
                   by usubjid idvarval qnam;
          run;

         proc transpose data=supp&in. out=supp&in._ (drop=_NAME_ _LABEL_);
                    by usubjid idvarval;
                    id qnam;
                    idlabel qlabel;
                    var qval;
          run;

         data supp&in._;
                    set supp&in._;
                    &in.seq=input(idvarval, best.);
                   drop idvarval;
         run;

          proc sort data=supp&in._;
                      by usubjid &in.seq;
          run;

         data &out.;
                      merge &in.(in=a) supp&in._;
                      by usubjid &in.seq;
                       if a;
          run;

%mend;

 

Instead of calling macro multiple times with each domain name per call as shown below. I want macro to check all the domains available in my library and call them one by one  if it has SUPP domain.

 

%combine(in=dm, out=dm_merg);
%combine(in=ae, out=ae_merg);
%combine(in=ds, out=ds_merg);


2 REPLIES 2
s_lassen
Meteorite | Level 14

The simplest solution is to modify the original macro so that it checks if the data exists, and exits if there are no data, e.g.:

%macro combine(in=, out=, dst=);
  %if not %sysfunc(exist(&in.)) %then %do;
     %put Table &in not found;
     %return;
     %end;
  %if not %sysfunc(exist(supp&in.)) %then %do;
     %put Table SUPP&in not found;
     %return;
     %end;   
/* and the rest of the macro as before */

Then you can just call the macro for all the domains, even if some of them do not exist:

%combine(in=dm, out=dm_merg);
%combine(in=se, out=se_merg);
%combine(in=sv, out=sv_merg);
%combine(in=ae, out=ae_merg);
%combine(in=ds, out=ds_merg);
hashman
Ammonite | Level 13

@ssv:

 

Generate a list of all data set names where a supp domain name matches a parent domain name, then go through the names in the list in a loop. Sort of like:

proc sql noprint ;                                                                                                                                                                                                                                              
  select memname into :supplist separated by " " from dictionary.tables where libname = "WORK" and memname not eqt "SUPP"                                                                                                                                       
  and    memname in (select substr (memname, 5)  from dictionary.tables where libname = "WORK" and memname     eqt "SUPP")                                                                                                                                      
  ;                                                                                                                                                                                                                                                             
quit ;                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                
%macro combine (list=, dst=) ;                                                                                                                                                                                                                                  
  %local i ;                                                                                                                                                                                                                                                    
  %do i = 1 %to sysfunc (countw (&list)) ;                                                                                                                                                                                                                      
    %let in = %scan (&list, &i) ;                                                                                                                                                                                                                               
    proc sort data = &in out = &in ;                                                                                                                                                                                                                            
      by usubjid &in.seq ;                                                                                                                                                                                                                                      
    run ;                                                                                                                                                                                                                                                       
    proc sort data = supp&in  out = supp&in ;                                                                                                                                                                                                                   
      by usubjid idvarval qnam ;                                                                                                                                                                                                                                
    run ;                                                                                                                                                                                                                                                       
    proc transpose data = supp&in out = supp&in._ (drop = _:) ;                                                                                                                                                                                                 
      by usubjid idvarval ;                                                                                                                                                                                                                                     
      id qnam ;                                                                                                                                                                                                                                                 
      idlabel qlabel ;                                                                                                                                                                                                                                          
      var qval ;                                                                                                                                                                                                                                                
    run ;                                                                                                                                                                                                                                                       
    data supp&in._ (drop = idvarval) ;                                                                                                                                                                                                                          
      set supp&in._ ;                                                                                                                                                                                                                                           
      &in.seq = input (idvarval, best.) ;                                                                                                                                                                                                                       
    run ;                                                                                                                                                                                                                                                       
    proc sort data = supp&in._ ;                                                                                                                                                                                                                                
      by usubjid &in.seq ;                                                                                                                                                                                                                                      
    run ;                                                                                                                                                                                                                                                       
    data &in._merg ;                                                                                                                                                                                                                                            
      merge &in (in = _in) supp&in._ ;                                                                                                                                                                                                                          
      by usubjid &in.seq ;                                                                                                                                                                                                                                      
      if _in ;                                                                                                                                                                                                                                                  
    run ;                                                                                                                                                                                                                                                       
  %end ;                                                                                                                                                                                                                                                        
%mend ;                                                                                                                                                                                                                                                         
                                                                                                                                                                                                                                                                
%combine (list=&supplist)             

This way, you don't have to call the same macro a bunch of times and/or determine which domains to use as an argument by eyeballing your library. Leave this tedious and error-prone work to the computer - you're using it anyway.

 

Kind regards

Paul D. 

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
  • 2 replies
  • 3306 views
  • 0 likes
  • 3 in conversation