The title of this page is "Roland's Graphical Patient Profiler".
I'll explain what this means. To put it into context, it is to do with
patients
and their progress on a clinical trial. Taking the first word "Roland"
-- that's the guy who wrote this thing called a "graphical patient profiler".
It's
me! So that's the first word cleared up. And as for the rest of it,
the "graphical" part means "pretty pictures", if you like, so combined
with what's left, "patient profiler", it means something I wrote
so that you can see pretty pictures of what is happening to a
patient during the progress of a clinical trial.
At the time of writing this, in March 2008, graphical patient profilers
are a relatively new thing. But my prediction for the end of 2008 is that
every pharmaceutical company will have, or will want, a graphical patient
profiler so that Clinical people monitoring a trial can have a frequently-updated
pictorial representation of how all individual patients are doing on a
drug trial as well as an overall pictue of the progress of the whole clinical
trial. The idea is that a Clinical person can see, at a glance, all they
need to know about a trial or any individual patient such as their demography
details, their dosing, their lab results, their AEs with their start and
end dates along with the severity or seriousness of these AEs, their vital
signs, their concomitant medications with their start and end dates, and
everything else that is needed, in an easy-to-read pictorial form with
time going from left to right. Enough of words, now for pictures! See what
I mean by clicking on a dummy patient profile using the link below. You
will be able to create this output yourself as explained later.
The full explanation about the patient profiler will be given on five
pages starting with this one, and they should be read in the order given.
The following page can be linked to at the bottom of the previous page.
The first page (this one) will explain what RGPP is and you will be able
to download it and play with it. The second page will tell you how to transform
your data into a format that the patient profiler can use. The third page
will explain how you can enhance your output to include graphical legends
in pop-up widows so that where you have color-coded certain things, the
explanation of the colors can be made to appear. The fourth page will explain
how I expect you to set up your html for viewing the patient profiler output.
The fifth page will set out my vision for RGPP. You can link to these other
pages below, but I must stress that it is important that you have read
and understood the previous pages.
This page you are looking at now is an "html" page. The page above you
linked to was also an html page. "Html" stands for "hyper-text markup language"
but you don't have to worry about what that means. All you need to know
is that it is a common format for use over the Internet or Intranet
(for
where a company has their own collection of web sites that they don't want
outsiders to see). The dummy patient profile page you linked to above was
an "html" page that referred to a "gif" file. A "gif" file is a type of
image file. You have probably heard of "jpegs" - that's what your digital
camera creates. "Gifs" are image files that are commonly used for graphical
diagrams and this is applicable to patient profiles. "Html" pages and "gif"
images are very easy to distribute or allow access to. Clinicians following
the progress of a clinical trial will be able to log onto their local Intranet
and it is easily possible for patient profile graphics to be made available
to them. If need be, an "html" page with its associated "gif" file could
be emailed to anybody who needed it. In short - it is very easy to distribute
or make available graphical html files. Giving access to or sending graphical
patient profiles to clinicians will be simplicity itself if this format
is used. It is this style of output that will be created using my Patient
Profiler.
Another thing about html pages is that you can hide messages behind
shapes, text and pictures. If you move your cursor (mouse pointer) over
a shape, text or pictures then you can see this text behind it, if there
is any put there. Again, my patient profiler is aimed to fully exploit
that ability. People using it will be strongly encouraged to put full detail
in text form behind every object shown. So a bar that shows the period
an AE lasts will give extra details about the AE such as its system organ
class, its severity, whether it is considered serious or not plus any other
information a clinician needs to see, providing that data is recorded.
The same for Vital Signs or Lab values, even if these are shown as numeric
values on the chart. The same for drug dosing. So lurking behind every
representation of data, either in text or shape form, it is intended to
put fuller details so that a clinician just has to "mouse over" it to get
more details.
Now before we leave this section I would ask you to click on the dummy
patient profile above and mouse over the shapes and values displayed. Apart
from the demography details, all the other text values shown in the timescale
region and the shapes have more text behind it. Mouse over each one and
you will see.
The graphical patient profiler is aimed for viewing and not for
printing.
If it is printed out then not only will it be less clear but the information
hiding behind the values will be lost. So this is not something to be printed
and faxed to somebody. Instead, you can email the html page and its related
gif to people who need to see it. They will then have the full "picture"
and be able to see the text behind the values as well. Remember that html
format is easy to distribute. People don't have to be logged onto a server
to see it because you can email it to them. But, of course, you should
treat this sort of information as confidential and be careful who you send
it to.
What data does it work on?
You might be wondering what sort of data the patient profiler needs to
work on. The answer is any sort of data but there is a proviso that
will be explained. It can be raw data that is not clean. In can
be derived data that has been cleaned. It does not matter. But whatever
data you have has to be transformed into data the patient profiler
can understand. This can be a lot of work but when done once then the code
can hopefully be reused on other studies. Transforming the data is a lot
of bother but it is unavoidable. Putting displays of extra data behind
the values and shapes takes a lot of preparation and can't be done automatically.
You may choose to display values using different colors and this will not
be something that is in your original data. You may choose to display values
using a mixture of different letter heights. Again, this is not something
to be found in study data. So you have some transforming of data to do
to get the patient profiler to work.
The four patient profiler datasets
For the patient profiler to work, it requires four datasets that must be
named exactly as stated below. Their structure will be explained shortly
but first I will list them and say what they do.
There will be a dataset with only one observation in it that
contains the style settings for the patient profiler that controls the
general layout and colors and the default scale spacing to use. This dataset
is named rgpp_style. This dataset has many variables and takes a
while to set up but once set, can be used without change on all clinical
trials. It holds the unchanging values that dictate the patient profiler
layout style that is intended for use throughout an organisation without
alteration. If you are used to using sas macros then you should think of
this dataset as a "macro parameter dataset". In fact, the contents of this
dataset will be converted to effective macro parameters by the patient
profiler.
There will be a dataset with only one observation in it that
contains the global values for a run of the graphical patient profiler.
You would put the name of the patient variable in this, the folder destination
for the html pages and gif files produced and the scale you want to display.
This dataset is named rgpp_global. If you are used to using sas
macros then you should think of this dataset as a "macro parameter dataset".
In fact, the contents of this dataset will be converted to effective macro
parameters by the patient profiler.
There will be a dataset with one observation per patient (subject).
This will contain the subject identity, the html file name, the gif image
name and the start and end days for the data you want selected for a patient
and the start and end days to show on the scale. This dataset is named
rgpp_patients.
Lastly, there is the data you want to display. There will be multiple
observations per patient. This dataset should be is named rgpp_data.
In the following sections, the structure of each of these datasets will
be explained.
rgpp_style
This is the dataset that controls the general layout for the patient profiler
display. This dataset has a lot of variables that control the layout style.
You are expected to use one layout style only throughout an organisation.
Once the layout has been decided upon, this dataset is intended for use
throughout an organisation with no changes being made to it so that
the style of the reports is uniform throughout the organisation. The sas
programmer who sets this up is expected to know something of sas graphics,
especially in regard to choosing the values of ypixels, xpixels,
vpos
and hpos.
You can tailor the display of the patient profiler to get it to look
how you want. You can choose colors and fonts. You can choose the size
of the html page. You can choose how much of it you want to use for the
time display area and how much to leave for text on the left. What I will
say at this point is that you are required to choose some colors and because
of the way sas works, your color names must not be more than eight
characters long. This does not mean you are limited to colors with
names that are eight characters long or less. Any and every color in existence
can be referred to as an eight character name once you know how. So if
you wanted to use AntiqueWhite as a background then you can use
it. If you wanted to use DarkSlateBlue as the default text color
then you can use that as well. You just have to find out how to refer to
these colors by an eight character code and use that instead. This involves
a bit of study so I have written a page on this that explains it all very
clearly that you can link to below. It will open in a new window. Keep
referring to that page to become expert on choosing colors for your sas
html displays.
Assuming you can choose whatever color you like and refer to it by an
eight character name (or less) I will continue with the description of
the rgpp_settings dataset. What you will see below is an example of it
with settings filled in. Note that this is sas code you can use. You can
changes the settings but you must not change the length of the variables
or change their type. The variable declarations must not be changed. Just
their values. And you must make sure that numeric variables and given numeric
values and character variable are given character values that do not exceed
the allowed length.
Note that some of the numeric variables used are of the True/False type
and should only be given the numeric value "0" or "1". 0=False, 1=True.
Note that fonts declared below that are non-sas internal fonts must
be specified inside single quotes that in turn are contained in double
quotes. You are not seeing double!
All heights are in "cells", if you know "goptions" and annotate datasets.
The patient profiler uses the cell reference system, rather than percentages.
This is the sas default. Using cells is much better for "long" pages such
patient profile html pages.
This first dataset, with only one observation, has a lot of variables.
It dictates the style you want for the patient profiler output. Once this
dataset is created correctly it is intended to be used without change for
the forseeable future. You can always store this dataset somewhere, call
it with a "set" statement and override individual values in your code if
you need to.
data rgpp_style; *- This is the version 1.0 template for the RGPP style dataset.
-; *- The version of this dataset should match the version
of RGPP -; *- you are using which will be displayed in the log if you
call -; *- the macro with a positional parameter value set like
this: -; *- %rgpp(xxx)
-; *- Note that the above call only gives you information about
-; *- the macro and does not do any processing of data. Do
not use -; *- the word "check" (unquoted) for this call as this is
for -; *- checking input datasets in addition to providing information
-; *- about the macro.
-;
*- Note that ALL COLORS ARE LIMITED TO 8 CHARACTERS except
for cback. -; *- Refer to the web site for how to specify any color in
short form. -;
*- Do not change any of these variable names or their characteristics
-; *- or RGPP will fail due to errors.
-; length cstripe cscale $ 8 fitemtext fitemdesc
fblockdesc fpatient cback $ 32 citemdesc citemdesctrunc
cblockdesc cpatient citemtext cfigure $ 8 cblockbox $ 8 cblockdescbg cpatientbg
$ 8 hblockdescbg wblockdescbg
hpatientbg wpatientbg 8 hitemdesc hblockdesc
hpatient hitemtext hfigure hscaletext 8 drawblockbox uniformscale
usearrows stripeonfirst 8 ypixels xpixels
vpos hpos 8 hposdmin hposdmax
hposdmean hposminfigwidth hposmingap 8 maxucletters maxmcletters
8 ;
*- Note that ALL VARIABLES MUST BE SET to mon-missing values.
-; *- You are not allowed to default any values or omit any
variables. -; *- If any value is missing then RGPP will fail due to errors.
-;
*- Size of html output with number of rows and columns. -; *- You need a knowledge of sas graphics to set these.
-; ypixels=2400; vpos=120; /* number of rows */ xpixels=1100; hpos=55; /* number of columns */
*- Start and end hpos positions for date area. The maximum
-; *- value must not exceed what was specifed in hpos= above.
-; hposdmin=10; hposdmax=55; *- mean position calculated automatically -; hposdmean=(hposdmin+hposdmax)/2;
*- Colors of the stripes across the date area -; cstripe="beige"; *- Alternate lines within a block will be striped so that
it is -; *- easy for the eye to scan across without going up or down
a -; *- line. You specify here whether you want the lines striped
-; *- starting from the first line or not. If not then striping
is -; *- done on the second line. Your choice will depend on the
-; *- color of the block description background color because
it -; *- might be better to have the first line as a background
color -; *- to contrast with the block description background.
-; *- 0=no, 1=yes
-; stripeonfirst=1;
*- Backgound color. This can be up to 32 characters long.
-; *- All other colors are limited to 8 characters due to
-; *- annotate dataset restrictions.
-; cback="FloralWhite";
*- Font, color and height of text displayed on the left of
the date area -; *- (note that non-sas fonts need to be enclosed in an extra
set of single quotes) -; *- Note that hitemdesc must not be given a value greater
than 1.0 -; fitemdesc="'Arial'"; citemdesc="maroon"; hitemdesc=0.8;
*- Height, font and default color of the text to use when
text values -; *- are displayed in the date area such as vital signs values.
-; *- (note that non-sas fonts need to be enclosed in an extra
set of single quotes) -; *- Note that hitemtext must not be given a value greater
than 1.0 -; fitemtext="'Arial'"; hitemtext=0.7; citemtext="maroon";
*- Maximum upper case and mixed case letters that you know
will -; *- fit on the left of the date area. You will have to do
a trial -; *- run, inspect the outputs and adjust these values. -; *- (for pure upper case) -; maxucletters=23; *- (for mixed case) -; maxmcletters=30; *- Color to show this text when it gets truncated. You will
be -; *- able to mouse over this truncated text to see the full
text. -; citemdesctrunc="blue";
*- Font, color, height and background color of Patient top-of-page
title -; *- (note that non-sas fonts need to be enclosed in an extra
set of single quotes) -; fpatient="'Arial / Bold'"; cpatient="black"; hpatient=2.2; *- color, height and width of patient background -; cpatientbg="CXE0E0E0"; hpatientbg=2.4; wpatientbg=20;
*- Font, color, height and background color of block titles
-; *- (note that non-sas fonts need to be enclosed in an extra
set of single quotes) -; fblockdesc="'Arial / Bold'"; cblockdesc="black"; hblockdesc=1.05; *- color, height and width of block description background
-; cblockdescbg="CXE0E0E0"; hblockdescbg=1.5; wblockdescbg=43;
*- Whether to draw a box around each block of information
displayed -; *- and the color if so. 0=no 1=yes -; drawblockbox=1; cblockbox="maroon";
*- Height and color of the time scale to draw if this is
requested. -; *- Note that block box color (cblockbox) overrides the scale
color -; *- if drawblockbox=1. -; hscaletext=0.8; cscale="maroon";
*- Whether the time ticks on the scale should be uniformly
spaced. -; *- 0=no, 1=yes -; uniformscale=1;
*- Whether to use arrow heads to point to start or end day
values -; *- that have been imputed where their exact value is unknown.
-; *- This also applies to start or end values that fall off
the -; *- day scale at either end. 0=no, 1=yes.
-; usearrows=1;
*- Height and color of the figures. Height is effectively
the -; *- thickness of the arrow or rod shafts used for showing
period -; *- information such as the duration of an adverse event.
Note -; *- that if arrows are used then the value for hfigure must
not -; *- be greater than 0.5 -; hfigure=0.4; cfigure="BIYG";
*- This is the minimum width in hpos values that you want
for -; *- period data. Some adverse events might only last a day
and -; *- so a rod or an arrow used to represent it might be too
-; *- short to see. This setting will ensure that these short
-; *- periods are visible. The position on the day scale will
be -; *- the mid position of the start and end day. This will
be a -; *- box shape that will override an arrow shape. Set it to
a -; *- value that is slightly less than the hfigure value.
-; hposminfigwidth=0.3;
*- hposmingap is a control used when you are displaying text
-; *- values. If two text values are very close to each other
due -; *- to the dates being close then the two sets of text will
-; *- overlap and become unreadable. What the patient profiler
-; *- will do is to display a box for the second set of text
-; *- instead of the text if the values are too close. It is
up -; *- to you to decide how close you want to get before it
makes -; *- this substitution. This is given in hpos positions. Look
at -; *- the range of hpos values you used for the scale (hposdmin
-; *- and hposdmax) and decide what value, based on this, you
-; *- require to ensure displayed text values stay separate.
-; hposmingap=1.3;
run;
rgpp_global
This dataset has very few variables and only one observation. It
states what the patient variable name is, the destination folder for the
html pages and gif files that gets created and the scale to use.
data rgpp_global; *- do not change any of these variable names or their characteristics
-; length patvar $ 32 webout scale $ 200;
*- Name of the unique patient identifier variable present
-; *- in the rgpp_patients and rgpp_data datasets. -; patvar="subjid";
*- Destination folder for the html files and gif files -; *- created during a run of the patient profiler. Note
-; *- this destination folder must actually exist. For a
-; *- complete run of new reports you should ensure that
-; *- the destination folder is empty before you do the
-; *- full run. -; webout="C:\webtemp";
*- Set this to your scale you want to show on the time axis.
They should be pairs -; *- of study day numbers (first day of study being Day 0)
and labels separated -; *- with a #. Pairs of study days and labels should be separated
from others like -; *- themselves with a single upright line that sas normally
uses (in pairs) for -; *- concatenantion. An example is given below.
-; scale="-14#Screen | 0#Baseline | 7#WK1 | 14#WK2 | 28#WK4
| 56#WK8 | 112#WK16";
run;
rgpp_patients
This dataset has very few variables. One observation is required for
each patient you want to create a patient profile for. If a patient
is not listed in this dataset then no profile will be shown. Also, you
should ensure that data exists in the rgpp_data dataset for all the patients
you have listed in rgpp_patients. Note that you must give valid values
to these variables. Missing values are not allowed and will result in errors.
The code you see below is there to help you. It lists the variables
the patient profiler needs and describes them. You need your subject
variable as well, as described in the code. It is not the complete code.
You will need a "set" statement for whatever dataset of patients you have
got and you will maybe merge with a dataset (or two) of day values you
need. How you do this is entirely up to you. The important thing is that
the patient profiler gets the variables it needs with specific names and
characteristics.
data rgpp_patients; *- Do not change any of these variable names or their characteristics.
-; *- This list of variables does not include the subject variable
-; *- defined in rgpp_global and you should ensure that this
subject -; *- variable is also present on this dataset and added to
the "keep" -; *- list you will find below. -; length htmlfile $ 64 gifname $ 8 minscaleday mindataday
maxdataday maxscaleday 8 ;
*- Replace "your-subject-variable" with the subject variable
name -; *- you defined to rgpp_global. -; KEEP your-subject-variable htmlfile gifname minscaleday
mindataday maxscaleday maxdataday ;
*- "htmlfile" will be the name of the html file created.
Do not put -; *- the suffix ".html" at the end as the software does that
for you. -; *- You must ensure that this name is unique for each patient.
Its -; *- name should allow you to easily match a patient id to
the html -; *- file name. -;
*- "gifname" can only be eight characters long. You must
ensure that -; *- this name is unique for a patient. It must start with
a letter -; *- and not a number. It's name should allow you to
easily match a -; *- patient id to the gif name. -;
*- "minscaleday" is the lowest day to show on the scale for
this patient -;
*- "mindataday" is the lowest day for accepting data for
this patient. -; *- It must not be less than the minscaleday value. You would
normally -; *- set this slightly higher than the minscaleday value to
ensure that -; *- information you are displaying as text values does not
get written -; *- over the end of the scale.
*- "maxscaleday" is the highest day to show on the scale
for this patient -;
*- "maxdataday" is the highest day for accepting data for
this patient. -; *- It must not be more than the maxscaleday value. You would
normally -; *- set this slightly lower than the maxscaleday value to
ensure that -; *- information you are displaying as text values does not
get written -; *- over the end of the scale.
/*************** your set statement or merge statement go here plus whatever manipulations are required to populate the output variables
the patient profiler needs which are your subject variable you
defined to rgpp_global plus the variables in the keep list below.
All these variables must contain valid values. None of them should
contain missing values. ****************/
run;
rgpp_data
This dataset has many variables and multiple observations per patient.
There is the subject variable plus a set of "block" variables and a set
of "item" variables. There are two "day" variables as well - "day1" and
"day2". A "block" is a group of items you want to display together as a
block. An "item" is the thing you want to display within that block and
will
have characteristics like a height, a color, its day1 values (and a day2
value for period data). Day values are calculated as days from first dose.
You might display the value as text or it might be a box or, for period
data, it will be a rod or an arrow. Creating this dataset is quite a lot
of work but once you have done it for one study then you should be able
to adapt it for other studies. Typically, you would create separate datasets
for each block of information. Your datasets might be called something
like demog, dosing, vitals, labs, aes, conmeds and then right at the end
you bring all these datasets together and give the collection of this data
the name rgpp_data.
Once you get used to it, coding this dataset will become easy. The real
hard work will be in setting up the variable itemhtml. Each and
every item you display on the time scale (not "demog" type of data which
does not have a day associated with it) should have a text box that appears
when you mouse over it that states what the value is, what the parameter
or type of measure is, the units, the days since first dose and maybe many
other things. It is important to repeat whatever information is implicit
for its position on the day scale. Even if you were displaying the value
"98.4°F" as text then you would still need to have this value in your
box that appears when you mouse over it.
To help you code this dataset faster, you are allowed to have missing
values for things like "itemcolor" and "itemheight". In this case, the
patient profiler will use the defaults defined in the rgpp_style dataset.
%macro dclvars; *- Do not change any of these variable names or their characteristics.
-; *- This list of variables does not include the subject variable
-; *- defined in rgpp_global and you should ensure that this
subject -; *- variable is also present on this dataset and added to
the "keep" -; *- list you will find below. -;
*- Change "your-subject-variable"
in the below keep list -; *- to the subject variable you declared
in rgpp_global. -; KEEP your-subject-variable blockisdemog blockismsg
blockscale blockhtml itemhtml blockseq itemseq blockdesc itemdesc itemtext itemcolor itemheight day1 day2 day1_imp day2_imp ; %mend dclvars;
data rgpp_data;
%dclvars
*- Below is a "retain list" to help you. You will declare
all the -; *- variables you need in the above length statement. If
you do not -; *- refer to these variables in your code then you will get
an -; *- "uninitialized" note in the log so IF YOU ARE NOT CHANGING
these -; *- variables in your block of code then you should have
these -; *- delared in a "retain list" to make sure they get referred
to. -; *- But IF YOU ARE SETTING these variables in your code then
they -; *- SHOULD NOT also be in the "retain list". Some of these
variables -; *- can be set in the retain list and left. For example,
blockscale -; *- is for saying whether you want the day scale drawn for
a block. -; *- You can either leave it set to 1 (Yes) or 0 (no) and
not bother -; *- setting it in your code. Some of the variables declared
in the -; *- "length" statement are not included in the retain list
below -; *- because you will always be setting them in your code.
-;
*- "blockisdemog" is set to 1 if what is contained within
the block is -; *- demography-type information (like the text values of
age, sex, race -; *- and any other textual information such as end-of-study
status). -; *- This will alert the patient profiler that your text items
should be -; *- displayed at the start of the date area and that the
day1 value, -; *- even if non-missing, should be ignored. 0=no, 1=yes
-;
*- "blockismsg" is set to 1 if what is contained within the
block -; *- description is a message you want the patient profiler
to display -; *- where the block description would be placed. You would
typically -; *- use this to put out a message such as "No Adverse Events
were -; *- recorded for this Subject". 0=no, 1=yes -;
*- "blockscale" is set to 1 if you want to display the day
scale -; *- underneath the block. 0=no, 1=yes -;
*- For "blockhtml" refer to "itemhtml" for how to construct
this. -; *- if you set up blockhtml then it allows you to have a
pop-up box -; *- behind the text of the block description shown in the
middle of -; *- the data area. For SAS versions 8.2 and 9.1.3 there is
an -; *- alignment problem with the pop-up text as it will only
appear -; *- if you mouse over left of centre of the text. This bug
is -; *- supposed to be fixed in sas 9.2 -;
*- "itemhtml" should be set for each and every item you want
to -; *- show in the date area. If you are displaying text then
this -; *- same text should be in your pop-up box along with other
useful -; *- information. It is easy to make a coding mistake with
this -; *- variable. There is an example below that will help you
to code -; *- it. Be especially careful with the double and single
quotes. -; *- The "0D"x are new-line characters and they are Zero D
and not -; *- Oh D. Note that all your text and numeric values at the
end of -; *- each line should be kept short by using trim(left( ))
and each -; *- line, except the last one, should end with a pair of
"||" for -; *- concatenation to the following line.
-;
/******** itemhtml='ALT="Parameter: '||trim(itemdesc)|| "0D"x||'Value: '||trim(itemtext)|| "0D"x||'Visit: '||trim(left(put(visitcd,visit.)))|| "0D"x||'Days after first dose: '||trim(left(put(day1,6.)))|| "0D"x||'Date imputed (Y/N)?: '||put(day1_imp,ny.)|| '"'; ********/
*- "blockseq" is the block sequence number used for sorting
the -; *- order of the blocks and displaying them in that order.
-;
*- "itemseq" is the item sequence number used for sorting
the -; *- order of the items within the block and displaying them
in -; *- that order. You can have more than one observation within
a -; *- block with the same "itemseq" value, in which case it
will -; *- put all the items on the same line. You have to be careful
-; *- to set this value correctly if you are doing this.
-;
*- "blockdesc" is the block description that will get displayed
-; *- above the block in the middle of the date area.
-;
*- "itemdesc" is the item description that will get displayed
-; *- to the left of the date area. -;
*- "itemtext" is the text, such as the value of a vital signs
-; *- measure, that you want to display as text in the date
area. -; *- you should only do this for timepoint data and not period
-; *- data (i.e. it has a day1 value but a missing day2 value).
-;
*- "itemcolor", if blank, will default to the color defined
in -; *- the rgpp_style dataset. You can set this to indicate
the -; *- severity or intensity of something. With all colors,
you -; *- are limited to eight characters for the color name. Read
my -; *- web page on sas colors if you need to know more about
what -; *- colors you can use and how you can refer to any and all
-; *- colors by an eight letter name or less. -;
*- "itemheight", if left missing, will default to the height
-; *- defined in the rgpp_style dataset. You would typically
use -; *- this to make the display of "itemtext" smaller such as
when -; *- you were displaying wide text for lab values such as
-; *- "NEGATIVE" instead of narrow lab measures such as "12.4".
-;
*- "day1" is start day of event calculated as days since
first -; *- dose of study drug. Do not adjust this, as is customary
in -; *- the industry, by adding "1" to its value. It should be
-; *- strictly the event date minus date of first dose. If
event -; *- date is first dose date then day1=0. It is not day1=1.
-;
*- "day2" is end day of event calculated as days since first
-; *- dose of study drug. Do not adjust this, as is customary
in -; *- the industry, by adding "1" to its value. It should be
-; *- strictly the event date minus date of first dose. For
non- -; *- period data, such as lab value and vital signs, then
day2 -; *- should be set to missing. -;
*- "day1_imp" is the flag that tells the patient profiler
if -; *- you imputed the value for day1. You would set this if
you -; *- were not sure of the date because it was a partial date,
-; *- for example. For period data it will use an arrow head
to -; *- point backwards to this start day. This action can be
-; *- overriden in the rgpp_style dataset. 0=no, 1=yes
-;
*- "day2_imp" is the flag that tells the patient profiler
if -; *- you imputed the value for day2. You would set this if
you -; *- were not sure of the date because it was a partial date,
-; *- for example. For period data it will use an arrow head
to -; *- point forwards to this end day. This action can be
-; *- overriden in the rgpp_style dataset. 0=no, 1=yes
-;
Running the Patient Profiler
Remember that the patient profiler is expecting to find 4 datasets and
they must be named as described. You have to prepare these datasets carefully.
The patient profiler macro is named %rgpp but you should note that
it is a stored macro. It is a compiled macro that exists in catalogs. There
is no source code stored with it. The reason it is in compiled form is
because I don't want people to copy my code. Also I need to package all
the macros it needs together. I will warn you now that when you run the
code, it will write two very obvious header lines. I can update the software
to recognise your sas site number and to remove these two header lines
for a yearly licence fee, but so long as you are happy to use it with the
headers there, then I am happy for you to use the software for free.
When you use stored macros you have to set some system
options. This is explained in the official sas documentation. The key options
are MSTORED, which tells sas that you will be using stored macros,
and SASMSTORE=, which tells sas the catalog the stored macro(s)
reside in. If you already have a macro catalog then you can copy my macro
from its own catalog into your catalog.
When you are ready to run, you have to make sure the 4 datasets are
present and correct and that the output folder (that you defined in rgpp_global)
actually exists and is ready to receive the created html and gif files
and they you run the %rgpp macro like in the following very simplified
case.
libname _mstore "C:\my\macrostore";
options mstored sasmstore=_mstore;
data rgpp_style; set xxxxx.rgpp_style; run;
data rgpp_global; all your lines of sas code; run;
data rgpp_patients; all your lines of sas code; run;
data rgpp_data; all your lines of sas code; run;
%rgpp
libname _mstore clear;
Downloading RGPP
RGPP is what I will be calling it from now on as it is shorter. You can
download it here but remember, it is a compiled macro. It
is in a catalog. You can use "proc copy" to copy it into your existing
stored macro catalog or you can copy it to a folder of your choice.
On another page, I will give details on how to transform your clinical
data into a format that RGPP will accept. I will show you how to deal with
both horizontal and vertical data and set up the itemhtml entries
for these. That's a bit complicated. Before you do that you are encouraged
to play around the RGPP using the code below. It assumes you have set up
the stored macro catalog. It also assumes you have run the code that produced
rgpp_style
and written it to your sasuser library. It can be fun to play around with
RGPP and you will learn a lot about it that way.
*- Assign the macro store library and set options to use it -; libname _mstore "C:\mstored" access=readonly; options mstored sasmstore=_mstore;
*- Run the code on the web site to create rgpp_style in your sasuser
library -; *- and then when you need it just copy it like in the code below.
-; data rgpp_style; set sasuser.rgpp_style; run;
data rgpp_global; *- do not change any of these variable names or their characteristics
-; *- Webout should be a real location as the html and gif
files will be -; *- written to there. -; length patvar $ 32 webout scale $ 200; patvar="subjectid"; scale="-14#Screen | 0#Baseline | 7#WK1 | 14#WK2 | 28#WK4
| 56#WK8 | 112#WK16"; webout="C:\webtemp"; run;
data rgpp_patients; subjectid="1234-001-0001"; htmlfile="P1234-001-0001"; gifname="G0010001"; minscaleday=-20; mindataday=-15; maxdataday=115; maxscaleday=120; run;
I have a small confession to make. That is, RGPP isn't really a
graphical patient profiler. I know I called it that - it is just easier
to think of it in that way if you encounter it for the first time. RGPP
is really a graphics rendering macro that I designed especially
for handling the normal requirements of patient profiles. In the four datasets
it requires, what you are basically doing in those datasets is telling
it what to draw. It doesn't know it is patient data
you are giving it. It could be any data you wish, so long as what
RGPP can draw suits your needs. A tailor-made graphical patient profiler
will almost certainly put demography information just under the main header.
All the real ones I have seen do that. Mine does not.
The reason it does not is because I have kept it flexible so it can be
used for other purposes and is not just limited to showing
patient data - one patient per page. Once you break that mould
then an obvious and immediate extension to the idea of a patient profiler
is to have it report on a study such that the study
is the main title and theblocks are patients. For
example, the clinician might be interested in all the AEs of patients who
have had at least one serious adverse event. It is an easy matter to display
that on one page. I will give you some dummy code to do this so you can
see what the output looks like.
Please take time to play with RGPP. The more you play with it,
the more you will understand the way it works and the more uses you will
find for it. Remember my quote, "RGPP is really a graphics rendering
macro". After you have run the following code for yourself, I hope
you will be closer to realizing that. Two patient's AE data will be displayed
on the same page when you run the code below. I have been lazy and made
the patients AEs the same, but you can see what I mean, I hope!
*- Assign the macro store library and set options to use it -; libname _mstore "C:\mstored" access=readonly; options mstored sasmstore=_mstore;
*- Run the code on the web site to create rgpp_style in your
sasuser library -; *- and then when you need it just copy it like in the code
below. -; data rgpp_style; set sasuser.rgpp_style; run;
data rgpp_global; *- do not change any of these variable names or their
characteristics -; *- Webout should be a real location as the html and
gif files will be -; *- written to there. -; length patvar $ 32 webout scale $ 200; patvar="studyid"; scale="-14#Screen | 0#Baseline | 7#WK1 | 14#WK2 |
28#WK4 | 56#WK8 | 112#WK16"; webout="C:\webtemp"; run;
blockseq=1; blockismsg=1; blockisdemog=0; blockscale=0; blockdesc="All Adverse Events for Subjects experiencing
at least one Serious Adverse Event"; output;
If you can't run the code, you can link to the output it created when
I ran it here.
Transforming your data for RGPP
You have to transform your data for RGPP as already explained. This is
the hard bit. This is the dull and tedious bit. It takes a lot of careful
coding and will take a long time. I know this is going to be tedious. (it
was tedious for me to document it). But once done, it should be possible
to use your code changed or unchanged for other studies. It's a big hurdle
to get over but something you only have to do once. You can read the page
on how to transform your data below.
You have been introduced to Roland's Graphical Patient Profiler
and have learnt that it is really a graphics rendering macro especially
designed to handle patient profiler work. Its four driver datasets have
been explained and how to transform your data for RGPP has been explained.