Download A SAS Macro to Present a Summary Table of the Number of Patients Having Experienced Adverse Events in a Clinical Trial

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Medical ethics wikipedia , lookup

Adherence (medicine) wikipedia , lookup

Patient safety wikipedia , lookup

Pharmacovigilance wikipedia , lookup

Pharmacogenomics wikipedia , lookup

Transcript
A SAS Macro to Present a Summary Table of the Number of
Patients Having Experienced Adverse Events in a Clinical
Trial
Christoph Gerlinger* and Ursula Franke**
*
Laboratoires Fournier S.C.A. and
biodat Gesellschaft für Biometrie und Statistik mbH
**
Summary
One of the major concerns when testing a new drug treatment are adverse events.
An adverse event is defined as any medical event that is experienced by a patient
in the course of a clinical trial and that compromises the patient's well-being.
This definition includes diseases as well as accidents.
For presentation and analyses, adverse events are coded using standardised
terminology. These classifications have hierarchical levels of detail. For
example, the COSTART code consists of "body systems" which are divided into
"subcategories" which are themselves subdivided into "terms".
A summary table of the number and percentage of events can be easily computed
using PROC TABULATE. However, it is not possible to present in the same
way the number of patients having experienced at least once an event which falls
into a given category, since a patient may have several events of the same kind or
several events which fall into the same category of a higher level.
A SAS® macro is presented which calculates the number and percentage of
patients falling into each body system, subcategory and term of the classification,
as well as the number of events that occured.
Introduction
A clinical trial is a controlled scientific procedure to assess the efficacy and the
safety of a drug treatment in humans. Groups of patients are treated in a
standardised way in order to allow the comparison of different drug treatments.
Usually a new or experimental drug is compared to a known reference drug or
placebo.
In the perspective of drug safety, a clinical trial design has to incorporate the
evaluation of adverse events, so that the drug-related events (i.e. side effects) can
be detected at an early stage of the development of a new drug. Any undesirable
medical experience, whether or not related to the tested drug, is considered an
adverse event.
In order to compare the adverse events of different drug treatments, one wishes to
present a summary table like Table 1 below, using in this example the COSTART 1
classifiaction of adverse events. This table is part of the report of the clinical trial.
If the new drug is tested successfully, the study report is one of the documents sent
to the health authorities in order to obtain the licence to sell the new drug.
The Problem
When analysing the adverse events which occurred during a clinical trial, one is
interested not only in the number of a given event, such as headache, but also in
the number and percent of patients who had headache(s). This number of patients
experiencing headache at least once cannot be calculated using PROC
TABULATE 2 since PROC TABULATE can only display the number of
observations in a SAS dataset. Also, PROC TABULATE can only print all
categories of a class variable, so that it would print the number of patients with
headache, as well as the number of patients without headache next to it. However,
in this context the number of patients without a given adverse event is of no
interest to the reader.
Table 1: Summary Table of Adverse Events
COSTART Classification of
Adverse Events
Any Event
BODY AS A WHOLE
BODY AS A WHOLE (GENERAL)
ALLERGIC REACTION
FEVER
FLU SYNDROME
HEAD
EDEMA FACE
HEADACHE
CARDIOVASCULAR SYSTEM
CARDIAC DISORDERS
ANGINA PECTORIS
Drug A (n=13)
Drug B (n=12)
Number Numbe
Numbe Number
of
r of
% of
r of
of
% of
Events Patients Patients Events Patients Patients
36
21
12
6
3
3
9
6
3
15
9
3
10
7
5
4
2
2
5
4
2
6
5
2
76.92
53.85
38.46
30.77
15.38
15.38
38.46
30.77
15.38
46.15
38.46
15.38
20
11
8
3
2
3
3
3
.
9
5
1
5
4
3
2
1
2
2
2
.
3
2
1
41.67
33.33
25.00
16.67
8.33
16.67
16.67
16.67
.
25.00
16.67
8.33
BRADYCARDIA
VASCULAR DISORDERS
MIGRAINE
VASCULITIS
6
6
3
3
4
3
2
2
30.77
23.08
15.38
15.38
4
4
2
2
2
1
1
1
16.67
8.33
8.33
8.33
Another problem lies in the computation of totals and subtotals. SAS PROC
TABULATE can print totals and subtotals of a table row or column. This is
sufficient to display totals and subtotals of the number of adverse events which
occurred. However, a given patient can have several different adverse events and
should nevertheless be counted only once for the total number of patients who
have experienced any adverse event. For example, a patient having both fever
and flu would be counted only once for the body system "BODY AS A
WHOLE".
Furthermore, we need to insert the subtotals into the table and to indent them
properly.
The Solution
A SAS macro 3 has been developed in order to produce a summary table like
Table 1 of the number of events and the number and the percentage of patients
who have experienced adverse events with different treatment regimens. The
macro creates a special SAS dataset with the table entries which is then
formatted and printed using PROC TABULATE.
The SAS macro requires two input SAS datasets. The first is a dataset containing
one observation per patient which allows the calculation of the total number of
patients per group. It contains at least a variable which identifies the patient
(typically the patient number) and a variable which indicates the patient's
treatment ("Drug A" or "Drug B" in our example). The second input dataset
contains one observation per adverse event that occurred. There are several
observations for a given patient if this patient had several adverse events or no
observation if the patient had no adverse event at all during the clinical trial. If a
patient had the same event at several occasions, the dataset contains one
observation per occurrence of the adverse event.
The table can be custom formatted since the formats of the different table
columns as well as the row title space 4 can be passed to the macro as macro
parameters. The macro allows the presention of only a subset of the adverse
events, such as all events related to the study drug or all serious adverse events.
In addition, the selection of a patient subset, such as female patients, is possible.
This is achieved by passing two "where clauses" as macro parameters. The first
"where clause" is used to select events and is applied to the dataset containing
the adverse events. The second "where clause" is used to select patients and is
applied to both the events dataset and the dataset containing all patients. It
should be noted that the variables used in the "where clause" for the events have
to exist in the events dataset and the variables used for the patient selection have
to exist in both datasets. The latter is necessary since if one wishes to present, for
example, the adverse events of the male patients, the macro has to calculate not
only the number of male patients but also the number of the events experienced
by male patients.
The insertion of the various subtotals is achieved by using a numeric code
variable with a SAS format. In fact, a six digit number has been assigned to each
COSTART term. The first two digits of the code present the body system and its
first four digits present the group. To insert the totals we use the following seven
digit code: for COSTART terms, the number 2 is used as seventh digit; for
COSTART groups, the numbers 001 are used after the four digits representing
the group; and for body systems, the numbers 00000 are used after the two digits
representing the body system. This yields a global code in ascending numeric
order which includes all subtotals. For the grand total of any adverse event, the
code 0 is used.
The indention of the different levels of the COSTART code in the tables above
has been obtained using a simple trick. The SAS format contains a special
character (@ in our example) as the first character of the label, as shown in the
following excerpt of the format definition.
proc format;
value costart 1000000 = "BODY AS A WHOLE"
1000001 = "@ BODY AS A WHOLE (GENERAL)"
1000032 = "@
ALLERGIC REACTION";
run;
Once PROC TABULATE has produced the table, the special character @ is
replaced by a blank character using an editor.
Description of the SAS Macro
After assigning defaults values in case no values are given in the macro call for
formatting and subgroup selection parameters, PROC SUMMARY2 is called to
create a SAS dataset containing an observation with the number of patients per
treatment group plus one observation for the total number of patients, regardless
of treatment group. This dataset is used in two ways: First to create a control
dataset for input into PROC FORMAT2 for the treatment groups which includes
the number of patients who are present, such as "Drug A (n=13)". The second
use is to create a weight variable defined as 100/(number of patients in treatment
group) which gives the weight of one patient as percentage of the number of
patients in the treatment group. This weight variable is later summed over all
patients having experienced a given adverse event to yield the percentage of
patients in the treatment group having had this adverse event at least once.
Next, PROC SUMMARY is called to create a SAS dataset containing exactly
one observation per patient and per COSTART term, group, or body system. In
this dataset each patient occurs only once for any given adverse event, thus
eliminating to count him twice in case of multiple events. The total number of
events is still available in the variable _FREQ_ which is created by PROC
SUMMARY. This output dataset is then merged with the dataset containing the
patient weight variable and the SAS bit-testing feature 5 is used to retain the
observations with the right crossing of the class variables of PROC SUMMARY.
The resulting dataset is used as input to PROC TABULATE which prints the
summary table in the form shown in Table 1. Finally PROC CATALOG2 and
PROC DATASETS2 are used to delete all datasets and the format created during
the macro execution in order to avoid their use afterwards by mistake.
SAS Macro Source Code
%macro _tabaes ( aesdat, aeswhere,
patdat, patwhere,
group, grpfmt, total, codpat,
rts, nevtfmt, npatfmt, pctnfmt );
%*
%*
%*
%*
%*
%*
%*
%*
%*
%*
%*
%*
%*
%*
%*
%*
DESCRIPTION:;
============;
;
PARAMETERS:;
aesdat : dataset with coded adverse events (one line per event);
contains variables costart = COSTART Term;
cosgroup = COSTART Group;
cosbody = COSTART Body System;
as well as the &group and &codpat variables and all;
variables used in the &aeswhere AND in the &patwhere clauses;
aeswhere: subset where clause for events. DEFAULT is no clause;
patdat : dataset with all patients (one line per patient);
patwhere: subset where clause for patients, it is also applied to the
events dataset. DEFAULT is no clause;
group
: name of treatment group variable;
grpfmt : name of treatment group format;
%*
%*
%*
%*
%*
%*
%*
%*
%*
%*
%*
%*
%*
%*
%*
%*
%*
%*
total
: flag, triggers total column if set to Yes;
codpat : name of patient identifier;
rts
: proc tabulate rts option. DEFAULT is 30;
nevtfmt : numeric format for number of events column. DEFAULT is 8.0 ;
npatfmt : numeric format for number of patients column. DEFAULT is 8.0 ;
pctnfmt : numeric format for percent of patients column. DEFAULT is 8.2 ;
;
PREREQUISITS;
the format COSTART must be available;
;
SIDEEFFECTS;
;
the following local datasets are created: __pats __fmt __sumaes __table;
they are deleted at the end of the macro execution;
;
the following local formats are created: __aesgr $_aesgr;
they are deleted at the end of the macro execution;
;
%* definitions and defaults;
%local __grpfmt;
%if
%if
%if
%if
%if
%if
"&aeswhere"
"&patwhere"
"&rts."
"&nevtfmt"
"&npatfmt"
"&pctnfmt"
eq
eq
eq
eq
eq
eq
""
""
""
""
""
""
%then
%then
%then
%then
%then
%then
%let
%let
%let
%let
%let
%let
aeswhere=1; %* 1=true;
patwhere=1; %* 1=true;
rts=30;
nevtfmt=8.0; %* default;
npatfmt=8.0; %* default;
pctnfmt=8.2; %* default;
%* first step: get number of patients per group in dataset __pats;
proc summary data=&patdat. missing;
where &patwhere;
class &group;
format &group &grpfmt.. ;
output out=__pats;
run;
%* second step: create control dataset __fmt for use with proc format to;
%*
define a format for the treatments including the number ;
%*
of patients per treatment group.;
%*
create dataset __pats with variable __weight to merge with;
%*
events dataset (below);
%*
the variable __weight is defined as 100/# of patients per;
%*
group, its sum yields the percentage of patients ;
data __pats(keep=&group __weight )
__fmt (keep=start end label fmtname);
set __pats;
length label $40.;
__weight = 100 / _freq_;
%* check whether format is numeric or character;
%if "%substr(&grpfmt,1,1)" ne "$" %then %do;
retain fmtname '__AESGR';
%let __grpfmt = __AESGR;
if &group ne . then
label = put(&group,&grpfmt..)||" (n="||trim(left(_freq_))||")";
else
label = "Total (n="||trim(left(_freq_))||")";
start = &group;
end = &group;
%end;
%else %do;
retain fmtname '$_AESGR';
%let __grpfmt = $_AESGR;
length start $40. end $40.;
if &group ne ' ' then
label = trim(put(&group.,&grpfmt..))||" (n="||trim(left(_freq_))||")";
else
label = "Total (n="||trim(left(_freq_))||")";
start = &group;
end = &group;
%end;
run;
%* create local format for treatment groups;
proc format cntlin=__fmt;
run;
%* third step: count the number of patients having an event at least once;
%*
create dataset __sumaes. Its variable _freq_ give the number;
%*
of events for a given event and patient;
proc summary data=&aesdat. missing;
where &aeswhere and &patwhere;
class &group &codpat costart cosgroup cosbody;
format &group &grpfmt.. ;
output out=__sumaes;
run;
proc sort data=__sumaes;
by &group;
run;
%* fourth step: create final dataset __table used for proc tabulate;
%*
the variable __rowvar is created to insert the body systems;
%*
and costart groups into the costart terms;
data __table;
merge __sumaes __pats;
by &group;
select ;
when ( _type_ eq '11100'B
when ( _type_ eq '11010'B
when ( _type_ eq '11001'B
when ( _type_ eq '11000'B
)
)
)
)
__rowvar=10*costart+2;
__rowvar=1000*cosgroup+1;
__rowvar=100000*cosbody+0;
__rowvar=0;
%* id total flag is set then keep sums over all groups;
%if "%upcase(&total)" eq "YES" %then %do;
when ( _type_ eq '01100'B ) __rowvar=10*costart+2;
when ( _type_ eq '01010'B ) __rowvar=1000*cosgroup+1;
when ( _type_ eq '01001'B ) __rowvar=100000*cosbody+0;
when ( _type_ eq '01000'B ) __rowvar=0;
%end;
otherwise delete;
end;
format __rowvar costart.;
run;
%* fifth step: use proc tabulate to print table;
proc tabulate missing format=8.0 data=__table;
format &group &__grpfmt..;
class __rowvar &group;
var __weight _freq_;
table __rowvar=' ',
&group=' ' * ( _freq_=' '
* sum = 'Number of Events'*f=&nevtfmt.
__weight=' ' * ( n = 'Number of Patients'*F=&npatfmt.
sum = '% of Patients'*f=&pctnfmt. ) )
/ rts=&rts. box = 'COSTART Classification of Adverse Events';
run;
%* sixth step: delete datasets and format created during macro execution;
proc catalog catalog=formats;
%if "%substr(&grpfmt,1,1)" ne "$" %then %do;
delete __AESGR /et=format;
%end;
%else %do;
delete _AESGR /et=formatC;
%end;
run;
proc datasets library=work nolist;
delete __sumaes __pats __fmt __table;
run;
%mend _tabaes;
Acknowledgement
The authors gratefully acknowledge the medical assistance of Nadine IndriAnnesley of Laboratoires Fournier's Pharmacovigilance Department.
Addresses of the authors:
Christoph Gerlinger
Laboratoires Fournier S.C.A.
Biometrics Department
50, rue de Dijon
F-21121 Daix
France
Ursula Franke
biodat Gesellschaft für Biometrie
und Statistik mbH
Oranienstraße 25
D-10999 Berlin
Germany
Telephone: (+33) 80 44 75 72
Telefax:
(+33) 80 44 75 69
Email: [email protected]
Telephone: (+49) 30 / 614 80 71
Telefax:
(+49) 30 / 614 80 77
Email:
[email protected]
References
1
U.S. Food and Drug Administration, 'COSTART' - Coding Symbols For
Thesaurus of Adverse Reaction Terms, Fourth Edition, Rockville, MD: U.S. Food
and Drug Administration, 1993.
SAS Institute Inc., SAS® Procedures Guide, Version 6, Third Edition, Cary, NC:
SAS Institute Inc., 1990.
2
3
SAS Institute Inc., SAS® Guide to Macro Processing, Version 6, Second Edition,
Cary, NC: SAS Institute Inc., 1990.
SAS Institute Inc., SAS® Guide to TABULATE Processing, Second Edition, Cary,
NC: SAS Institute Inc., 1990. page 118.
4
SAS Institute Inc., SAS® Procedures Guide, Version 6, Third Edition, Cary, NC:
SAS Institute Inc., 1990. page 381.
5
SAS is a registered trademark of SAS Institute Inc., Cary, NC.