/*
/ Program : trnslvls.sas
/ Version : 1.0
/ Author : Roland Rashleigh-Berry
/ Date : 28-Oct-2011
/ Purpose : To transpose levels data from the %freqlvls macro
/ SubMacros : %varfmt
/ Notes : This macro expects the variables LVL1ORD, LVL1, LVL2ORD etc. as
/ created by the %freqlvls macro.
/
/ Informats can be specified at each level to override the default
/ order sequence. The %mkordinfmt macro might be useful for
/ creating these informats.
/
/ If you set alllowlvl=yes then you have to specify an ordering
/ informat for that level.
/
/ Usage : %trnslvls(dsin=myds,lvls=5,trtvar=trtarm,trtord=99,prefix=TRT,
/ dsout=mydsout,plugwith=" 0 ( 0.0) 0")
/ %trnslvls(dsin=both,dsout=tranboth,var=str,trtvar=tpatt,
/ trtord="XXX",alllowlvl=yes,alllowwhere=lvl5 ne ".",
/ plugwith=" 0 ( 0.0) 0",lvls=5,lvl5infmt=int.,
/ lvl1anylbl="Patients with any AE")
/===============================================================================
/ PARAMETERS:
/-------name------- -------------------------description------------------------
/ dsin Input dataset
/ lvls Number of levels
/ var Variable to transpose
/ dsout Output dataset
/ trtvar Treatment variable
/ trtfmt Treatment variable format (to override existing format)
/ trtord Treatment value for ordering
/ prefix=TRT Prefix for transposed variables
/ plugwith Plugging value for transposed variables (optional)
/ byvars By variables (optional)
/ alllowlvl=no If this is set to yes then it will ensure the complete set
/ of the lowest level values present is represented for the
/ higher levels.
/ alllowwhere An optional where clause to apply to the alllowlvl terms.
/ lowinfmt The ordering informat for the lowest level (must be
/ specified for alllowlvl=yes).
/ lvlv1-9infmt Optional informats for changing the default LVL1ORD etc.
/ values. Note that these values should end with a period.
/ lvl1anylbl Quoted string to replace the "ANY " level 1 label. If you
/ set this to " " then this high level total will be dropped.
/===============================================================================
/ AMENDMENT HISTORY:
/ init --date-- mod-id ----------------------description------------------------
/ rrb 28Oct11 New (v1.0)
/===============================================================================
/ Copyright (C) 2011, Roland Rashleigh-Berry. Use of this software is by license
/ only commencing 01 Jan 2012 although permission is granted to use these macros
/ for educational or demonstration purposes and by drug regulatory agencies.
/
/ Users should ensure this software is suitable for the purpose to which it is
/ put and to provide adequate checks on the accuracy of any values produced as
/ no guarantee can be given that the results displayed by this software are as
/ expected and no liability is accepted for any damage caused through use of any
/ incorrect output produced. Only use this software if you agree to these terms.
/=============================================================================*/
%put MACRO CALLED: trnslvls v1.0;
%macro trnslvls(dsin=,
lvls=,
var=,
dsout=,
trtvar=,
trtfmt=,
trtord=,
prefix=TRT,
plugwith=,
byvars=,
alllowlvl=no,
alllowwhere=,
lowinfmt=,
lvl1infmt=,
lvl2infmt=,
lvl3infmt=,
lvl4infmt=,
lvl5infmt=,
lvl6infmt=,
lvl7infmt=,
lvl8infmt=,
lvl9infmt=,
lvl1anylbl=
);
%local i err errflag ;
%let err=ERR%str(OR);
%let errflag=0;
%if not %length(&dsin) %then %do;
%let errflag=1;
%put &err: (trnslvls) No dataset supplied to dsin=;
%end;
%if not %length(&var) %then %do;
%let errflag=1;
%put &err: (trnslvls) No variable name to transpose supplied to var=;
%end;
%if not %length(&lvls) %then %do;
%let errflag=1;
%put &err: (trnslvls) No levels count supplied to lvls=;
%end;
%if not %length(&prefix) %then %do;
%let errflag=1;
%put &err: (trnslvls) No prefix supplied to prefix=;
%end;
%if not %length(&trtvar) %then %do;
%let errflag=1;
%put &err: (trnslvls) No treatment variable supplied to trtvar=;
%end;
%if not %length(&trtord) %then %do;
%let errflag=1;
%put &err: (trnslvls) No treatment ordering value supplied to trtord=;
%end;
%if %length(&trtvar) %then %do;
%if not %length(&trtfmt) %then %let trtfmt=%varfmt(%scan(&dsin,1,%str(%()),&trtvar);
%if not %length(&trtfmt) %then %do;
%let errflag=1;
%put &err: (trnslvls) No format assigned to treatment variable "&trtvar" and none specifed to trtfmt=;
%end;
%end;
%if &errflag %then %goto exit;
%if %length(&lowinfmt) %then %let lvl&lvls.infmt=&lowinfmt;
%if not %length(&dsout) %then %let dsout=&dsin;
%if not %length(&alllowlvl) %then %let alllowlvl=no;
%let alllowlvl=%upcase(%substr(&alllowlvl,1,1));
%if &alllowlvl EQ Y and not %length(lvl&lvls.infmt) %then %do;
%put &err: (trnslvls) No informat specified to lvl&lvls.infmt for all-low-level ordering;
%got exit;
%end;
%if &alllowlvl EQ Y %then %do;
data _trnslow1;
set &dsin
%if %length(&alllowwhere) %then %do;
(where=(&alllowwhere))
%end;
;
keep lvl&lvls;
run;
proc sort nodupkey data=_trnslow1;
by lvl&lvls;
run;
data _trnslow2;
set &dsin(where=(lvl%eval(&lvls-1)ord NE 0));
run;
proc sort nodupkey data=_trnslow2(keep=&byvars
%do i=1 %to %eval(&lvls-1);
lvl&i
%end;
);
by &byvars
%do i=1 %to %eval(&lvls-1);
lvl&i
%end;
;
run;
proc sql noprint;
create table _trnslow3 as select * from
(select * from _trnslow2),
(select * from _trnslow1);
quit;
proc sort data=_trnslow3;
by &byvars
%do i=1 %to &lvls;
lvl&i
%end;
;
run;
%end;
*- keep the sorting order for a later merge -;
proc sort data=&dsin(keep=&byvars &trtvar lvl:
where=(&trtvar=&trtord
%if &alllowlvl EQ Y %then %do;
and lvl&lvls.ord=0
%end;
)) out=_lvlord(drop=&trtvar
%if &alllowlvl EQ Y %then %do;
lvl&lvls.ord lvl&lvls
%end;
);
by &byvars
%do i=1 %to &lvls;
lvl&i
%end;
;
run;
*- put the variable label into a variable -;
data _lvltran;
length _idlabel $ 120;
set &dsin;
_idlabel=put(&trtvar,&trtfmt);
run;
*- sort ready for the transpose -;
proc sort data=_lvltran;
by &byvars
%do i=1 %to &lvls;
lvl&i
%end;
&trtvar
;
run;
*- transpose -;
proc transpose data=_lvltran prefix=&prefix
out=_lvltran(drop=_name_);
by &byvars
%do i=1 %to &lvls;
lvl&i
%end;
;
id &trtvar;
idlabel _idlabel;
var &var;
format &trtvar;
run;
%if &alllowlvl EQ Y %then %do;
data _lvltran;
merge _lvltran _trnslow3;
by &byvars
%do i=1 %to &lvls;
lvl&i
%end;
;
run;
%end;
*- merge the ordering back in and plug gaps -;
data &dsout;
merge _lvlord _lvltran;
%if %length(&plugwith) %then %do;
array _trt &prefix:;
%end;
by &byvars
%if &alllowlvl EQ Y %then %do;
%do i=1 %to %eval(&lvls-1);
lvl&i
%end;
%end;
%else %do;
%do i=1 %to &lvls;
lvl&i
%end;
%end;
;
%if %length(&plugwith) %then %do;
do over _trt;
if missing(_trt) then _trt=&plugwith;
end;
%end;
%do i=1 %to &lvls;
%if %length(&&lvl&i.infmt) %then %do;
if lvl&i NE: "ANY " then lvl&i.ord=input(lvl&i,&&lvl&i.infmt);
%end;
%end;
%if %length(&lvl1anylbl) %then %do;
if lvl1=:"ANY " then lvl1=&lvl1anylbl;
if lvl1=" " then delete;
%end;
run;
*- delete work datasets -;
proc datasets nolist;
delete _lvlord _lvltran
%if &alllowlvl EQ Y %then %do;
_trnslow1 _trnslow2 _trnslow3
%end;
;
run;
quit;
%goto skip;
%exit: %put &err: (trnslvls) Leaving macro due to problem(s) listed;
%skip:
%mend trnslvls;