Chapter 4: Implementing CDISC SDTM with the SAS Clinical Standards Toolkit and Base SAS

SAS Clinical Standards Toolkit Background

Clinical Standards Setup for Study XYZ123

Building SDTM Datasets

Base SAS Macros and Tools for SDTM Conversions

Building the Special-Purpose DM and SUPPDM Domains

Building Define.xml

Chapter Summary

In Chapter 3, you saw how to create CDISC SDTM data just using Base SAS and metadata stored in Microsoft Excel files. In this chapter, you will explore another approach where you replace Microsoft Excel with the SAS Clinical Standards Toolkit as a metadata repository. You will first migrate the SDTM metadata from Excel into SAS Clinical Standards Toolkit 1.6. The metadata in the SAS Clinical Standards Toolkit and some SAS macros provided as part of that tool will be used to build the SDTM datasets. Finally, the SAS Clinical Standards Toolkit will be used to build define.xml.

More Information

Appendix A - Source Data Programs

SAS Clinical Standards Toolkit 1.6: User’s Guide

SAS Clinical Standards Toolkit Background

SAS created the SAS Clinical Standards Toolkit in response to the pharmaceutical industry’s need for a way to store and leverage clinical study metadata. The SAS Clinical Standards Toolkit is, at its core, a set of SAS datasets representing metadata, some text configuration files, and a set of SAS macros that work with those datasets and configuration files. A very nice plus to the SAS Clinical Standards Toolkit is the price. It is available to those with a Base SAS license (SAS 9.2 and later, and SAS 9.1.3 via a hot fix) by making a special request of your SAS sales representative. Another nice plus is that if you already understand Base SAS and the SAS macro language, then you have the basic technical understanding for how the SAS Clinical Standards Toolkit works.

The examples in this chapter are built in SAS Clinical Standards Toolkit 1.6. We expect that this toolset will evolve over time and as the CDISC models also evolve. You can find the documentation for the toolkit and for what was done in this chapter in the SAS Clinical Standards Toolkit 1.6: User’s Guide.

Clinical Standards Setup for Study XYZ123

In this section, you will see how to define the SDTM data for clinical study XYZ123 in the SAS Clinical Standards Toolkit. It is assumed that you have the SAS Clinical Standards Toolkit installed, and that you know where your CST global standards library resides. For the examples below, the CST global standards library is found at C:cstGlobalLibrary, but your installation directory might differ. If you have installed the CST to a different location, you need to replace this specified path below with your installation path.

Copy SDTM 3.2 Standard to XYZ123

A common use case for many people is to define an SDTM standard based on the CDISC SDTM. That is what we want to do here. So copy the SDTM 3.2 CST-provided metadata over to a new study-specific XYZ123 area. For this example, copy the entire contents of C:cstGlobalLibrarystandardscdisc-sdtm-3.2-1.6 over to C:cstGlobalLibrarystandardsXYZ_program_cdisc-sdtm-3.2-1.6.

Edit Study XYZ123 Metadata

To customize the SDTM XYZ123 metadata and make it differ from the generic CST-supplied CDISC SDTM 3.2 metadata, you need to edit some metadata datasets. For this example, all edits to SAS datasets were done by editing the datasets directly within SAS.

First, you need to update the domain-level metadata, which can be found in C:cstGlobalLibrarystandardsXYZ_program_cdisc-sdtm-3.2-1.6metadata eference_tables.sas7bdat. Because SUPPDM and the XYZ123 custom domain called XP are added to the 3.2 standard, you have to add two rows to the reference_tables dataset to look like this:

image

The standardversion column for all other rows/domains is also changed to “XYZ-SDTM-3.2” to point at the newly revised standard. Also note that the comment column here is blank. The CST is shipped with this column populated with the CDISC Notes column from the SDTM standard. But those note entries can cause the CST to crash due to special formatting characters loaded from the Microsoft Excel CDISC metadata file. So it is advisable that you delete that text or replace it with text that makes sense for your organization.

Now that the study and domain-level information has been defined, you need to edit the domain variable-level metadata. That dataset can be found at C:cstGlobalLibrarystandardsXYZ_program_cdisc-sdtm-3.2-1.6metadata eference_columns.sas7bdat. Here again, you need to add the data for the new XP and SUPPDM domains. The standardversion, order, length, displayformat, xmlcodelist, origin, term, and algorithm columns were edited as needed. Several of the domains were edited to remove SDTM variables that were optional. The other domains not used specifically in the conversion were left as they were. Lengths on studyid, domain, and usubjid were updated for consistency across domains, even though a majority of the domains are not used in this exercise.

Note that editing the reference_columns dataset can be quite time-consuming. This is the step where you have to enter the majority of your standard metadata. CDISC does not specify standard lengths of variables for the SDTM, so you need to make that effort here in the length variable. Order needs to be set so that you have the variables appear in your dataset in the proper order. The codelist needs to be set to point to the proper controlled terminology. Origin is set to tell the reviewer where the variable can be found on the CRF. The algorithm column defines your computational method if you have one. Here is a snapshot of the edits made to the DM rows of the reference_columns dataset:

image

Edit the XYZ123 SAS Clinical Standards Toolkit Control Files

Now that the XYZ123 metadata has been customized in the SAS Clinical Standards Toolkit to meet your needs, you need to make some edits to a few control files so that you can register the XYZ123 standard into the toolkit. First, you need to copy the initialization files initialize.properties and validation.properties from the base SDTM standard at C:cstGlobalLibrarystandardscdisc-sdtm-3.2-1.6programs to the XYZ custom standard at C:cstGlobalLibrarystandardsXYZ_program_cdisc-sdtm-3.2-1.6programs.

The first control metadata dataset to be edited is the standards dataset that holds the study-level metadata found at C:cstGlobalLibrarystandardsXYZ_program_cdisc-sdtm-3.2-1.6controlstandards.sas7bdat. The standardversion, mnemonic, comment, and rootpath variables were edited to look like this:

image

Next, you need to edit the standardsasreferences control dataset for the registration program to run. The standardsasreferences dataset is a controlling metadata dataset that tells the SAS Clinical Standards Toolkit where it can find the objects that it needs for the various tasks that it performs. The standardsasreferences dataset for standard XYZ123 can be found at C:cstGlobalLibrarystandardsXYZ_program_cdisc-sdtm-3.2-1.6controlstandardsasreferences.sas7bdat. Change the standard variable to XYZ std CDISC-SDTM. The resulting standardsasreferences dataset for this job looks like this:

image

You also need to edit the standardelookup control dataset for the registration program to run. The standardlookup dataset for standard XYZ123 can be found at C:cstGlobalLibrarystandardsXYZ_program_cdisc-sdtm-3.2-1.6controlstandardlookup.sas7bdat. Primarily the standard and standardversion columns need to be modified to point to the XYZ123 standard. A few rows of this dataset look like this:

image

It is critical to get these control datasets right in order to have your SAS Clinical Standards Toolkit jobs run properly. The SAS Clinical Standards Toolkit: User’s Guide has much more detail on the content of these datasets, and you should refer there for extensive details.

Register the XYZ123 Standard

You now need to run a program to register the XYZ123 SDTM standard into the SAS Clinical Standards Toolkit. Copy the registerstandard.sas program from the base SDTM 3.2 area C:cstGlobalLibrarystandardscdisc-sdtm-3.2-1.6programs over to the XYZ123 standard area at C:cstGlobalLibrarystandardsXYZ_program_cdisc-sdtm-3.2-1.6programs. You can use that program as a basis for your registration program. In this example, the start of the final registration program registerstandard.sas looks like this:

* Register the XYZ program standard to the global library;

* Register the standard to the global library;

 

* Set up macro variables needed by this program;            

%let _thisStandard=CDISC-SDTM;

%let _thisStandardVersion=XYZ-SDTM-3.2;

%let _thisProductRevision=1.6;

%let _thisDirWithinStandards=XYZ_program_cdisc-sdtm-3.2-1.6;

 

%cstutil_setcstgroot;                                        

 

* Set the framework properties used for the uninstall;       

 

%cst_setStandardProperties(

  _cstStandard=CST-FRAMEWORK,

  _cstSubType=initialize

  );

When the registerstandard.sas program is run, the XYZ123 standard becomes available for use by the SAS Clinical Standards Toolkit.

   You need to define these four macro variables. Beyond this, the code is standard CST program code.

   This step sets the &_cstgroot macro variable used by the code below it.

   This step initializes the toolkit environment.

   From this point, the program calls the %cst_registerStandard toolkit SAS macro that puts all of the XYZ123 standard metadata into the toolkit.

Now that the XYZ123 standard has been defined, this custom SDTM standard is available for use in Base SAS in order to convert the source data to SDTM datasets. In Chapter 3, you used Excel to store your study metadata, but here you will use the metadata in SAS Clinical Standards Toolkit. Also, the work that you have done here will be leveraged in Chapter 5 when you use this custom XYZ123 SDTM standard defined in the SAS Clinical Standards Toolkit to create SDTM domains in SAS Clinical Data Integration.

Building SDTM Datasets

Now that you have your metadata stored in the SAS Clinical Standards Toolkit, you can build the SDTM domains in Base SAS. In this part of the chapter, we look at changing how you wrote SDTM conversion programs in Chapter 3 so that they can leverage the metadata in the SAS Clinical Standards Toolkit. Except for a few changes, the Base SAS programming is almost entirely the same, so we will dissect only the programming in Chapter 3 that creates the DM/SUPPDM domain.

Base SAS Macros and Tools for SDTM Conversions

In Chapter 3, we introduced the --DTC SDTM date creation macro %make_dtc_date, the --DY SDTM study day macro %make_sdtm_dy, and the codelist format catalog file. For the SAS Clinical Standards Toolkit implementation, you can use those macros and that format catalog exactly as they appeared in Chapter 3. However, you use replacements enabled by the SAS Clinical Standards Toolkit for the %make_empty_dataset macro and the domain-sorting macro %make_sort_order.

Empty Dataset Creator via the SAS Clinical Standards Toolkit

The SAS Clinical Standards Toolkit comes with a SAS macro that creates an empty dataset for you. This dataset is called %cst_createTablesForDataStandard. To create zero record versions of the SDTM datasets defined in the XYZ123 standard, you would run SAS code that looks like this:

* initialize the toolkit framework;

%cst_setStandardProperties(

  _cstStandard=CST-FRAMEWORK,

  _cstSubType=initialize);

 

* define _ctsGroot macro variable;  

%cstutil_setcstgroot;

%cst_createTablesForDataStandard(

   _cstStandard=CDISC-SDTM,

   _cstStandardVersion=XYZ-SDTM-3.2,

   _cstOutputLibrary=work);        

   This step initializes the toolkit environment.

   This step sets the &_cstgroot macro variable used in step 3.

   This step calls the %cst_createTablesForDataStandard macro, creates an empty SAS dataset for every domain dataset found in the XYZ123 standard, and stores those datasets in the SAS WORK library.

Domain Sorter via the SAS Clinical Standards Toolkit

In Chapter 3, there is a SAS macro that sorts the data based on the metadata found in Excel. Here, we modify that macro to sort the data based on the SAS Clinical Standards Toolkit XYZ123 metadata.

*--------------------------------------------------------------*;

* make_sort_order.sas creates a global macro variable called

* **SORTSTRING where ** is the name of the dataset that contains

* the metadata specified sort order for a given dataset.

*

* MACRO PARAMETERS:

* dataset = the dataset or domain name

*--------------------------------------------------------------*;

%macro make_sort_order(dataset=);

  ** create **SORTSTRING macro variable;

  %global &dataset.SORTSTRING;

  data _null_;

    set " C:cstGlobalLibrarystandardsXYZ_program_cdisc-sdtm-3.2-

            1.6metadata eference_tables.sas7bdat";

        where upcase(table) = "&dataset";

        call symputx(compress("&dataset" || "SORTSTRING"),

             left(keys));

    run;

%mend make_sort_order;

When the %make_sort_order macro is executed, the **SORTSTRING global macro variable is created.

   Here you use the reference_tables.sas7bdat SAS Clinical Standards Toolkit XYZ123 SDTM domain metadata dataset as the source metadata instead of Excel.

   The **SORTSTRING variable is created in this step, which is used in the final dataset sorting when the actual domain is created. The KEYS variables come from the reference_tables.sas7bdat dataset. In this case, we are assuming that you want your final domain sorted by the contents of the KEYS variable as defined in the study metadata. The KEYS variable often describe a unique record for a subject.

Building the Special-Purpose DM and SUPPDM Domains

The following SAS code builds the DM and SUPPDM datasets from our source clinical trial data found in “Appendix A - Source Data Programs.” The following program assumes that the source datasets can be found under the libref source and that the permanent SAS formats can be found under the libref library.

*---------------------------------------------------------------*;

* DM.sas creates the SDTM DM and SUPPDM datasets and saves them

* as permanent SAS datasets to the target libref.

*---------------------------------------------------------------*;

 

**** CREATE EMPTY DM AND SUPPDM DATASETS;   

* initialize the toolkit framework;

%cst_setStandardProperties(

  _cstStandard=CST-FRAMEWORK,

  _cstSubType=initialize);

 

* define _ctsGroot macro variable;

%cstutil_setcstgroot;

 

%cst_createTablesForDataStandard(

   _cstStandard=CDISC-SDTM,

   _cstStandardVersion=XYZ-SDTM-3.2,

   _cstOutputLibrary=work

   );

 

 

**** GET FIRST AND LAST DOSE DATE FOR RFSTDTC AND RFENDTC;  

proc sort

  data=source.dosing(keep=subject startdt enddt)

  out=dosing;

    by subject startdt enddt;

run;

 

**** FIRSTDOSE=FIRST DOSING AND LASTDOSE=LAST DOSING;

data dosing;

  set dosing;

    by subject;

 

    retain firstdose lastdose;

 

    if first.subject then

      do;

        firstdose = .;

        lastdose = .;

      end;

 

    firstdose = min(firstdose,startdt,enddt);

    lastdose = max(lastdose,startdt,enddt);

 

    if last.subject;

run;

 

**** GET DEMOGRAPHICS DATA;

proc sort

  data=source.demographic

  out=demographic;

    by subject;

run;

 

**** MERGE DEMOGRAPHICS AND FIRST DOSE DATE;

data demog_dose;

  merge demographic

        dosing;

    by subject;

run;

 

**** DERIVE THE MAJORITY OF SDTM DM VARIABLES;      

options missing = ' ';

data dm;

  set dm

    demog_dose(rename=(race=_race));

 

    studyid = 'XYZ123';

    domain = 'DM';

    usubjid = left(uniqueid);                      

    subjid = put(subject,3.);

    rfstdtc = put(firstdose,yymmdd10.);

    rfendtc = put(lastdose,yymmdd10.);

    rfxstdtc = put(firstdose,yymmdd10.);

    rfxendtc = put(lastdose,yymmdd10.);

    rficdtc = put(icdate,yymmdd10.);

    rfpendtc = put(lastdoc,yymmdd10.);

    dthfl = 'N';

    siteid = substr(subjid,1,1) || "00";

    brthdtc = put(dob,yymmdd10.);

    age = floor ((intck('month',dob,firstdose) -

          (day(firstdose) < day(dob))) / 12);

    if age ne . then

      ageu = 'YEARS';

    sex = put(gender,sex_demographic_gender.);    

    race = put(_race,race_demographic_race.);

    armcd = put(trt,armcd_demographic_trt.);

    arm = put(trt,arm_demographic_trt.);

    actarmcd = put(trt,armcd_demographic_trt.);

    actarm = put(trt,arm_demographic_trt.);

    country = "USA";

run;

**** DEFINE SUPPDM FOR OTHER RACE;

data suppdm;

  set suppdm

      dm;

    keep studyid rdomain usubjid idvar idvarval qnam qlabel qval qorig  

         qeval;

    **** OUTPUT OTHER RACE AS A SUPPDM VALUE;  

    if orace ne '' then

      do;

        rdomain = 'DM';

        qnam = 'RACEOTH';

        qlabel = 'Race, Other';

        qval = left(orace);

        qorig = 'CRF';

        output;

      end;

 

    **** OUTPUT RANDOMIZATION DATE AS SUPPDM VALUE;

    if randdt ne . then

      do;

        rdomain = 'DM';

        qnam = 'RANDDTC';

        qlabel = 'Randomization Date';

        qval = left(put(randdt,yymmdd10.));

        qorig = 'CRF';

        output;

      end;

run;

 

 

**** SORT DM ACCORDING TO METADATA AND SAVE PERMANENT DATASET;   

%make_sort_order(dataset=DM)        

 

proc sort

  data=dm(keep = studyid domain usubjid subjid rfstdtc rfendtc rfxstdtc

                 rfxendtc rficdtc rfpendtc dthdtc dthfl siteid brthdtc age

                 ageu sex race armcd arm country)

  out=target.dm;

    by &DMSORTSTRING;

run;

 

 

**** SORT SUPPDM ACCORDING TO METADATA AND SAVE PERMANENT DATASET;

%make_sort_order(dataset=SUPPDM)

 

proc sort

  data=suppdm

  out=target.suppdm;

    by &SUPPDMSORTSTRING;

run;

When the DM.sas program has been run, the DM and SUPPDM SDTM domain datasets are saved to the target libref.

   The first step in this program creates the empty SDTM DM and SUPPDM datasets called DM and SUPPDM, based on the SAS Clinical Standards Toolkit metadata.

   The SDTM DM variables RFSTDTC and RFENDTC are defined here as the first day of study medication dosing and the last day of dosing, respectively.

   This is where the empty dataset DM with the defining variable attributes is set with the source data and the bulk of the SDTM DM variables are defined. Note the RENAME clause in the SET statement, which is required when you have source variables named the same as target variables with conflicting variable attributes.

   In these examples, you see that there is a source variable called UNIQUEID in the source datasets, which is supposed to uniquely identify a patient within and across studies. In most clinical databases, a truly unique patient identifier UNIQUEID does not exist, and in practice many trials are submitted where USUBJID is set equal to SUBJID.

   For the SEX, RACE, ARM, and ARMCD variables, the associated formats were created in the make_codelist_formats.sas program in the previous section. In this example, ARM is the same as ACTARM, which is fairly simplistic. It in no way means that your study will have all patients receiving assigned treatment.

   The supplemental qualifiers created here in SUPPDM are for other race and randomization date. This chunk of code creates those qualifier records. However, you typically have to define IDVAR and IDVARVAL. IDVAR defines the SDTM parent domain variable.  IDVARVAL defines the value of that variable that can be used to join or merge these supplemental qualifier variables back onto the parent domain. Often, IDVAR=--SEQ and IDVARVAL is the sequence number because --SEQ tends to be the most exacting identifier that you can have in the SDTM because it identifies a single record. You should define IDVAR to be the highest-level identifier that you can in order to be clear about the qualifying relationship to the parent domain.

   At this point in the program, we call the %make_sort_order macro twice to get the DMSORTSTRING and SUPPDMSORTSTRING macro variables defined. Then we use that to sort and save our final DM and SUPPDM domain datasets.

The remaining domains created with Base SAS in Chapter 3 can be modified like this to use the SAS Clinical Standards Toolkit metadata instead of Microsoft Excel. The key changes involve the empty dataset creation and the final sort order definition so that those are based on the SAS Clinical Standards Toolkit instead of Excel. However, the remaining code from Chapter 3 is essentially untouched here in Chapter 4.

Building Define.xml

Now that you have built your SDTM datasets based on the XYZ123 custom SDTM standard in the SAS Clinical Standards Toolkit, you can build your define.xml file using the SAS Clinical Standards Toolkit. The first thing to do is to create an area to store your metadata in order to build your define file. For this example, the C:UsersyouridDesktopSAS_BOOK_cdisc_2nd_editionCSTCST_make_define folder was created for this work as the “root” level for the define file work. Under this root level, you will want to create additional folders called “metadata,” “results,” “sourcedata,” “sourcexml,” and “stylesheet.” These folders will contain the following content:

Folder Contents
“root” This is where you will store your CST programs
metadata This is where you will create SAS datasets source_study, source_tables, source_values, source_codelists, and source_documents that drive the define.xml creation process.
esults This is where create_sasdefine_from_source.sas and create_definexml.sas will write informational run log datasets that you can review.
sourcedata This is where create_sasdefine_from_source.sas writes datasets for create_definexml.sas to use.
sourcexml This is where created_definexml.sas will save your final define.xml and associated XSL file.
stylesheet This is the template XSL style sheet that create_definexml.sas uses and places into sourcexml.

Keep in mind that the CST is designed to be run in UTF-8 encoding, so you may need to switch your SAS session encoding from Latin to UTF-8 before running any programs below.

Create the Study Level Metadata Dataset

You need to first define a study level metadata dataset called C:UsersyouridDesktopSAS_BOOK_cdisc_2nd_editionCSTCST_make_definemetadatasource_study.sas7bdat. This is manually created study-level metadata data that ends up in the define file header. For this example, that dataset looks like this:

image

Create the Table and Column-Level Metadata Datasets

Now you need to create the table and column-level metadata datasets, which you can get from your CST defined standard. Copy C:cstGlobalLibrarystandardsXYZ_program_cdisc-sdtm-3.2-1.6metadata reference_columns and reference_tables SAS datasets for the XYZ123 standard to the define file metadata folder of C:UsersyouridDesktopSAS_BOOK_cdisc_2nd_editionCSTCST_make_definemetadata source_columns.sas7bdat and source_tables.sas7bdat respectively. Subset those datasets just for the domains and variables found in the XYZ123 SDTM datasets.

The define file generation process requires a few additional columns that are not found in the reference_tables and reference_columns datasets that you do need to add for the define file generation to work properly. When you copy reference_tables to source_tables, you need to add columns StudyVersion, Domain, Order, and DomainDescription. When copying reference_columns to source_columns, you need to add columns StudyVersion, SignificantDigits, and OriginDescription.

Create the Value-Level Metadata Dataset

Value-level metadata is essentially row-level metadata that enables you to further distinguish more precise metadata characteristics of a column value. Think of laboratory data and how the results can have varying types (for example, character or numeric) or varying degrees of numeric precision (that is, significant digits). For the SDTM, some level of value-level metadata is expected, but the precise quantity needed is left undefined by CDISC. For this example, the only value-level metadata that we specify is around the lab data. It is as follows with the null value variables of ALGORITHM, COMMENT, VALUE, and WHERECLAUSECOMMENT columns hidden. Here is a snapshot of the source_values dataset:

image

image

Create the Codelists Metadata Dataset

For every column in the source_columns or source_values dataset that has an XMLCODELIST defined, you need to create a codelist in the source_codelist dataset. Here is what that dataset looks like with the null value variables of CODEDVALUENUM, CODELISTDESCRIPTION, EXTENDEDVALUE, HREF, and REF hidden. Also note that this is only a partial selection of all of the rows in the source_codelists dataset.

image

image

Create the Document Reference Metadata Dataset

Hyperlinks to external documents from the define.xml file is are handled by the CST in a document reference dataset called source_documents. You need to create a row in this dataset for each document reference that you wish.

image

Create Define File Generation Programs

Now that the SAS Clinical Standards Toolkit define file metadata has been created, you can create the define file generation programs. There are two steps to generating the define file. First you must run a program that creates the source datasets that feed the define file. Then you must run a program that uses those datasets to create the define.xml file itself.

To create the program that creates the datasets that are used to write the define file, copy create_sasdefine_from_source.sas from: C:cstSampleLibrarycdisc-definexml-2.0.0-1.6programs to C:UsersyouridDesktopSAS_BOOK_cdisc_2nd_editionCSTCST_make_define. After a few edits, the final create_sasdefine_from_source.sas program looks like this:

******************************************************************************;

* create_sasdefine_from_source.sas                                           *;

*                                                                            *;

* Sample driver program to perform a primary Toolkit action, in this case,   *;

* creating the Define-XML data sets from the CDISC standard model (SDTM,     *;

* ADaM or SEND source metadata).                                             *;

* A call to a standard-specific Define-XML macro is required later in this   *;

* code.                                                                      *;

*                                                                            *;

* Assumptions:                                                               *;

*         The SASReferences file must exist, and must be identified in the   *;

*         call to cstutil_processsetup if it is not work.sasreferences.      *;

*                                                                            *;

* CSTversion  1.6                                                            *;

*                                                                            *;

*  The following statements may require information from the user            *;

*********************************************************************** ******;

 

%let _cstStandard=CDISC-DEFINE-XML;

%let _cstStandardVersion=2.0.0;    * <----- User sets the Define-XML version *;

 

%let _cstTrgStandard=CDISC-SDTM;   * <----- User sets to standard of the study*;

%let _cstTrgStandardVersion=XYZ-SDTM-3.2; * <----- User sets to standard version     *;

 

%*let _cstTrgStandard=CDISC-ADAM;  * <----- User sets to standard of the study  *;

%*let _cstTrgStandardVersion=2.1;  * <----- User sets to standard version    *;

 

%* Subfolder with the SAS Source Metadata data sets;

%let _cstSrcMetaDataFolder=%lowcase(&_cstTrgStandard)-&_cstTrgStandardVersion/metadata;

 

 

******************************************************************************;

* The following code sets (at a minimum) the studyrootpath and               *;

* studyoutputpath. These are used to make the driver programs portable across*;

* platforms and allow the code to be run with minimal modification. These    *;

* macro variables by default point to locations within the cstSampleLibrary, *;

* set during install but modifiable thereafter.  The cstSampleLibrary is     *;

* assumed to allow write operations by this driver module.                   *;

******************************************************************************;

 

%cst_setStandardProperties(_cstStandard=CST-FRAMEWORK,_cstSubType=initialize);

%cstutil_setcstsroot;

data _null_;

call symput ('studyRootPath',cats("C:UsersyouridDesktopSAS_BOOK_cdisc_2nd_editionCSTCST_make_define"));   

call symput ('studyOutputPath',cats("C:UsersyouridDesktopSAS_BOOK_cdisc_2nd_editionCSTCST_make_define"));

run;

%let workPath=%sysfunc(pathname(work));

 

 

******************************************************************************;

* One strategy to defining the required library and file metadata for a CST  *;

* process is to optionally build SASReferences in the WORK library.  An      *;

* example of how to do this follows.                                         *;

*                                                                            *;

* The call to cstutil_processsetup below tells CST how SASReferences will be *;

* provided and referenced. If SASReferences is built in work, the call to    *;

* cstutil_processsetup may, assuming all defaults, be as simple as:          *;

*        %cstutil_processsetup(_cstStandard=CDISC-SDTM)                      *;

******************************************************************************;

 

%let _cstSetupSrc=SASREFERENCES;

 

%cst_createdsfromtemplate(_cstStandard=CST-FRAMEWORK, _cstType=control,_cstSubType=reference, _cstOutputDS=work.sasreferences);

 

proc sql;                            

  insert into work.sasreferences

  values ("CST-FRAMEWORK"     "1.2"                     "messages"        ""           "messages" "libref"  "input"  "dataset"  "N"  "" ""                          1  ""                         "")

  values ("&_cstStandard"     "&_cstStandardVersion"    "messages"        ""           "crtmsg"   "libref"  "input"  "dataset"  "N"  "" ""                          2  ""                         "")

  values ("&_cstStandard"     "&_cstStandardVersion"    "autocall"        ""           "auto1"    "fileref" "input"  "folder"   "N"  "" ""                          1  ""                         "")

  values ("&_cstStandard"     "&_cstStandardVersion"    "properties"      "initialize" "inprop"   "fileref" "input"  "file"     "N"  "" ""                          1  ""                         "")

  values ("&_cstStandard"     "&_cstStandardVersion"    "results"         "results"    "results"  "libref"  "output" "dataset"  "Y"  "" "&studyOutputPath/results"  .  "sourcetodefine_results.sas7bdat" "")

  values ("&_cstStandard"     "&_cstStandardVersion"    "sourcedata"      ""           "srcdata"  "libref"  "output" "folder"   "Y"  "" "&studyOutputPath/sourcedata" . ""   "")

  values ("&_cstTrgStandard"  "&_cstTrgStandardVersion" "sourcemetadata"  "study"      "sampdata" "libref"  "input"  "dataset"  "N"  "" "&studyRootPath/metadata"  .  "source_study"             "")

  values ("&_cstTrgStandard"  "&_cstTrgStandardVersion" "sourcemetadata"  "table"      "sampdata" "libref"  "input"  "dataset"  "N"  "" "&studyRootPath/metadata"  .  "source_tables"            "")

  values ("&_cstTrgStandard"  "&_cstTrgStandardVersion" "sourcemetadata"  "column"     "sampdata" "libref"  "input"  "dataset"  "N"  "" "&studyRootPath/metadata"  .  "source_columns"           "")

  values ("&_cstTrgStandard"  "&_cstTrgStandardVersion" "sourcemetadata"  "codelist"   "sampdata" "libref"  "input"  "dataset"  "N"  "" "&studyRootPath/metadata"  .  "source_codelists"         "")

  values ("&_cstTrgStandard"  "&_cstTrgStandardVersion" "sourcemetadata"  "value"      "sampdata" "libref"  "input"  "dataset"  "N"  "" "&studyRootPath/metadata"  .  "source_values"            "")

  values ("&_cstTrgStandard"  "&_cstTrgStandardVersion" "sourcemetadata"  "document"   "sampdata" "libref"  "input"  "dataset"  "N"  "" "&studyRootPath/metadata"  .  "source_documents"         "")

;

quit;

 

************************************************************;

* Debugging aid:  set _cstDebug=1                          *;

* Note value may be reset in call to cstutil_processsetup  *;

*  based on property settings.  It can be reset at any     *;

*  point in the process.                                   *;

************************************************************;

%let _cstDebug=0;

data _null_;

  _cstDebug = input(symget('_cstDebug'),8.);

  if _cstDebug then

    call execute("options &_cstDebugOptions;");

  else

   call execute(("%sysfunc(tranwrd(options %cmpres(&_cstDebugOptions), %str( ),   %str( no)));"));

run;

 

******************************************************************************;

* Clinical Standards Toolkit utilizes autocall macro libraries to contain    *;

* and reference standard-specific code libraries. Once the autocall path is  *;

* set and one or more macros have been used within any given autocall        *;

* library deallocation or reallocation of the autocall fileref cannot occur  *;

* unless the autocall path is first reset to exclude the specific fileref.   *;

*                                                                            *;

* This becomes a problem only with repeated calls to %cstutil_processsetup() *;

* or %cstutil_allocatesasreferences within the same sas session.  Doing so,  *;

* without submitting code similar to the code below may produce SAS errors   *;

* such as:                                                                   *;

*   ERROR - At least one file associated with fileref AUTO1 is still in use. *;

*   ERROR - Error in the FILENAME statement.                                 *;

*                                                                            *;

* If you call %cstutil_processsetup() or %cstutil_allocatesasreferences more *;

* than once within the same sas session, typically using %let                *;

* _cstReallocateSASRefs=1 to tell CST to attempt reallocation, use of the    *;

* following code is recommended between each code submission.                *;

*                                                                            *;

* Use of the following code is NOT needed to run this driver module          *;

* initially.                                                                 *;

******************************************************************************;

 

%*let _cstReallocateSASRefs=1;

%*include "&_cstGRoot/standards/cst-framework-&_cstVersion/programs/resetautocallpath.sas";

 

 

******************************************************************************;

* The following macro (cstutil_processsetup) utilizes the following          *;

* parameters:                                                                *;

*                                                                            *;

* _cstSASReferencesSource - Setup should be based upon what initial source?  *;

*   Values: SASREFERENCES (default) or RESULTS data set. If RESULTS:         *;

*     (1) no other parameters are required and setup responsibility is       *;

*            passed to the cstutil_reportsetup macro                         *;

*     (2) the results data set name must be passed to cstutil_reportsetup as *;

*            libref.memname                                                  *;

*                                                                            *;

* _cstSASReferencesLocation - The path (folder location) of the              *;

*                             sasreferences data set (default is the path to *;

                              the WORK library)                              *;

*                                                                            *;

* _cstSASReferencesName - The name of the sasreferences data set             *;

*                              (default is sasreferences)                    *;

******************************************************************************;

 

%cstutil_processsetup();

 

*********************  *******************************************************;

* Run the standard-specific Define-XML macros.                               *;

*******************************************************************************;

 

%define_sourcetodefine(

  _cstOutLib=srcdata,

  _cstSourceStudy=sampdata.source_study,

  _cstSourceTables=sampdata.source_tables,

  _cstSourceColumns=sampdata.source_columns,

  _cstSourceCodeLists=sampdata.source_codelists,

  _cstSourceDocuments=sampdata.source_documents,

  _cstSourceValues=sampdata.source_values,

  _cstFullModel=N,

  _cstLang=en

  );

 

******************************************************************************;

* Clean-up the CST process files, macro variables and macros.                *;

******************************************************************************;

* Delete sasreferences if created above  *;

proc datasets lib=work nolist;

  delete sasreferences / memtype=data;

quit;

 

%*cstutil_cleanupcstsession(

     _cstClearCompiledMacros=0

    ,_cstClearLibRefs=1

    ,_cstResetSASAutos=1

    ,_cstResetFmtSearch=0

    ,_cstResetSASOptions=0

    ,_cstDeleteFiles=1

    ,_cstDeleteGlobalMacroVars=0);

   You need to define the _cstTrgStandard and _cstTrgStandardVersion macro variables to point at your standard for the study.

   The studyRootpath and studyOutputPath need to point to your define file work area.

   This is where you need to define your sasreferences dataset. It defines where the CST can find things. If you set up the folder structure as indicated at the start of this section, then this section can be left as it is.

Any findings from running this program would be written to the esultssourcetodefine_results.sas7bdat SAS dataset. After create_sasdefine_from_source.sas has been run, it creates the source datasets needed for the SAS Clinical Standards Toolkit to create the define.xml file. Those datasets are stored at C:UsersyouridDesktopSAS_BOOK_cdisc_2nd_editionCSTCST_make_definesourcedata. The datasets look like this:

image

Now you need to run the SAS program that takes those SAS datasets and writes the actual define file. Copy create_definexml.sas from C:cstSampleLibrarycdisc-definexml-2.0.0-1.6programs to C:UsersyouridDesktopSAS_BOOK_cdisc_2nd_editionCSTCST_make_define. The final create_definexml.sas program that writes the define file looks like this:

******************************************************************************;

* create_definexml.sas                                                       *;

*                                                                            *;

* Sample driver program to create a CDISC-DEFINE-XML V2.0.0 define.xml file  *;

*                                                                            *;

* Assumptions:                                                               *;

*         The SASReferences file must exist, and must be identified in the   *;

*         call to cstutil_processsetup if it is not work.sasreferences.      *;

*                                                                            *;

* CSTversion  1.6                                                            *;

*                                                                            *;

*  The following statements may require information from the user            *;

******************************************************************************;

 

%let _cstStandard=CDISC-DEFINE-XML;

%let _cstStandardVersion=2.0.0;

 

%let _cstTrgStandard=CDISC-SDTM;          * <----- User sets to standard        *;

%let _cstTrgStandardVersion=XYZ-SDTM-3.2; * <----- User sets to standard version*;

%let _cstDefineFile=define.xml;

 

%*let _cstTrgStandard=CDISC-ADAM;     * <----- User sets to standard         *;

%*let _cstTrgStandardVersion=2.1;     * <----- User sets to standard version *;

%*let _cstDefineFile=define.xml;

 

%* Subfolder with the SAS Define-XML data sets;

%let _cstSrcDataFolder=%lowcase(&_cstTrgStandard)-&_cstTrgStandardVersion;

 

******************************************************************************;

* The following data step sets (at a minimum) the studyrootpath and          *;

* studyoutputpath. These are used to make the driver programs portable       *;

* across platforms and allow the code to be run with minimal modification.   *;

* These nacro variables by default point to locations within the             *;

* cstSampleLibrary, set during install but modifiable thereafter. The        *;

* cstSampleLibrary is assumed to allow write operations by this driver       *;

* module.                                                                    *;

************* ****************************************************************;

 

%cst_setStandardProperties(_cstStandard=CST-FRAMEWORK,_cstSubType=initialize);

%cstutil_setcstsroot;

data _null_;

call symput ('studyRootPath',cats("C:UsersyouridDesktopSAS_BOOK_cdisc_2nd_editionCSTCST_make_define"));  

call symput ('studyOutputPath',cats("C:UsersyouridDesktopSAS_BOOK_cdisc_2nd_editionCSTCST_make_define"));

run;

%let workPath=%sysfunc(pathname(work));

 

 

******************************************************************************;

* One strategy to defining the required library and file metadata for a CST  *;

* process is to optionally build SASReferences in the WORK library.  An      *;

* example of how to do this follows.                                         *;

*                                                                            *;

* The call to cstutil_processsetup below tells CST how SASReferences will be *;

* provided and referenced. If SASReferences is built in work, the call to    *;

* cstutil_ processsetup may, assuming all defaults, be as simple as:         *;

*        %cstutil_processsetup(_cstStandard=CDISC-SDTM)                      *;

******************************************************************************;

 

%let _cstSetupSrc=SASREFERENCES;

 

%cst_createdsfromtemplate(_cstStandard=CST-FRAMEWORK, _cstType=control,_cstSubType=reference, _cstOutputDS=work.sasreferences);

 

proc sql;                          

  insert into work.sasreferences

  values ("CST-FRAMEWORK"  "1.2"                   "messages"     ""           "messages" "libref"  "input"  "dataset"  "N"  ""  ""                                   1 ""                        "")

  values ("&_cstStandard"  "&_cstStandardVersion"  "messages"     ""           "crtmsg"   "libref"  "input"  "dataset"  "N"  ""  ""                                   2 ""                        "")

  values ("&_cstStandard"  "&_cstStandardVersion"  "autocall"     ""           "auto1"    "fileref" "input"  "folder"   "N"  ""  ""                                   1 ""                        "")

  values ("&_cstStandard"  "&_cstStandardVersion"  "control"      "reference"  "control"  "libref"  "both"   "dataset"  "Y"  ""  "&workpath"                          . "sasreferences"           "")

  values ("&_cstStandard"  "&_cstStandardVersion"  "results"      "results"    "results"  "libref"  "output" "dataset"  "Y"  ""  "&studyOutputPath/results"           . "write_results.sas7bdat"  "")

  values ("&_cstStandard"  "&_cstStandardVersion"  "sourcedata"   ""           "srcdata"  "libref"  "input"  "folder"   "N"  ""  "&studyRootPath/sourcedata"          . ""                   "")

  values ("&_cstStandard"  "&_cstStandardVersion"  "externalxml"  "xml"        "extxml"   "fileref" "output" "file"     "Y"  ""  "&studyOutputPath/sourcexml"         . "&_cstDefineFile"         "")

  values ("&_cstStandard"  "&_cstStandardVersion"  "referencexml" "stylesheet" "xslt01"   "fileref" "output" "file"     "Y"  ""  "&studyOutputPath/stylesheet"        . "define2-0-0.xsl"         "")

  values ("&_cstStandard"  "&_cstStandardVersion"  "properties"   "initialize" "inprop"   "fileref" "input"  "file"     "N"  ""  ""                                   1 ""                        "")

  ;

quit;

 

************************************************************;

* Debugging aid:  set _cstDebug=1                          *;

* Note value may be reset in call to cstutil_processsetup  *;

*  based on property settings.  It can be reset at any     *;

*  point in the process.                                   *;

************************************************************;

%let _cstDebug=0;

data _null_;

  _cstDebug = input(symget('_cstDebug'),8.);

  if _cstDebug then

    call execute("options &_cstDebugOptions;");

  else

    call execute(("%sysfunc(tranwrd(options %cmpres(&_cstDebugOptions), %str( ), %str( no)));"));

run;

 

 

******************************************************************************;

* Clinical Standards Toolkit utilizes autocall macro libraries to contain and*;

* reference standard-specific code libraries.  Once the autocall path is set *;

* and one or more macros have been used within any given autocall library,   *;

* deallocation or reallocation of the autocall fileref cannot occur unless   *;

* the autocall path is first reset to exclude the specific fileref.          *;

*                                                                            *;

* This becomes a problem only with repeated calls to %cstutil_processsetup() *;

* or %cstutil_allocatesasreferences within the same sas session.  Doing so,  *;

* without submitting code similar to the code below may produce SAS errors   *;

* such as:                                                                   *;

*   ERROR - At least one file associated with fileref AUTO1 is still in use. *;

*     ERROR - Error in the FILENAME statement.                               *;

*                                                                            *;

* If you call %cstutil_processsetup() or %cstutil_allocatesasreferences more *;

* than once within the same sas session, typically using %let                *;

* _cstReallocateSASRefs=1 to tell CST to attempt reallocation, use of the    *;

* following code is recommended between each code submission.                *;

*                                                                            *;

* Use of the following code is NOT needed to run this driver module          *;

* initially.                                                                 *;

******************************************************************************;

 

%*let _cstReallocateSASRefs=1;

%*include "&_cstGRoot/standards/cst-framework-&_cstVersion/programs/resetautocallpath.sas";

 

 

******************************************************************************;

* The following macro (cstutil_processsetup) utilizes the following          *;

* parameters:                                                                *;

*                                                                            *;

* _cstSASReferencesSource - Setup should be based upon what initial source?  *;

*   Values: SASREFERENCES (default) or RESULTS data set. If RESULTS:         *;

*   (1) no other parameters are required and setup responsibility is         *;

*          passed to the cstutil_reportsetup macro                           *;

*   (2) the results data set name must be passed to cstutil_reportsetup as   *;

*          libref.memname                                                    *;

*                                                                            *;

* _cstSASReferencesLocation - The path (folder location) of the              *;

*                             sasreferences data set (default is             *;

*                             the path to the WORK library)                  *;

*                                                                            *;

* _cstSASReferencesName - The name of the sasreferences data set             *;

*                              (default is sasreferences)                    *;

************************************************************* ****************;

 

%cstutil_processsetup();

 

 

*******************************************************************************;

* Run the standard-specific Define-XML macros.                                *;

*******************************************************************************;

%define_write(

  _cstCreateDisplayStyleSheet=1,

  _cstHeaderComment=%str( Produced from SAS data using the SAS Clinical Standards Toolkit &_cstVersion )

  );

 

***************************************************************************;

* Run the cross-standard schema validation macro.                         *;

* Running cstutilxmlvalidate is not required.  The define_read macro will *;

* attempt to import an invalid define xml file. However, importing an     *;

* invalid define xml file may result in an incomplete import.             *;

*                                                                         *;

* cstutilxmlvalidate parameters (all optional):                           *;

*  _cstSASReferences:  The SASReferences data set provides the location   *:

*          of the to-be-validate XML file associated with a registered    *;

*          standard and standardversion (default:  &_cstSASRefs).         *;

*  _cstLogLevel:  Identifies the level of error reporting.                *;

*          Valid values: Info (default) Warning, Error, Fatal Error       *;

*  _cstCallingPgm:  The name of the driver module calling this macro      *;

***************************************************************************;

 

%cstutilxmlvalidate();

 

***************** ***********************************************************;

* Clean-up the CST process files, macro variables and macros.               *;

*************************************************************** *************;

* Delete sasreferences if created above  *;

proc datasets lib=work nolist;

  delete sasreferences / memtype=data;

quit;

 

%*cstutil_cleanupcstsession(

     _cstClearCompiledMacros=0

    ,_cstClearLibRefs=1

    ,_cstResetSASAutos=1

    ,_cstResetFmtSearch=0

    ,_cstResetSASOptions=0

    ,_cstDeleteFiles=1

    ,_cstDeleteGlobalMacroVars=0);

 

   You need to define the _cstTrgStandard and _cstTrgStandardVersion macro variables to point at your standard for the study.

   The studyRootpath and studyOutputPath need to point to your define file work area.

   This is where you need to define your sasreferences dataset. It defines where the CST can find things. If you set up the folder structure as indicated at the start of this section, then this section can be left as it is.

The %define_write macro actually writes the define.xml file where the _cstCreateDisplayStyleSheet=1 macro variable setting creates the default CDISC supplied style sheet. The %cstutilxmlvalidate macro ensures that the define.xml file is a valid XML file. Any findings from the validation or define file generation would be written to the esultswrite_results.sas7bdat SAS dataset. The start of the resulting define.xml file looks like this:

image

Chapter Summary

In this chapter, you used the SAS Clinical Standards Toolkit to define and register a new XYZ123 compound customized SDTM standard. You then used that XYZ123 standard to build SDTM domains within Base SAS code. This chapter shows you how you can use the SAS Clinical Standards Toolkit to house your CDISC SDTM metadata instead of Microsoft Excel (as seen in Chapter 2). The Base SAS SDTM conversion code from Chapter 3 was then updated to use the SAS Clinical Standards Toolkit metadata for conversion purposes. Finally, we used the SAS Clinical Standards Toolkit to create the define.xml file.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset