What you will see on this page is a study reported all the way through from empty directories through dataset build, report code developed and tested through to reports produced in a final run. To keep it simple, there will only be two derived datasets and two tables produced. After this has been done, it will be demonstrated how to convert your reporting code into macros so that you can use Spectre as a "push-button" reporting system. Being a "push button" reporting system is the ultimate goal of Spectre. Once CDISC data standards have all been defined and tables and listings content and layouts have all been defined for these CDISC datasets then you will be able to have a set of macros to do all your reporting, called from the "titles members", and the ultimate goal of Spectre will have been achieved. There will be more explanation of this later.
Firstly, I will show you the directory structure I am going to use that I have set upon my PC.
Roland@DELL1 ~
$ cd /cygdrive/c/pharma Roland@DELL1 /cygdrive/c/pharma
xenuyama
Roland@DELL1 /cygdrive/c/pharma
|
If you look at the directory structure above you will see "formats" and "macros" directories existing at each level. When I assign macros to the sasautos path I want the macros at the lowest level earlier in the path than those at the higher levels. Last but one I want the Spectre macros and last of all the SASAUTOS that come with sas. The same applies to the formats in the sense that the lower level formats should be earlier in the fmtsearch= path.
Note the "progs" and "macros" directory under "24weeks". That is where
I will be doing most of my coding. I have set up a shortcut in my .bashrc
member (might be .bashrc_own for you) so that I can jump
to the 24weeks progs directly using "cd $xyprogs".
Here is the command in my .bashrc to set up this variable.
xyprogs=/cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs |
If you are not allowed to edit your .bashrc file and are not allowed to have a .bashrc_own file then it does not matter. You can always create your own command files in your home directory with all your shortcuts and other things you need and "source" it. You might have different command files for the different studies you are working on. How to "source" a command file is explained here.
Roland@DELL1 ~
$ cd /cygdrive/c/pharma Roland@DELL1 /cygdrive/c/pharma
Roland@DELL1 /cygdrive/c/pharma
|
So there it is! Empty directories apart from "silly_sas_program.sas". You will see Spectre at work from nothing through to final reports production.
*- Note that this is a WINDOWS autoexec member meant to be
-;
*- stored at a high level location such as the folder that contains -; *- the sas executable or the C: drive. You can have simpler autoexec -; *- members stored in the study programs folders but what they SHOULD -; *- ALWAYS DO is assign all needed macro directories in the correct -; *- order if you are initiating sas from the pharmaceutical area. You -; *- should NOT allocate any study datasets in this member. -; *- these options are always needed for Spectre (center optional)
-;
*- assign spectre macros to sasautos -;
%*- Allocate study reporting macros if in the reporting area -;
%*- Put an entry in the log so the user has a record -;
|
If I go to the 24weeks "progs" directory and start up sas interactively
then this is the final "note" statement from autoexec.sas in my
log window showing the sasautos path.
NOTE: sasautos=("C:\pharma\xenuyama\tokyo\DRUG001\DRUG001C3001\24weeks\macros"
"C:\pharma\xenuyama\tokyo\DRUG001\DRUG001C3001\macros" "C:\pharma\xenuyama\tokyo\DRUG001\macros" "C:\pharma\xenuyama\tokyo\macros" "C:\pharma\xenuyama\macros" "C:\spectre\macros" SASAUTOS) NOTE: AUTOEXEC processing completed. |
You will see my code members below but since I am starting from empty
directories so I am going to start by creating the local macro header for
%allocr
using the lmhdr script (short
for "local macro header"). If you look
in the script you will see it is pulling out details from the directory
path, namely the client, office, drug, protocol and increment. It has been
coded to match my directory structure. You will likely have to change it
to match yours. Watch me jump to the "progs" directory from my home directory,
navigate to the "macros" directory, set up the variable "prog" and export
it having set it to the program "allocr", generate the header and then
"cat" it to the terminal. Last I will copy it over as "allocw.sas"
and will edit any changes I need.
Roland@DELL1 ~
$ cd $xyprogs Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/macros
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/macros
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/macros
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/macros
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/macros
|
Next I add the code to each macro. The %allocw macro will be a copy of the code in the %allocr macro except the libraries will be allocated in write mode and it will have access to the "raw" directory in read mode. I didn't allocate the "raw" directory in %allocr because I don't want the possibility of a report being produced from raw data. This suits my standards but maybe not yours.
Time to code up these two macros. I will use Wordpad as my editor on
the Windows side to make changes and add the code. Here they are.
/*
/ Program : allocr.sas / Version : 1.0 / Author : Roland / Date : 03-Mar-2007 / SAS version : 9.1.3 / Client : xenuyama / Office : tokyo / Drug : DRUG001 / Protocol : DRUG001C3001 / Increment : 24weeks / Purpose : Allocate data libraries and formats in read mode / SubMacros : none / Notes : NOT A SPECTRE MACRO / Usage : %allocr / /=============================================================================== / PARAMETERS: /-------name------- -------------------------description------------------------ / /=============================================================================== / AMENDMENT HISTORY: / init --date-- mod-id ----------------------description------------------------ / /=============================================================================*/ %*- declare which libref to use for the "protocol" and "titles"
dataset -;
libname der "C:\pharma\xenuyama\tokyo\DRUG001\DRUG001C3001\24weeks\data\derived"
*- assign format libraries for increment, protocol, drug, office
and client -;
options fmtsearch=(iformats.formats pformats.formats dformats.formats
%put NOTE: fmtsearch=%sysfunc(getoption(fmtsearch)); |
/*
/ Program : allocr.sas / Version : 1.0 / Author : Roland / Date : 03-Mar-2007 / SAS version : 9.1.3 / Client : xenuyama / Office : tokyo / Drug : DRUG001 / Protocol : DRUG001C3001 / Increment : 24weeks / Purpose : Allocate data libraries and formats in read mode / SubMacros : none / Notes : NOT A SPECTRE MACRO / Usage : %allocw / /=============================================================================== / PARAMETERS: /-------name------- -------------------------description------------------------ / /=============================================================================== / AMENDMENT HISTORY: / init --date-- mod-id ----------------------description------------------------ / /=============================================================================*/ %*- declare which libref to use for the "protocol" and "titles"
dataset -;
libname raw "C:\pharma\xenuyama\tokyo\DRUG001\DRUG001C3001\24weeks\data\raw"
*- assign format libraries for increment, protocol, drug, office
and client -;
options fmtsearch=(iformats.formats pformats.formats dformats.formats
%put NOTE: fmtsearch=%sysfunc(getoption(fmtsearch)); |
I will run "find ." again from the "pharma" directory
to show you what now exists. You will see that these two macros are listed.
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/macros
$ cd /cygdrive/c/pharma Roland@DELL1 /cygdrive/c/pharma
Roland@DELL1 /cygdrive/c/pharma
|
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ showfmts Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
Next I edit using Wordpad to add the sas code.
/*
/ Program : mk_ifmts.sas / Author : Roland (Roland) / Date : 25-Feb-2007 / SAS version : 9.1.3 / Client : xenuyama / Office : tokyo / Drug : DRUG001 / Protocol : DRUG001C3001 / Increment : 24weeks / Purpose : Create the increment formats / Notes : /=============================================================================== / Modification History: / -user-id --date-- --mod-id--- ---------------------purpose-------------------- / /=============================================================================*/ %allocw proc format lib=iformats;
|
Now it is time to run the code. Spectre does all its important runs in batch and sas is invoked using the script sasb and you are expected to do all your code development in batch using this same script. The reason for this is that sasb identifies what it thinks might be wrong with your code and you are expected to check on its findings. It writes its findings to a file that has the extension ".chk". Note that "sasb" will recognise your exported variable "prog" so I don't have to supply a program name as a parameter to the sasb script.
I've already debugged the code so I know it will run without errors
or warnings. Watch me run the code and use "showfmts" again to see what
formats have been created.
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ sasb sas program "mk_ifmts" ended with return code 0: 0 ERROR(s) 0 WARNING(s) Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
The "showfmts" script has listed all the formats that are assigned by
the %allocr script in alphabetical order. To see an individual format,
use the showfmt script ("showfmts"
but without the "s" at the end). Note that for character formats that start
with a "$" the dollar sign must be "escaped" using a backslash. This is
because the Unix or Cygwin shell will think it is a variable that it is
required to resolve just like "$prog" so you have to stop it from resolving
in this way. I will display the "racecd" format and the "$country" format.
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ showfmt racecd 1 CAUCASIAN 2 BLACK 3 ASIAN 4 HISPANIC 5 OTHER Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
Time to do a "find ." to see what stage we have reached. Remember that
the ".chk" file was created by "sasb" with its findings from the sas log.
It will be empty in this case.
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ cd /cygdrive/c/pharma Roland@DELL1 /cygdrive/c/pharma
Roland@DELL1 /cygdrive/c/pharma
|
I am going to build a "demog" dataset and an "adv" dataset and place them in the "derived" folder. The "adv" datasets relies on the "demog" dataset so I will name the "demog" program as d01_demog and the adv program as d02_adv so they run in the correct order. I have no real data so this is generated test data. I borrowed some code from the "Creating Test Datasets" page that you can link to here.
First I will generate the headers.
Roland@DELL1 /cygdrive/c/pharma
$ cd $xyprogs Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
Now I add the sas code using Wordpad and here are the two code members..
/*
/ Program : d01_demog.sas / Author : Roland (Roland) / Date : 03-Mar-2007 / SAS version : 9.1.3 / Client : xenuyama / Office : tokyo / Drug : DRUG001 / Protocol : DRUG001C3001 / Increment : 24weeks / Purpose : Build the demog dataset / Notes : /=============================================================================== / Modification History: / -user-id --date-- --mod-id--- ---------------------purpose-------------------- / /=============================================================================*/ %allocw data der.demog;
|
/*
/ Program : d02_adv.sas / Author : Roland (Roland) / Date : 03-Mar-2007 / SAS version : 9.1.3 / Client : xenuyama / Office : tokyo / Drug : DRUG001 / Protocol : DRUG001C3001 / Increment : 24weeks / Purpose : Build the adv dataset / Notes : /=============================================================================== / Modification History: / -user-id --date-- --mod-id--- ---------------------purpose-------------------- / /=============================================================================*/ %allocw data adv;
|
Now I'll run the code.
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ echo $prog d01_demog Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
The programs ran without any problems. Time for another "find ." from
the pharma directory to see what we have now.
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ cd /cygdrive/c/pharma Roland@DELL1 /cygdrive/c/pharma
Roland@DELL1 /cygdrive/c/pharma
|
Roland@DELL1 /cygdrive/c/pharma
$ cd $xyprogs Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
Here is the "runderived" script it generated.
#!/bin/bash
# Script : runderived # Author : This script was automatically generated by the "makerun" script. # Date : 3-Mar-2007 at 07:03:06 # Client : xenuyama # Office : tokyo # Drug : DRUG001 # Protocol : DRUG001C3001 # Inc : 24weeks # Purpose : To run the programs that build the derived datasets # SubScripts : crtitlesds # Notes : If you edit this script to limit the number of datasets built # then note that there is a delete of all derived datasets in the # der. and stat. libraries near the start and all programs .log, .lst # and .chk members are deleted using the "rem" script. You should # comment out the "rem" lines that do not apply by putting a hash in # front of these commands as is the case with all the lines in this # header. It is recommended that for interim runs, you comment out the # lines that delete all the stats and der datasets. # # Note that this script was generated by the "makerun" script. # Next time "makerun" is run, it will overwrite this member. # # Note that to run this script you must use the command exactly # as shown in the usage notes below with the study programs # directory the current directory # # Usage: ./runderived 1>runderived.log 2>runderived.err # # Define error exit routine
# email the user telling them the job ended due to errors
# Use "ssmtp" for Cygwin and "mailx" for Unix
$msg
else
# say when the script ended
# identify user
# say who is running this script and what date and time
# Delete the "der" and "stat" derived datasets so long
# Re-create the titles and protocol datasets
# For all programs, delete the .log, .lst and .chk if they exist
# Run all programs using sasb and exit if a
# cat all the .chk files onto an empty runderived.chk
# email the user telling them the job has ended
# Use "ssmtp" for Cygwin and "mailx" for Unix
$msg
# say when the script ended
|
Now I am going to run "runderived" You will see the same error messages
as before due to the reporting components being missing. It will write
to both standard output and standard error so you will see two start and
finish messages.
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ ./runderived This script was started by Roland (Roland) on Sat Mar 3 07:07:46 WEST 2007 This script was started by Roland (Roland) on Sat Mar 3 07:07:46 WEST 2007 Error: File "protocol.txt", the protocol information file, is missing grep: *.titles: No such file or directory cat: [tlg]*.titles: No such file or directory sas program "d01_demog" ended with return code 0: 0 ERROR(s) 0 WARNING(s) sas program "d02_adv" ended with return code 0: 0 ERROR(s) 0 WARNING(s) This script finished at Sat Mar 3 07:07:56 WEST 2007 This script finished at Sat Mar 3 07:07:56 WEST 2007 Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
You will see that it found and ran "d01_demog" and "d02_adv" and did
it in the correct order. Normally the output from "runderived" is sent
to a "log" file and an "err" file but I wanted you to see all the messages
as they were coming out. I'll run it again the way it is supposed to be
run and "cat" the "log" and "err" file. You will see that all the useful
stuff is written to the "err" file.
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ ./runderived 1>runderived.log 2>runderived.err Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
To create the "protocol.txt" file a script needs to be run. You know
what -- I have forgotten the name of it! But that is not a problem.
All Spectre scripts and macros can be viewed in the terminal window. The
command I need to find this script is "showme scripts" where I will
be shown the complete list of scripts and their purposes. I type in the
command as you see below.
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ showme scripts |
And then my terminal window looks like the following and I can scroll
up and down and find the script I want.
Index of members in this directory with standard headers
======================================================== (this list was generated by the crindex script) a4lsps
- Calculate and display linesize and pagesize values for different
Usage: a4lsps -l 1.0 -r 1.0 -t 1.0 -b 1.0 a4ps
- For paged adhoc reports that are not part of the reporting
Usage: a4ps file.lst > file.ps
a4ps2pdf - To convert an A4 postscript file to a pdf
Usage: a4ps2pdf file.ps file.pdf
alltitles
- Production script to collect all .titles files together and put
Usage: alltitles antigrep - To list all files that DO NOT contain a specified string
Usage: antigrep 'FG_21_08' *.sas
badchars - Show bad characters (not clean 7 bit) in the input stream
Usage: badlines file.ext | badchars
baddrug
- To list which SAS programs do not have a correct drug name
Usage: baddrug
badinc
- To list which SAS programs do not have a correct increment
/cygdrive/c/spectre/scripts/@index.txt |
I'll scroll up and down until I find this script. Here it is in the
middle of the page.
Usage: contentsl adv contentsl adv acct contentsl # all datasets are listed contentsl_win - To list the contents
(in long form) of one or more SAS datasets
Usage: contentsl_win adv
crindex
- To create an index of macros or scripts with standard headers
Usage: crindex * > @index.txt
crindex_win - To create
an index of macros or scripts with standard headers
Usage: crindex_win * > @index.txt
crprottmpl - Production
script to create file "protocol.template" in the study
Usage: crprottmpl crtitlesds - Production
script to create der.titles dataset from individual
Usage: crtitlesds crtitlesds_win - Production script to create
der.titles dataset from individual
Usage: crtitlesds_win crtitlestmpl - Production script
to create file "titles.template" in the study
Usage: crtitlestmpl dashes - To list files that have spanning dashed lines in them
Usage: dashes *.lis
|
The script I need is named crprottmpl. It creates "protocol.template" which has to be copied across as "protocol.txt" and edited.
This display, where I can scroll up and down in my terminal window, has been created by an editor named "less". To get out of "less" and return to the terminal, press the "q" key.
Now I am back in the terminal window. I'll run the "crprottmpl"
script and move "procotol.template" to "protocol.txt".
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ crprottmpl Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
This is the "protocol.txt" file I have to edit. I've reduced
the text size so it hopefully won't wrap in your browser.
#===========================================================================================================================================
# Template for Make a copy of this in the programs directory and call it "protocol.txt". # protocol.txt This file contains the list of protocol details that will be written to protocol dataset. # # # This member was generated by the script "crprottmpl" for: # # CLIENT: xenuyama # OFFICE: tokyo # DRUG: DRUG001 # STUDY: DRUG001C3001 # INC: 24weeks # # DATE: 03-Mar-2007 # #===================== THE LINES BELOW THAT START WITH A # ARE A GUIDE TO TELL YOU HOW TO FILL IN THE INFORMATION ========================== # # drugname: FKXYZ (XXXXX) (this information will appear in the headers) # # protocol: Protocol No. XY-XXX-YY-ZZ (this information will appear in the headers) # # report: Report No. XYZZ-XXX-YY, Draft version, (this information will appear in the headers) # # titlestyle: xy Set this to the prefix of the client titles macro # # dflayout: p10 Default layout to use when no layout is specified in the titles member. This must be one of the allowed # layouts as listed in "titles.template". # # dfllayout: l10 Default landscape layout when only "l" is specified as the layout in the titles member. # # dfplayout: p10 Default portrait layout when only "p" is specified as the layout in the titles member. # # dfltlayout: lt10 Default landscape tight (i.e. lines are closer together) layout when only "lt" is specified as the layout in the titles member. # # dfptlayout: pt10 Default portrait tight (i.e. lines are closer together) layout when only "pt" is specified as the layout in the titles member. # # paper: A4 Must be either "A4" or "Letter" # # margin: 1.0 All-round page margin in inches # # lmargin: Left margin in inches if different from all-round margin value assigned to margin: (left in sense of portrait orientation). # Leave this blank if there is the same all-round margin. # # rmargin: Right margin in inches if different from all-round margin value assigned to margin: (right in sense of portrait orientation). # Leave this blank if there is the same all-round margin. # # tmargin: Top margin in inches if different from all-round margin value assigned to margin: (top in sense of portrait orientation). # Leave this blank if there is the same all-round margin. # # bmargin: Bottom margin in inches if different from all-round margin value assigned to margin: (bottom in sense of portrait orientation). # Leave this blank if there is the same all-round margin. # # clean: clean in (0,1) Selection criteria for selecting clean/unclean patients from the acct dataset. # # pop1: FAS First set of analysis set abbreviation and its label. What the programmer puts in their .titles file # poplabel1: Full Analysis Set for the analysis set will be checked against the list you put in this member. # # pop2: Second set of analysis set abbreviation and its label. # poplabel2: There are a maximum of 9 sets allowed. # #============================================================================================================================================ drugname: XYZ (XXXXX)
|
This is the information part of the file after making the changes. I
will allow most of them to default.
drugname: DRUG001
protocol: Protocol No. XY-XXX-YY-ZZ report: Report No. XYZZ-XXX-YY, Draft version, titlestyle: xy dflayout: p10 dfllayout: l10 dfplayout: p10 dfltlayout: lt10 dfptlayout: pt10 paper: A4 margin: 1.0 lmargin: rmargin: tmargin: bmargin: clean: pop1: FAS poplabel1: Full Analysis Set pop2: PPS poplabel2: Per-Protocol Set pop3: ITT poplabel3: Intent to Treat pop4: poplabel4: pop5: poplabel5: pop6: poplabel6: pop7: poplabel7: pop8: poplabel8: pop9: poplabel9: |
Once this file has been set up it has to be activated. This is
done with the same script that activates report program titles members,
as will be explained later. This script is named crtitlesds
(create titles dataset). I will run it now. Again, it will complain that
there are no "titles" members.
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ crtitlesds grep: *.titles: No such file or directory cat: [tlg]*.titles: No such file or directory Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
The way this protocol file has been activated is to create a sas dataset
named "protocol" in the derived dataset folder. To see the contents
of this dataset then use the showprot
script. This will create an output that looks like the "protocol.txt"
file but in reality it has read the "der.protocol" dataset and is
just displaying it in the same style as the "protocol.txt" file.
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ showprot Drugname: DRUG001
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
It is time for another "find ." from the pharma directory. Look out
for the "protocol" dataset. There will be a "titles" dataset as well but
with nothing in it.
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ cd /cygdrive/c/pharma Roland@DELL1 /cygdrive/c/pharma
Roland@DELL1 /cygdrive/c/pharma
|
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ prog=t_demog Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
This is what the titles file looks like. There are a lot of instructions
at the start to help you fill it out. You do not have to keep this header
information. I have made the text smaller so it hopefully does not wrap
in your browser.
#===========================================================================================================================================
# Template for titles. Make a copy of this to go with your sas program and give it the file extension .titles such as t_meds.titles # You must only have ONE set of titles in this file. # # This member was generated by the script "crtitlestmpl" for: # # CLIENT: xenuyama # OFFICE: tokyo # DRUG: DRUG001 # STUDY: DRUG001C3001 # INC: 24weeks # # DATE: 03-Mar-2007 # #===================== THE LINES BELOW THAT START WITH A # ARE A GUIDE TO TELL YOU HOW TO FILL IN THE INFORMATION ========================== # # program: progname (put your program name here without the .sas extension. Case should match your program member name) # # layout: Leave blank to use study default or set it to l/p (landscape/portrait) [t] (tight lines) f (font size) # Here is a list of valid possible values: l8 l8.5 l9 l10 lt8 lt8.5 lt9 lt10 p8 pc8 p9 pt9 p10 pt10 p11 pt11 # The preference is for p10 (portrait 10 point). If your report will not fit on the page then try l10 (landscape 10 point) # but if it still will not fit then try l9 and if it still will not fit then try l8. You should not go lower than an 8 point # font without asking for permission to do so. # # population: FAS, PPS, SEL etc. abbreviations. This must match one of the analysis set abbreviations in "protocol.txt". # # sascode: If you set this to anything, the sas program will be generated and any corresponding program you have will be overwritten. # # titles below: Put your titles BELOW this line. All titles will be CENTRED unless you start with a space in which case LEFT-ALIGNED. # Table 1.2.3 # ANOTHER TITLE LINE # A LEFT-ALIGNED TITLE - THE FIRST SPACE WILL BE DROPPED WHEN IT IS LEFT-ALIGNED BUT EXTRA SPACES WILL BE SHOWN # footnotes below: Put your footnotes BELOW this line. All footnotes will be LEFT-ALIGNED. Leading spaces are allowed. # First footnote # Second footnote # Third footnote indented two spaces # # endxxx: This line ends the titles entry. Do not specify anything after it. #=========================================================================================================================================== program: t_demog layout: population: sascode: #################### Columns ruler for titles and footnotes -- do not exceed the maximum column for your layout ############################ #--------1---------2---------3---------4---------5---------6---------7---------8---------9---------0---------1---------2---------3---------4 titles below: footnotes below: endxxx: #--------1---------2---------3---------4---------5---------6---------7---------8---------9---------0---------1---------2---------3---------4 |
I am going to choose a portrait 10 point font layout for the FAS (Full
Analysis Set) population and give it a title of "TABLE 1". I'll strip out
the comment lines so you can see it more clearly in larger text. Note that
I have given it a footnote of "&_longline_". This is a spanning line
of underscores that gets set up by Spectre.
program: t_demog
layout: P10 population: FAS sascode: titles below: TABLE 1 DEMOGRAPHY footnotes below: &_longline_ endxxx: |
The titles member has to be activated using the crtitlesds
script. After it is activated, I can check it is there using the showtitles
script. Note the warning about the program not being there yet.
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ crtitlesds Warning: (crtitlesds) Titles entries exist for the following program(s) but no program yet exists t_demog.sas Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Program: t_demog
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
I'll create the titles member for t_adv.sas at this point as
I want to finish with the titles in this section and get on with the report
code. I'll give t_adv a landscape 10 point font layout and table
number 2. First I'll create the template.
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ prog=t_adv Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
Next I'll edit it to give this, removing all the header instructions.
program: t_adv
layout: L10 population: FAS sascode: titles below: TABLE 2 ADVERSE EVENTS footnotes below: &_longline_ endxxx: |
Now I'll activate it.
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ crtitlesds Warning: (crtitlesds) Titles entries exist for the following program(s) but no program yet exists t_adv.sas t_demog.sas Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ prog=t_demog Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
Now I'll add the code. I am making the call to %unistats the simplest
one possible for this demonstration. See the page about %unistats to learn
more about improving the layout here.
/*
/ Program : t_demog.sas / Author : Roland (Roland) / Date : 03-Mar-2007 / SAS version : 9.1.3 / Client : xenuyama / Office : tokyo / Drug : DRUG001 / Protocol : DRUG001C3001 / Increment : 24weeks / Purpose : Table of demography / Notes : /=============================================================================== / Modification History: / -user-id --date-- --mod-id--- ---------------------purpose-------------------- / /=============================================================================*/ %allocr %titles proc sort data=der.demog(where=(&_pop_.cd=1))
%popfmt(demog,trtcd,uniqueid=patno invid) %openrep %unistats(dsin=demog,
%closerep
|
Now I'll run the code...
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ sasb sas program "t_demog" ended with return code 0: 0 ERROR(s) 0 WARNING(s) Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
Spectre sends the reporting program output to ".lis" files
when you are between the %openrep and %closerep macros and not the ".lst"
files that you are used to. This is so it can add page numbers to the listings.
This leaves you free to use ".lst" output for diagnostics. Here
is the contents of t_demog.lis
DRUG001
Page 1 of 1
Protocol No. XY-XXX-YY-ZZ Report No. XYZZ-XXX-YY, Draft version, March 3, 2007 TABLE 1
DEMOGRAPHY
___________________________________________________________________________ Number of Patients (%) / Descriptive Stat
Ambicor (1g/day) Betamaxin (500mg/day)
GENDER CODE
RACE CODE
AGE (YEARS)
WEIGHT (KG)
HEIGHT (CM)
___________________________________________________________________________ |
Next I'll create the header for t_adv.
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ prog=t_adv Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
Now I add the code. I am making the call to %npcttab the simplest one
possible for this demonstration. See the page about %npcttab to learn more
about improving the layout here.
/*
/ Program : t_adv.sas / Author : Roland (Roland) / Date : 03-Mar-2007 / SAS version : 9.1.3 / Client : xenuyama / Office : tokyo / Drug : DRUG001 / Protocol : DRUG001C3001 / Increment : 24weeks / Purpose : Table of adverse events / Notes : /=============================================================================== / Modification History: / -user-id --date-- --mod-id--- ---------------------purpose-------------------- / /=============================================================================*/ %allocr %titles proc sort data=der.demog(where=(&_pop_.cd=1)) out=demog(drop=&_pop_.cd);
%popfmt(demog,trtcd,uniqueid=patno invid) proc sort data=der.adv out=adv;
data adv;
%openrep %npcttab(dsin=adv,midlvl=amsoc,lowlvl=ampt) %closerep
|
Now I'll run the code.
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ sasb sas program "t_adv" ended with return code 0: 0 ERROR(s) 0 WARNING(s) Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
Here is the contents of t_adv.lis
DRUG001
Page 1 of 2
Protocol No. XY-XXX-YY-ZZ Report No. XYZZ-XXX-YY, Draft version, March 3, 2007 TABLE 2
ADVERSE EVENTS
____________________________________________________________________________________________________________________
Ambicor (1g/day) Betamaxin (500mg/day)
Total
Gastrointestinal disorders
Respiratory, thoracic and mediastinal disorders
Psychiatric disorders
Musculoskeletal and connective tissue disorders
Vascular disorders ____________________________________________________________________________________________________________________
TABLE 2
ADVERSE EVENTS
____________________________________________________________________________________________________________________
Ambicor (1g/day) Betamaxin (500mg/day)
Total
ANY AE
4 ( 44.4)
6 ( 75.0) 10 ( 58.8)
General disorders and administration site conditions
Nervous system disorders
____________________________________________________________________________________________________________________ |
Time for another "find ." from the pharma directory.
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ cd /cygdrive/c/pharma Roland@DELL1 /cygdrive/c/pharma
|
Roland@DELL1 /cygdrive/c/pharma
$ cd $xyprogs Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
This is the contents of runreports that was generated.
#!/bin/bash
# Script : runreports # Author : This script was automatically generated by the "makerun" script. # Date : 3-Mar-2007 at 07:57:06 # Client : xenuyama # Office : tokyo # Drug : DRUG001 # Protocol : DRUG001C3001 # Inc : 24weeks # Purpose : To run the programs that create reports # SubScripts : crtitlesds donepages # Notes : If you edit this script to limit the number of reports produced # then note that there is a delete of all programs .log, .lst, .chk # and .lis members using "rm". You should comment out the "rm" # lines that do not apply by putting a hash in front of these # commands as is the case with all the lines in this header. # # Note that this script was generated by the "makerun" script. # Next time "makerun" is run, it will overwrite this member. # # Note that to run this script you must use the command exactly # as shown in the usage notes below with the study programs # directory the current directory. # # Usage: ./runreports 1>runreports.log 2>runreports.err # # identify user
# say who is running this script and what date and time
# Create the titles and protocol datasets
# Set up an environment variable for routing the output
# convert to a Windows path style for Cygwin
export OUTDIR OUTDIRWIN
# Delete the "donelist" files
# For all programs, delete the .log, .lst, .chk and .lis* if they
exist
# Run all programs using sasb
# cat all the .chk files onto an empty runreports.chk
# add number of pages and sort "donelist" into order
# email the user telling them the job has ended
# Use "ssmtp" for Cygwin and "mailx" for Unix
$msg
# say when the script ended
|
If you look at the "runreports" script you will see it deletes
two files named "donelist.txt" and "donelist.tmp". These
files do not appear in the "find ." above. This is because they are only
created when "runreports" runs and not when individual users run
their reporting code. What it is doing is writing a record of what reporting
programs ran. At the end it will add the number of pages in each output
and sorts it into order as the final "donelist.txt". This file can
then be used to gather outputs in the correct order and can form the basis
for creating PDF files. We are not going to go into creating PDFs on this
page, though. Next I will run "runreports".
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ ./runreports This script was started by Roland (Roland) on Sat Mar 3 08:00:04 WEST 2007 This script was started by Roland (Roland) on Sat Mar 3 08:00:04 WEST 2007 sas program "t_adv" ended with return code 0: 0 ERROR(s) 0 WARNING(s) sas program "t_demog" ended with return code 0: 0 ERROR(s) 0 WARNING(s) This script finished at Sat Mar 3 08:00:21 WEST 2007 This script finished at Sat Mar 3 08:00:21 WEST 2007 Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
Here is a "find ." done from the pharma directory again. Note the "donelist"
files that have appeared.
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ cd /cygdrive/c/pharma Roland@DELL1 /cygdrive/c/pharma
Roland@DELL1 /cygdrive/c/pharma
|
These are the contents of the donelist files. Note that donelist.txt
is a sorted version of donelist.tmp and with total pages added.
Roland@DELL1 /cygdrive/c/pharma
$ cd - /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
As I promised, I have guided you through from empty directories to producing final reports, step by step. That is now done. What you see is what ran on my PC using Cygwin.
Now comes the change to the titles members to call these macros from
the "sascode" line. t_demog.titles now looks like this.
program: t_demog
layout: P10 population: FAS sascode: %t_demog titles below: TABLE 1 DEMOGRAPHY footnotes below: &_longline_ endxxx: |
t_adv.titles now looks like this.
program: t_adv
layout: L10 population: FAS sascode: %t_adv titles below: TABLE 2 ADVERSE EVENTS footnotes below: &_longline_ endxxx: |
I want you to consider that these two very simple titles definitions could have come out of a spreadsheet somewhere and been exported to the programs directory. Once this method is used, then in a sense, report coding is no more. True, somebody has to write the reporting macros, but when the CDISC standards have all been clarified and report layouts clarified then there could be a repository of reporting macros for you to use. If this happens then you won't need programmers to write the reporting macros any more. When that happens, Spectre will have become a push-button reporting system.
Now I have changed the titles, I will rerun the "crtitlesds"
script. There will still be a t_adv.sas and a t_demog.sas
after "crtitlesds" has run but look at them now! They have been
overwritten and now contain the sas code that was defined to the titles
member in the "sascode" line.
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ crtitlesds Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
%t_adv Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
%t_demog Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
What I will do now is delete all the t_* files that are not titles members
so that only the titles members remain.
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ ls t_* t_adv.chk t_adv.lis t_adv.log t_adv.sas t_adv.titles t_demog.chk t_demog.lis t_demog.log t_demog.sas t_demog.titles Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
Can you see that all that is left are the two "titles" members? Imagine
they were exported there from a statistician's spreadsheet. Now I will
run "makerun". No problems there, as you can see.
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ makerun Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
Now I will run "runreports". Everything worked as it did before.
The
".lis" outputs are there and the same as before!
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
$ ./runreports This script was started by Roland (Roland) on Sat Mar 3 08:10:36 WEST 2007 This script was started by Roland (Roland) on Sat Mar 3 08:10:37 WEST 2007 sas program "t_adv" ended with return code 0: 0 ERROR(s) 0 WARNING(s) sas program "t_demog" ended with return code 0: 0 ERROR(s) 0 WARNING(s) This script finished at Sat Mar 3 08:10:52 WEST 2007 This script finished at Sat Mar 3 08:10:52 WEST 2007 Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
Roland@DELL1 /cygdrive/c/pharma/xenuyama/tokyo/DRUG001/DRUG001C3001/24weeks/progs
|
So there you see Spectre working as a "push button" reporting system. It may take a while for this concept to "sink in" but I hope you will eventually realize that Spectre can, indeed, become a "push button" reporting system.
Use the "Back" button of your browser to return to the previous page
SAS and all other SAS Institute Inc. product or service names are registered
trademarks or trademarks of SAS Institute Inc. in the USA and other countries.
® indicates USA registration.