ADSL 数据集的建立:练习示例

总结

  • 通过一则创立 ADSL 数据集的练习示例加深对 ADSL 数据集的理解;

ADSL(Subject-Level Analysis Data Set) 是 ADaM 中的一种数据集,特点是每一行是一个单独患者的记录(类似 SDTM 中的 DM 数据集),主要包括的变量有:

  • Demographic 相关的变量;
  • 计划和实际的 Treatment 相关变量;
  • 是否为 “Safety” 的患者标识 flag

ADSL 的建立过程中,一般需要从 SDTM Domain 中的数个数据集合并而来:

  • DM 中的大部分变量
  • EX (Exposure),DS (Disposition) 和其他 SDTM Domain

ADSL 的结构

ADSL 的结构是一行记录代表一个患者,包括 Identifier,Demographics, Population flags, treatment, dose 和其他 subject-level 的变量。下面一一进行分析。

  • Identifier 变量
    • STUDYID, USUBJID, SUBJID, SITEID,在存在于 DM 中;
  • Subject Demographics 变量
    • AGE:DM.AGE,如果分析需要 derive 一个 age 出来,需要添加 AAGE 变量;
    • AGEU、SEX、RACE:都从 DM 中合并过来;
  • Population Flag 变量
    • FASFL:全分析数据集的标识
    • SAFFL:Safety Population 的标识
  • Dose 变量
    • TRTSDT、TRTSDTM:分别是 Treatment 中第一次服药的日期和日期时间;
    • TRTxxSDTF:xx一般是两位数字,代表第几个阶段,也就是第几个阶段的TRT;
    • TRTSDTF:第一次服药的标识。
  • Subject-Level Trial Experience 变量
    • EOSDT:研究结束的日期
    • EOSSTT:研究结束的状态,比如取值“COMPLETED”

阅读和熟悉 ADSL 的 Spec

熟悉 ADSL 的 Spec,对于我们初学制作 ADSL 的合并数据集过程非常有帮助。

可以看到 Spec 里面的各个内容:

  • Variable:变量名
  • Label:每个变量的含义说明,基本上和 SDTM IG 中每个变量的 Label 对应;
  • Type:存储格式,分为 char 和 num 两种,需要仔细对照检查,必要时转换;
  • Length:变量储存长度,Derive 新变量的时候要注意设置;
  • Controlled Terminology(CT),有 CT 要求时严格遵守即可;
  • Notes:需要写明每个变量的来源,如果是 Derive 的,需要写清楚计算过程;

Snipaste_2023-05-08_09-27-53.png

Snipaste_2023-05-08_09-28-18.png

ADSL 的程序

第一部分

Derive 以下这几个新变量:

  • AETHNIC:如果 ETHINIC 为空,则赋值 “NOT COLLECTED”;
  • ARACE:转换种族 RACE 变量,方便分析;
  • TRTSDT, TRTSTM:分别是 Treatment 开始时第一次暴露(给药)的日期和时间,注意是以 num 存储并按照规定格式,所以需要 input 转换;
  • TRTEDT,TRTETM:最后一次暴露(给药)的日期和时间,要求同上;
  • TRT01P, TRT01A:分别是计划和实际的治疗方式,按要求转换;
  • SAFFL,FASFL:对应 Safety Population 和 Full Analysis Set 的标识;Safety Population 意指至少经过一次暴露(给药)的人群,所以只要 RFSTDTC 不为空,就代表 “Y”;

注意:Derive 的新版量最好注意一下 length 的设置;

/* Begin Writing SAS Program sdtm.dm.sas */
/* Demographic Variables */
data DM1;
  set sdtm.DM; 

  /* Derive AETHNIC, ARACE */
  length AETHNIC $40.;
  if missing(ETHTIC) then AETHNIC = "NOT COLLECTED";
  else AETHNIC = ETHTIC;
  if RACE="WHITE" then ARACE="W";
  else if RACE="BLACK OR AFRICAN AMERICAN" then ARACE="B";
  else if RACE="NATIVE HAWAIIAN OR OTHER PACIFIC ISLANDERS" then ARACE="HP";
  else if RACE="ASIAN" then ARACE="A";
  else if RACE="AMERICAN INDIAN OR ALASKA AMERICAN" then ARACE="AA";
  
  /* Derive TRTSDT, TRTSTM, TRTEDT, TRTETM */
  TRTSDT = input(substr(RFSTDTC, 1, 10), yymmdd10.);
  TRTSTM = input(substr(RFSTDTC, 12), time5.);
  TRTEDT = input(substr(RFENDTC, 1, 10), yymmdd10.);
  TRTETM = input(substr(RFENDTC, 12), time5.);
  format TRTSDT yymmdd10. TRTSTM time5. TRTEDT yymmdd10. TRTETM time5.;

  /* Derive TRT01P, TRT01A */
  length TRT01P TRT01A $20.;
  if ARMCD = "DRUG A" then TRT01P = "TRTA";
  if ACTARMCD = "DRUG A" then TRT01A = "TRTA"; 

  /* Derive SAFFL, FASFL */
  if ^missing(RFSTDTC) then do;
    SAFFL = "Y";
    FASFL = "Y";
  end;
  else do;
    SAFFL = "N";
    FASFL = "N";
  end;
run;

第二部分

Derive 以下这几个新变量:

  • EOSDT 和 EOSSTT:需要用到 DS Domain 的 DSDECOD(表示患者完成试验的状态),DSSTDTC(表示患者对应试验结束状态的日期)。思路是:先把 DM 和 DS merge 起来,再取出 DSDECOD 和 DSSTDTC 进行转换即可;
  • TR01SDTM,TR01SDT,TR01EDTM,TR01EDT
    • 代表治疗中第一次暴露(给药)的日期和时间,以及最后一次的日期和时间;
    • 来源是 EX Domain 中的 EXSTDTC,EXENDTC,思路是要取出每个 USUBJID 下的第一条给药记录中的 EXSTDTC 和最后一条给药记录中的 EXENDTC,再和 DM 进行 merge,转换对应变量即可;
/* Merge DS and DM1 to catch DSDECOD, DSSTDTC */
proc sql;
  create table DM2 as select a.*, b.DSDECOD, DSSTDTC 
    from DM1 a left join sdtm.DS b on a.USUBJID=b.USUBJID;
quit;

/* Derive EOSDT, EOSSTT variables */
data DM3;
  set DM2;
  length EOSDT 8 EOSSTT $20.;
  EOSDT = input(substr(DSSTDTC, 1, 10), yymmdd10.);
  if DSDECOD="COMPLETED" then EOSSTT="COMPLETED";
  else EOSSTT="DISCONTINUED";
  format EOSDT yymmdd10.;
run;

/* Sort data set SDTM.EX by USUBJID, EXESTDC without duplicate values */
proc sort data=sdtm.EX out=EX nodupkey;
  by USUBJID EXESTDC EXENDTC;
run;

data EX1 EX2;
  set EX;
  by USUBJID EXSTDTC EXENDTC;

  /* Create dataset EX1 if the first.USUBJID statement */
  /* Cretae dataset EX2 if the last.USUBJID statement */
  if first.USUBJID then output EX1;
  if last.USUBJID then output EX2;
run;

/* Create data set DM4 and DM5 */
proc sql;
  create table DM4 as 
    select a.*, b.EXSTDTC 
    from DM3 a left join EX1 b on a.USUBJID=b.USUBJID;
  create table DM5 as
    select a.*, b.EXENDTC
  from DM4 a left join EX2 b on a.USUBJID=b.USUBJID;
quit;

data FINAL;
  set DM5;

  /* Derive TRT01SDTM, TRT01SDT, TRT01EDTM, TRT01EDT */
  length TRT01SDTM TRT01SDT TRT01EDTM TRT01EDT 8.;
  TRT01SDTM = input(EXSTDTC, e8601dt.);
  TRT01SDT = input(substr(EXSTDTC, 1, 10), yymmdd10.);
  TRT01EDTM = input(EXENDTC, e8601dt.);
  TRT01EDT = input(substr(EXENDTC, 1, 10), yymmdd10.);
  format TRT01SDTM TRT01EDTM e8601dt. TRT01SDT TRT01EDT yymmdd10.;
run;

第三部分

主要包括声明 libname、校正所有变量的 label 和 length,以及变量顺序:

libname ADAM ".../directory";
data ADAM.ADSL(label="Subject-Level Analysis Data set");
  /*Assign variable attributes such as label and length to conform with ADAM.ADSL
  Specification (these will also be the same attributes as the ADAM IG). */
  
  attrib
  STUDYID label="Study Identifier" length=$20
  USUBJID label="Unique Subject Identifier" length=$20
  SUBJID label="Subject Identifier for the Study" length=$20
  SITEID label="Study Site Identifier" length=$10
  BRTHDTC label="Date/Time of Birth" length=$20
  AGE label="Age" length=8
  AGEU label="Age Units" length=$10
  SEX label="Sex" lenght=$2
  RACE label="Race" length=$100
  ARACE label="Analysis Race" length=$100
  ETHNIC label="Ethnicity" length=$60
  AETHNIC label="Analysis Ethnicity" length=$60
  SAFFL label="Safety Population Flag" length=$1
  ARM label="Description of Planned Arm" length=$200
  ARMCD label="Planned Arm Code" length=$20
  ACTARMCD label="Actual Arm Code" length=$20
  ACTARM label="Description of Actual Arm" length=$200
  TRT01P label="Planned Treatment for Period 1" length=$20
  TRT01A label="Actual Treatment for Period1" length=$20
  RFSTDTC label="Subject Reference Start Date/Time" length=$20
  RFENDTC label="Subject Reference End Date/Time" length=$20
  TRTSDT label="Date of First Exposure to Treatment" length=8
  TRTSTM label="Time of First Exposure to Treatment" length=8
  TRT01SDTM label="Datetime of First Exposure in Period 1" length=8
  TRT01SDT label="Date of First Exposure of Period 1" length=8
  TRTEDT label="Date of Last Exposure to Treatment" length=8
  TRTETM label="Time of Last Exposure to Treatment" length=8
  TRT01EDTM label="Datetime of Last Exposure in Period 1" length=8
  TRT01EDT label="Date of Last Exposure in Period 1" length=8
  EOSSTT label="End of Study Status" length=$20
  EOSDT label="End of Study" length=8
  COUNTRY label="Country" length=$4
  ;

  set FINAL;
  keep STUDYID USUBJID SUBJID SITEID BRTHDTC AGE AGEU SEX RACE ARACE ETHNIC
  AETHNIC SAFFL ARM ARMCD ACTARMCD ACTARM TRT01P TRT01A RFSTDTC RFENDTC TRTSDT 
  TRTSTM TRT01SDTM TRT01SDT TRTEDT TRTETM TRT01EDTM TRT01EDT EOSSTT EOSDT COUNTRY
  ;
run;

这样就完成了一个初步练习。