%popfmt

(Author: Roland Rashleigh-Berry                                                    Date: 28 Apr 2006)

Introduction

This page is about a very important macro named %popfmt. You have to call this macro before you can call the major reporting macros %unistats and %npcttab or any other major reporting macros that might get written for the reporting system. At its simplest level, it is a macro that creates a treatment format based on the treatment format you give it (or the one assigned to the treatment variable) but with treatment totals at the end. So suppose you had a treatment arm that formats to "Drug A" it would create a new format so that the treatment arm would be formatted to "Drug A@(N=xxx)" where "xxx" is the total population for that treatment arm. Even if you do not think you need such a format, you still have to call this macro as it provides useful information to other reporting macros through the global macro variables it sets up.

%popfmt calls other macros. To see a list of dependencies then click here.

Calling %popfmt

The macro has a number of parameters and these are shown below, copied from the macro header. Note that the first three parameters are "positional" parameters. "Positional" parameters do not need you to supply the parameter name with an equals sign when you specify the values. You just give the values directly but they must be in the specified order and they must be the first values you pass to the macro.
 
/ dsin              (pos) Input dataset
/ trtvar            (pos) Treatment arm variable
/ dstrt             (pos) Input dataset containing complete set of trtvar values.
/                   If you are sure your input dataset contains all the trtvar
/                   values you need then you need not specify this. If you do
/                   specify this and there is no data in your input dataset
/                   corresponding to a treatment arm then this will have (N=0).
/ trtfmt            (Optional) treatment variable format. If omitted it uses
/                   the currently assigned format for the treatment variable.
/ uniqueid=patno    Variable(s) that uniquely identify a patient. If more
/                   than one variable then separate with spaces.
/ prefix=TRT        Prefix for a list of variables that will end in the unique
/                   values of the treatment variable that will get written to
/                   the global macro variable _trtlist_ . If you transpose your
/                   data with this prefix then the variable list can be used in
/                   your proc report.
/ totaln=99         Number value to represent "total" for all treatment arms.
/ totalc="Z"        Character value (in quotes) to represent "total" for all
/                   treatment arms.
/ pvaluen=9999      Number value to represent the pvalue treatment arm.
/ pvaluec="ZZZZ"    Character value to represent the pvalue treatment arm.
/ pvallbl="p-value" Label text for the pvalue treatment arm.
/ totstr=Total      Text to represent the "total" for all treatments. If you set
/                   this to null then the format created will not contain an
/                   entry for the total treatment groups.
/ split=@           Split character to put before the (N=xxx) ending. If you
/                   want a space instead then set this to %str( ).
/ suffix            (in quotes) suffix to put after the (N=xxx) ending as part
/                   of the created format. Default is nothing.

The first three parameters are positional to save you time typing. They will be the parameters you will most often set. The first positional parameter is the input dataset which is normally the "acct" dataset that you get after selecting on the "population". The population might be the "Full Analysis set". The second positional parameter is the treatment arm variable. The third positional parameter is a dataset you are sure contains a full set of treatment arm values, since the dataset you supplied as the second parameter, might not contain all the treatment arm values and yet will will probably need to show this treatment arm on the report, even with a zero population total. So a typical call to the %popfmt macro will look like this:
 
proc sort data=stat.acct(keep=patno trtgrp agegrp
                        where=(fascd=1 and agegrp=1))
           out=acct(drop=fascd);
  by patno;
run;

%popfmt(acct,trtgrp,stat.acct(where=(fascd=1)))

The other parameters are not positional so you must supply the name of the parameter when you specify the values. If you wanted your total column to have the label "Overall" rather than "Total" and you do not want a split character put before the "(N=xxx)" ending on the format created then you could make the call to %popfmt like this:
 
%popfmt(acct,trtgrp,stat.acct(where=(fascd=1)),totstr=Overall,split=%str( ))

Note that uniqueid= will be set to a value that is best for your site. It is the minimum variables that will uniquely define a patient. If you are using an acct dataset that is a collection from many studies then you will probably have to change this to ensure the set of variables defined a unique patient. You might have to set "uniqueid=site patient", for example, since you might have the same patient number in different studies being combined.

When %popfmt is called it sets up a large number of global macro variables as will be shown later. Another thing it does is to set up a dataset in the work area named _popfmt with two variables. The first variable is the treatment arm variable that you supplied and the second variable is "total" - the population total for that treatment arm. Added to the list of values for the treatment arms will be that for the treatment arm total. Using the macro defaults, this value will be numeric 99 if the treatment arm variable is numeric or the character "Z" if the treatment arm variable is character. This is shown above in the parameter list copied from the macro header. You can change these values if you wish when you call the macro. This dataset will be used by the major reporting macros to calculate percentages based on populations. If you write macros then you may need to use this dataset so it is important to know it is there.

Thinking with %popfmt

Not all the tables you produce will have columns that are treatment arms with population totals. Suppose you select on a single treatment arm and your columns are Adverse Events that are "related" to study drug and "regardless of relationship" to study drug. You may have patient counts and percentages but in this case the percentage will be that of the treatment arm population which will be the same for both columns. Using %popfmt is also applicable here, but you will have to learn how to think with %popfmt. The dataset you supply to %popfmt need not be an acct dataset, even if it contains patient details from that dataset, and the variable you define for the treatment arm need not be a real treatment arm variable. Staying with this example, the variable that shows relationship to the study drug might be "relatecd". This has to be the variable to merge on and the percentages calculated so we need to feed in a fake acct dataset to the %popfmt macro with the full population count in each value of relatecd. This is how that might be done. Note the creation of "fakeacct" with the full population output for relatecd=1 and relatecd=999.
 
proc format;
  value rel
  1="RELATED"
  999="REGARDLESS OF RELATIONSHIP"
  ;
run;

*- acct data -;
proc sort data=stat.acct(keep=protocol sitecd patient fascd trtcd age
                     where=(fascd=1 and trtcd=1 ))
           out=acct(drop=fascd trtcd);
  by protocol sitecd patient;
run;

data fakeacct;
  set acct;
  relatecd=1;output;
  relatecd=999;output;
  format relatecd rel.;
run;

%popfmt(fakeacct,relatecd,uniqueid=protocol sitecd patient,totstr=OVERALL)

The "fakeacct" dataset is only used to give the correct population total for both relatecd=1 and relatecd=999 and this creates the _popfmt dataset with these totals in that a later macro will use to calculate percentages. As soon as "fakeacct" has been used by %popfmt it can be deleted as it will no longer be required. The acct dataset is still required and will be used to merge with the adverse event data so that only data for that population is selected. Here is how it might be done:
 
*- adverse event data -;
proc sort data=s.adv(keep=protocol sitecd patient atpercd
                          amsoc ampt relatecd 
                    where=(atpercd=2))
           out=adv(drop=atpercd);
  by protocol sitecd patient;
run; 

*- set up duplicate for "regardless of relationship" -;
data adv;
  set adv;
  output;
  relatecd=999;
  output;
run;
 

*- merge acct and adv data -;
data adv;
  merge acct(in=_acct) adv(in=_adv where=(relatecd in (1,999)));
  by protocol sitecd patient;
  if _acct and _adv;
run;

Using the above method the data going into a reporting macro can merge with _popfmt on "relatecd" and calculate percentages.

There will be a lot of tables that the main reporting macros %popfmt, %unistats and %npcttab can handle that may not be obvious when you first look at the table. The above is such an example. As a rough guide, if a table looks similar in layout to one of the normal tables that come out of the main reporting macros, then it is likely that these macros can produce that table. But you have to be able to think with the %popfmt macro to make that possible.

The global macro variables set up

As mentioned in the Introduction, the %popfmt macro is a very important macro. It wites a lot of useful information to global macro variables that other reporting macros can use. For example, it writes what treatment variable was used and what the uniqueid= value was so later macros can default to these values and so save the user the bother of supplying these values. It calculates column widths so later macros can default to these widths. The idea is to provide enough information so that it is easy to call later macros with the minimum number of paraneters set. This is to aid in automation which is the ultimate goal the reporting system is seeking to achieve.

When global macro variables are set up or if macros alter the values of global macro variables already set up then it is a convention that the macro reports on this and writes the information to the log. Here is a real life example.
 
MSG: (popfmt) The following global macro variables have been set up
MSG: (popfmt) and can be resolved in your code.
_popfmt_=popfmt.   (output format with (N=xxx) population totals added)
_rawfmt_=TRTNARR.   (input format)
_popnfmt_=popnfmt.  (format for giving pure population totals)
_poptfmt_=poptfmt.  (copy of input format but containing total treatment arm)
_trtvar_=trtrand    (name of treatment variable)
_trtvartype_=N  (treatment variable type N/C)
_trttotstr_=99 (treatment total string identifier)
_uniqueid_=patient   (variable(s) used to uniquely identify subjects)
_trttotvar_=TRT99  (transposed treatment total variable)
_trtpvalstr_=9999  (p-value string identifier)
_trtpvalvar_=TRT9999  (p-value variable)
_trtpref_=TRT  (treatment variable prefix used in transpose)
_trtvarlist_=TRT1 TRT2 (transposed treatment variables)
_trtinlist_=1 2  (treatment arm values)
_trtnum_=2  (number of treatment arms)
_trtcwidths_=23 15    (column widths according to format popfmt.)
_trtfwidths_=23 15    (column widths according to format poptfmt.)
_trttotcwidth_=7   ("Total" column width according to format popfmt.)
_trttotfwidth_=5   ("Total" column width according to format poptfmt.)
_n1_=177
_n2_=187
_n99_=364

MSG: (popfmt) Dataset "_popfmt" has been created containing population totals
MSG: (popfmt) with one observation per treatment group and one observation for
MSG: (popfmt) the total of all treatment groups. Use this to merge with and
MSG: (popfmt) calculate percentages. Variables are as follows:
trtrand: Treatment group (dataset is sorted in this order)
total: Total population for the treatment group

Conclusion

You have been introduced to the very important macro %popfmt and you have seen how to use it and what information it writes to the log. It has been stressed that you have to be able to think with this macro so that you can use it and the other reporting macros to create tables that at first sight do not look as though they are capable of being produced using the reporting macros.
 


 

Use the "Back" button of your browser to return to the previous page.

contact the author