options ls=78 ps=60;

data node2;
     set vwlib.node;

        /* change blanks to Zs for character data          */
     array missing {*} _CHARACTER_; 
     do i=1 to dim(missing);
        if missing{i}='' then missing{i}='Z';
     end;

proc sort data=node2;
    by id node_cod site_loc;

/***********************************************************/

   /* when all variables are transposed together           */
   /* transposed numeric variables will automatically be   */
   /* converted to character                               */
proc transpose data=node2 out=nodet prefix=var;
   var node_code--bulky;
   by id malig_no;
run;

data nodet;
   set nodet;

      /* changes numeric variable from character back      */
      /* into a numeric                                    */
   size=input(node_siz, 5.1); 
run;

/***********************************************************/

   /* when numeric and character variables are             */
   /* transposed separately                                */ 

   /* character variables                                  */
proc transpose data=node2 out=nodet1;
   var node_cod site_loc bulky;
   by id malig_no;
run;

   /* numeric variables                                    */
proc transpose data=node2 out=nodet2;
   var node_siz;
   by id malig_no;
run;

data nodet;
   merge nodet1 nodet2; 
   by id malig_no;
run;

/***********************************************************/

   /* create a macro to rename                             */
%macro r (a, name, new);
   data &a;
   set nodet;
   by id malig_no;
   %local i;
   %do i=1 %to 3;
       if  _NAME_="&name" then
           do;
               &new&i=var&i;
               if &i=1 & &new&i='' then delete;
           end;
       else delete;
   %end;
   drop _NAME_ var1-var3;
run;
%mend r;

%r(b, NODE_COD, node);
%r(c, SITE_LOC, site);
%r(d, NODE_SIZ, size);
%r(e, BULKY   , bulk);

data all;
   merge b c d e;  
   by id malig_no;

      /* change Zs back to blanks for character data       */
   array missing {*} node1-node3 site1-site3 size1-size3
                     bulk1-bulk3;
   do i=1 to dim(missing);
      if missing{i}='Z' then missing{i}='';
   end;

   array valid {3} node1-node3;
   a='/'
   b='_';
   do i=1 to 3;
      if index(valid{i},a) ne 0 then 
         valid{i}=translate(valid{i}, b, a);
   end;

         /* combine nodal sites when more than             */
         /* one of same node for a patient                 */
      prev_n='    ';
      prev_s='    ';
      array node{3} node1-node3;
      array site{3} site1-site3;
      array s{3} s1-s3;
      do i=1 to 3;
         s{i}=site{i};
         if node{i}=prev_n then s{i}=trim(prev_s)||site{i};
         if s{i} not in ('', 'L', 'M', 'R', 'LR')
            then put id= s{i}=;
         prev_n=node{i};
         prev_s=site{i};
      end;

%macro assign (n, site);
   %local i;
   %let z=sz;
   %let b=bl;
   %do i=1 %to 3;
     if node&i="&n" then 
     do;
         &n=s&i;
         if site&i="&site" then
            do;
                &site&n&z=size&i;
                &site&n&b=bulk&i;
            end;
     end;
   %end;
%mend assign;

%assign(AXIL,);
%assign(AXIL, L);
%assign(AXIL, R);

%assign(GAST,);
%assign(GAST, M);

%assign(INGU,);
%assign(INGU, L);
%assign(INGU, R);

drop i prev_n prev_s node1-node3 site1-site3
   s1-s3 size1-size3 bulk1-bulk3;
run;