Clinwright Public work of Clinwright examples · free Start free

ADLBH

Analysis Dataset Lab Hematology

BASIC DATA STRUCTURE · one record per subject per parameter per analysis visit · keys USUBJID, PARAMCD, AVISIT, LBSEQ

Variables

VariableLabelTypeLengthDerivation
STUDYIDStudy IdentifiertextPredecessor ADSL.STUDYID
SUBJIDSubject Identifier for the StudytextPredecessor ADSL.SUBJID
USUBJIDUnique Subject IdentifiertextPredecessor LB.USUBJID
TRTPPlanned TreatmenttextPredecessor ADSL.TRT01P
TRTPNPlanned Treatment (N)integer8Predecessor ADSL.TRT01PN
TRTAActual TreatmenttextPredecessor ADSL.TRT01A
TRTANActual Treatment (N)integer8Predecessor ADSL.TRT01AN
TRTSDTDate of First Exposure to Treatmentinteger8Predecessor ADSL.TRTSDT
TRTEDTDate of Last Exposure to Treatmentinteger8Predecessor ADSL.TRTEDT
AGEAgeinteger8Predecessor ADSL.AGE
AGEGR1Pooled Age Group 1textPredecessor ADSL.AGEGR1
AGEGR1NPooled Age Group 1 (N)integer8Predecessor ADSL.AGEGR1N
RACERacetextPredecessor ADSL.RACE
RACENRace (N)integer8Predecessor ADSL.RACEN
SEXSextextPredecessor ADSL.SEX
COMP24FLCompleters of Week 24 Population FlagtextPredecessor ADSL.COMP24FL
DSRAEFLDiscontinued due to AE?textPredecessor ADSL.DSRAEFL
SAFFLSafety Population FlagtextPredecessor ADSL.SAFFL
AVISITAnalysis VisittextAnalysis Visit
AVISITNAnalysis Visit (N)integer8Assigned Sponsor
ADYAnalysis Relative Dayinteger8Predecessor LB.LBDY
ADTAnalysis Dateinteger8LB.LBDTC converted to SAS date
VISITVisit NametextPredecessor LB.VISIT
VISITNUMVisit Numberfloat8Predecessor LB.VISITNUM
PARAMParametertextFor PARAMN<100: same as LBTEST concatenated with LBSTRESU. For PARAMN>100: LBTEST concatenated with LB.LBSTRESU concatenated with "change from previous visit, relative to normal range"
PARAMCDParameter CodetextFor PARAMN<100: same as LBTESTCD. For PARAMN>100: _ + LBTESTCD
PARAMNParameter (N)integer8Assigned Sponsor
PARCAT1Parameter Category 1textAssigned Sponsor
AVALAnalysis Valuefloat8
BASEBaseline Valuefloat8LBSTRESN when ADLBC.ABLFL=Y
CHGChange from Baselinefloat8AVAL - BASE, for post baseline records.
A1LOAnalysis Range 1 Lower Limitfloat8Predecessor LB.LBSTNRLO
A1HIAnalysis Range 1 Upper Limitfloat8Predecessor LB.LBSTNRHI
R2A1LORatio to Analysis Range 1 Lower Limitfloat8AVAL / A1LO
R2A1HIRatio to Analysis Range 1 Upper Limitfloat8AVAL / A1HI
BR2A1LOBase Ratio to Analysis Range 1 Lower Limfloat8AVAL / A1LO at baseline
BR2A1HIBase Ratio to Analysis Range 1 Upper Limfloat8AVAL / A1HI at baseline
ANL01FLAnalysis Flag 01textY' if the absolute value of this AVAL is the largest for the subject for VISITS 4-12 inclusive. Null otherwise. Only the first on-treatment AVAL that has absolute val equal to the max is flagged
ALBTRVALAmount Threshold Rangefloat8Maximum of [LBSTRESN-(1.5*ULN)] and [(.5*LLN) - LBSTRESN]
ANRINDAnalysis Reference Range IndicatortextIf AVAL < (0.5*LBSTNRLO) then ANRIND='L'. If LAVAL > 1.5* LBSTNRHI then ANRIND='H'. ANRIND='N' otherwise. Used for shift tables.
BNRINDBaseline Reference Range IndicatortextADLBC.ANRIND when ADLBC.ABLFL=Y
ABLFLBaseline Record FlagtextY if VISITNUM=1, null otherwise
AENTMTFLLast value in treatment visittextLast observed value for this lab test during treatment phase: 'Y' if VISITNUM=12. If subject discontinues prior to VISIT 12, then this variable is set to 'Y' if this is the last assessment of this analyte for the subject
LBSEQSequence Numberinteger8Predecessor LB.LBSEQ
LBNRINDReference Range IndicatortextPredecessor LB.LBNRIND
LBSTRESNNumeric Result/Finding in Standard Unitsfloat8Predecessor LB.LBSTRESN

Program adlbh.sas

Version 1, written from Clinwright's patterns, 2026-10-17, checks passed.

/*==== 00-header ====*/
/*----------------------------------------------------------------------------
  Data set : ADLBH (Analysis Dataset Lab Hematology)
  Reporting effort : CSR
  ADaM     : ADLBC, ADSL
  The header and the finalize step follow from the specification.
----------------------------------------------------------------------------*/
libname sdtm "/work/sdtm" access=readonly;
libname adam "/work/adam";
options validvarname=upcase nofmterr msglevel=i;

/*==== 10-inputs ====*/
/* The LB records of the tests of the parameter table, with the subject's TRTSDT, TRTEDT, STUDYID, SUBJID, TRT01P, TRT01PN, TRT01A, TRT01AN, AGE, AGEGR1, AGEGR1N, RACE, RACEN, SEX, COMP24FL, DSRAEFL, SAFFL from ADSL. */
proc sort data=sdtm.lb(keep=studyid usubjid lbseq lbtestcd lbstresn lbstnrlo lbstnrhi lbnrind visitnum visit lbdtc lbdy where=(lbtestcd in ('ANISO', 'BASO', 'EOS', 'HCT', 'HGB', 'LYM', 'MACROCY', 'MCH', 'MCHC', 'MCV', 'MICROCY', 'MONO', 'PLAT', 'POIKILO', 'POLYCHR', 'RBC', 'WBC'))) out=work._ds; by usubjid; run;
proc sort data=adam.adsl(keep=usubjid trtsdt trtedt studyid subjid trt01p trt01pn trt01a trt01an age agegr1 agegr1n race racen sex comp24fl dsraefl saffl) out=work._adsl; by usubjid; run;
data work._ds;
  merge work._ds(in=_in) work._adsl;
  by usubjid;
  if _in;
  length trtp $200;
  trtp = trt01p;
  trtpn = trt01pn;
  length trta $200;
  trta = trt01a;
  trtan = trt01an;
  ady = lbdy;
  aval = lbstresn;
  a1lo = lbstnrlo;
  a1hi = lbstnrhi;
run;

/*==== 20-parameters ====*/
/* PARAM: from LBTESTCD by the parameter table (one value format per mapping). */
proc format;
  value $_param
    "ANISO" = "Anisocytes"
    "BASO" = "Basophils (GI/L)"
    "EOS" = "Eosinophils (GI/L)"
    "HCT" = "Hematocrit"
    "HGB" = "Hemoglobin (mmol/L)"
    "LYM" = "Lymphocytes (GI/L)"
    "MACROCY" = "Macrocytes"
    "MCH" = "Ery. Mean Corpuscular Hemoglobin (fmol(Fe))"
    "MCHC" = "Ery. Mean Corpuscular HGB Concentration (mmol/L)"
    "MCV" = "Ery. Mean Corpuscular Volume (fL)"
    "MICROCY" = "Microcytes"
    "MONO" = "Monocytes (GI/L)"
    "PLAT" = "Platelet (GI/L)"
    "POIKILO" = "Poikilocytes"
    "POLYCHR" = "Polychromasia"
    "RBC" = "Erythrocytes (TI/L)"
    "WBC" = "Leukocytes (GI/L)"
    other = " ";
run;
data work._ds;
  set work._ds;
  length param $200;
    param = put(lbtestcd, $_param.);
run;

/* PARAMN: the code of PARAM. */
proc format;
  invalue paramn_ (upcase just)

    "HEMOGLOBIN (MMOL/L)" = 1

    "HEMATOCRIT" = 2

    "ERY. MEAN CORPUSCULAR VOLUME (FL)" = 3

    "ERY. MEAN CORPUSCULAR HEMOGLOBIN (FMOL(FE))" = 4

    "ERY. MEAN CORPUSCULAR HGB CONCENTRATION (MMOL/L)" = 5

    "LEUKOCYTES (GI/L)" = 6

    "LYMPHOCYTES (GI/L)" = 7

    "MONOCYTES (GI/L)" = 8

    "EOSINOPHILS (GI/L)" = 9

    "BASOPHILS (GI/L)" = 10

    "PLATELET (GI/L)" = 11

    "ERYTHROCYTES (TI/L)" = 12

    "ANISOCYTES" = 13

    "MACROCYTES" = 14

    "MICROCYTES" = 15

    "POIKILOCYTES" = 16

    "POLYCHROMASIA" = 17

    other = .;
run;
data work._ds;
  set work._ds;
  if param ne '' then paramn = input(param, paramn_.);
run;

/* PARAMCD: from LBTESTCD by the parameter table (one value format per mapping). */
proc format;
  value $_paramcd
    "ANISO" = "ANISO"
    "BASO" = "BASO"
    "EOS" = "EOS"
    "HCT" = "HCT"
    "HGB" = "HGB"
    "LYM" = "LYM"
    "MACROCY" = "MACROCY"
    "MCH" = "MCH"
    "MCHC" = "MCHC"
    "MCV" = "MCV"
    "MICROCY" = "MICROCY"
    "MONO" = "MONO"
    "PLAT" = "PLAT"
    "POIKILO" = "POIKILO"
    "POLYCHR" = "POLYCHR"
    "RBC" = "RBC"
    "WBC" = "WBC"
    other = " ";
run;
data work._ds;
  set work._ds;
  length paramcd $200;
    paramcd = put(lbtestcd, $_paramcd.);
  /* The records of tests that are not parameters of the data set are not analyzed. */
  if missing(paramcd) then delete;
run;

/*==== 30-timing ====*/
/* ADT: LB.LBDTC as a SAS date. */
data work._ds;
  set work._ds;
  length _dtc $10;
  _dtc = lbdtc; /* (its first 10 characters: SUBSTR would complain of a shorter variable) */
  if length(_dtc) = 10 then adt = input(_dtc, ?? yymmdd10.);

  format adt date9.;
  drop _dtc;
run;

/*==== 40-visits ====*/
/* AVISIT: from the scheduled visit, by its name; other visits get none. */
data work._ds;
  set work._ds;
  length avisit $40;

  select (upcase(visit));

    when ("BASELINE") do; avisitn = 0; avisit = "Baseline"; end;

    when ("WEEK 2") do; avisitn = 2; avisit = "Week 2"; end;

    when ("WEEK 4") do; avisitn = 4; avisit = "Week 4"; end;

    when ("WEEK 6") do; avisitn = 6; avisit = "Week 6"; end;

    when ("WEEK 8") do; avisitn = 8; avisit = "Week 8"; end;

    when ("WEEK 12") do; avisitn = 12; avisit = "Week 12"; end;

    when ("WEEK 16") do; avisitn = 16; avisit = "Week 16"; end;

    when ("WEEK 20") do; avisitn = 20; avisit = "Week 20"; end;

    when ("WEEK 24") do; avisitn = 24; avisit = "Week 24"; end;

    when ("WEEK 26") do; avisitn = 26; avisit = "Week 26"; end;

    when ("END OF TREATMENT") do; avisitn = 99; avisit = "End of Treatment"; end;

    otherwise call missing(avisit, avisitn);
  end;


  if visitnum = 1 then do; avisitn = 0; avisit = "Baseline"; end;

run;

/* End of Treatment: each subject's last scheduled record after baseline up to VISITNUM 12, as a record of its own. */
proc sort data=work._ds(where=(avisitn > 0 and visitnum <= 12)) out=work._eot;
  by usubjid paramcd adt visitnum;
run;
data work._eot;
  set work._eot;
  by usubjid paramcd;
  if last.paramcd;
  avisit = "End of Treatment";
  avisitn = 99;
run;
data work._ds;
  set work._ds work._eot;
run;
proc sort data=work._ds; by usubjid; run;

/*==== 50-baseline ====*/
/* R2A1LO: AVAL / A1LO. */
data work._ds;
  set work._ds;
  if not missing(aval) and a1lo not in (., 0) then r2a1lo = aval / a1lo;
run;

/* R2A1LO as the data set keeps it, for what is derived from it. */
data work._ds; set work._ds; if not missing(r2a1lo) then r2a1lo = round(r2a1lo, 1e-1); run;

/* R2A1HI: AVAL / A1HI. */
data work._ds;
  set work._ds;
  if not missing(aval) and a1hi not in (., 0) then r2a1hi = aval / a1hi;
run;

/* R2A1HI as the data set keeps it, for what is derived from it. */
data work._ds; set work._ds; if not missing(r2a1hi) then r2a1hi = round(r2a1hi, 1e-1); run;

/* ABLFL: the record of visit 1, per subject and PARAMCD. */

data work._ds;
  set work._ds;
  length ablfl $1;
  if visitnum = 1 and not missing(aval) then ablfl = 'Y';
run;

/* BR2A1LO: R2A1LO of the baseline record (ABLFL = 'Y'), per subject and PARAMCD. */
proc sort data=work._ds; by usubjid paramcd; run;
data work._br2a1lo(keep=usubjid paramcd br2a1lo);
  set work._ds(where=(ablfl = 'Y'));
  br2a1lo = r2a1lo;
run;
data work._ds;
  merge work._ds work._br2a1lo;
  by usubjid paramcd;
run;

/* BR2A1HI: R2A1HI of the baseline record (ABLFL = 'Y'), per subject and PARAMCD. */
proc sort data=work._ds; by usubjid paramcd; run;
data work._br2a1hi(keep=usubjid paramcd br2a1hi);
  set work._ds(where=(ablfl = 'Y'));
  br2a1hi = r2a1hi;
run;
data work._ds;
  merge work._ds work._br2a1hi;
  by usubjid paramcd;
run;

/* BASE: AVAL of the baseline record (ABLFL = 'Y'), per subject and PARAMCD. */
proc sort data=work._ds; by usubjid paramcd; run;
data work._base(keep=usubjid paramcd base);
  set work._ds(where=(ablfl = 'Y'));
  base = aval;
run;
data work._ds;
  merge work._ds work._base;
  by usubjid paramcd;
run;

/* The baseline record without an analysis visit (a screening value, the test not done on the day of the first dose): the Baseline analysis visit. */
data work._ds;
  set work._ds;
  if ablfl = 'Y' and missing(avisit) then do; avisit = 'Baseline'; avisitn = 0; _blvis = 1; end;
run;
/* (Then a record of the same subject and PARAMCD at the Baseline visit that is not the baseline, the day of the first dose without a value: no analysis visit.) */
proc sort data=work._ds; by usubjid paramcd descending _blvis; run;
data work._ds;
  set work._ds;
  by usubjid paramcd;
  retain _blmov;
  if first.paramcd then _blmov = (_blvis = 1);
  if _blmov and ablfl ne 'Y' and avisit = 'Baseline' then call missing(avisit, avisitn);
  drop _blvis _blmov;
run;

/* BASE as the data set keeps it, for what is derived from it. */
data work._ds; set work._ds; if not missing(base) then base = round(base, 1e-5); run;

/* CHG: AVAL - BASE, after baseline only. */
data work._ds;
  set work._ds;
  if nmiss(aval, base) = 0 and ablfl ne 'Y' and adt > trtsdt then chg = aval - base;
run;

/*==== 60-flags ====*/
/* ANRIND: AVAL against 0.5 x A1LO and 1.5 x A1HI. */
data work._ds;
  set work._ds;
  length anrind $8;
  if missing(aval) then anrind = '';
  else if not missing(a1lo) and aval < 0.5 * a1lo then anrind = 'L';
  else if not missing(a1hi) and aval > 1.5 * a1hi then anrind = 'H';
  else if nmiss(a1lo, a1hi) < 2 then anrind = 'N';
run;

/* AENTMTFL (Last value in treatment visit): Last observed value for this lab test during treatment phase: 'Y' if VISITNUM=12. If subject discontinues prior to VISIT 12, then this variable is set to 'Y' if this is the last assessment of this analyte for the subject -- to write. */

/* ANL01FL (Analysis Flag 01): Y' if the absolute value of this AVAL is the largest for the subject for VISITS 4-12 inclusive. Null otherwise. Only the first on-treatment AVAL that has absolute val equal to the max is flagged -- to write. */

/* BNRIND: ANRIND of the baseline record (ABLFL = 'Y'), per subject and PARAMCD. */
proc sort data=work._ds; by usubjid paramcd; run;
data work._bnrind(keep=usubjid paramcd bnrind);
  set work._ds(where=(ablfl = 'Y'));
  bnrind = anrind;
run;
data work._ds;
  merge work._ds work._bnrind;
  by usubjid paramcd;
run;

/*==== 70-other ====*/
/* PARCAT1 = "HEM". */
data work._ds;
  set work._ds;
  length parcat1 $40;
  parcat1 = "HEM";
run;

/* ALBTRVAL (Amount Threshold Range): Maximum of [LBSTRESN-(1.5*ULN)] and [(.5*LLN) - LBSTRESN] -- to write. */

/*==== 89-final ====*/
/* The data set as derived; the finalize step keeps the specification's variables. */
data work._final;
  set work._ds;
run;

/*==== 90-finalize ====*/
/* 90-finalize: from the specification; the variables, their order and attributes are not changed here. */
/* The text variables the specification gives no length: as long as their longest value (at least 1). */
%let _len1 = 1; %let _len2 = 1; %let _len3 = 1; %let _len4 = 1; %let _len5 = 1; %let _len6 = 1; %let _len7 = 1; %let _len8 = 1; %let _len9 = 1; %let _len10 = 1; %let _len11 = 1; %let _len12 = 1; %let _len13 = 1; %let _len14 = 1; %let _len15 = 1; %let _len16 = 1; %let _len17 = 1; %let _len18 = 1; %let _len19 = 1; %let _len20 = 1; %let _len21 = 1; %let _len22 = 1;
data _null_;
  length _ren _asg _siz $32767;
  _dsid = open('work._final');
  if varnum(_dsid, 'STUDYID') > 0 then do; _ren = catx(' ', _ren, 'STUDYID=_rz1'); _asg = catx(' ', _asg, 'STUDYID = _rz1;');
    _siz = catx(' ', _siz, '_len1 = max(_len1, lengthn(STUDYID));'); end;
  if varnum(_dsid, 'SUBJID') > 0 then do; _ren = catx(' ', _ren, 'SUBJID=_rz2'); _asg = catx(' ', _asg, 'SUBJID = _rz2;');
    _siz = catx(' ', _siz, '_len2 = max(_len2, lengthn(SUBJID));'); end;
  if varnum(_dsid, 'USUBJID') > 0 then do; _ren = catx(' ', _ren, 'USUBJID=_rz3'); _asg = catx(' ', _asg, 'USUBJID = _rz3;');
    _siz = catx(' ', _siz, '_len3 = max(_len3, lengthn(USUBJID));'); end;
  if varnum(_dsid, 'TRTP') > 0 then do; _ren = catx(' ', _ren, 'TRTP=_rz4'); _asg = catx(' ', _asg, 'TRTP = _rz4;');
    _siz = catx(' ', _siz, '_len4 = max(_len4, lengthn(TRTP));'); end;
  if varnum(_dsid, 'TRTA') > 0 then do; _ren = catx(' ', _ren, 'TRTA=_rz5'); _asg = catx(' ', _asg, 'TRTA = _rz5;');
    _siz = catx(' ', _siz, '_len5 = max(_len5, lengthn(TRTA));'); end;
  if varnum(_dsid, 'AGEGR1') > 0 then do; _ren = catx(' ', _ren, 'AGEGR1=_rz6'); _asg = catx(' ', _asg, 'AGEGR1 = _rz6;');
    _siz = catx(' ', _siz, '_len6 = max(_len6, lengthn(AGEGR1));'); end;
  if varnum(_dsid, 'RACE') > 0 then do; _ren = catx(' ', _ren, 'RACE=_rz7'); _asg = catx(' ', _asg, 'RACE = _rz7;');
    _siz = catx(' ', _siz, '_len7 = max(_len7, lengthn(RACE));'); end;
  if varnum(_dsid, 'SEX') > 0 then do; _ren = catx(' ', _ren, 'SEX=_rz8'); _asg = catx(' ', _asg, 'SEX = _rz8;');
    _siz = catx(' ', _siz, '_len8 = max(_len8, lengthn(SEX));'); end;
  if varnum(_dsid, 'COMP24FL') > 0 then do; _ren = catx(' ', _ren, 'COMP24FL=_rz9'); _asg = catx(' ', _asg, 'COMP24FL = _rz9;');
    _siz = catx(' ', _siz, '_len9 = max(_len9, lengthn(COMP24FL));'); end;
  if varnum(_dsid, 'DSRAEFL') > 0 then do; _ren = catx(' ', _ren, 'DSRAEFL=_rz10'); _asg = catx(' ', _asg, 'DSRAEFL = _rz10;');
    _siz = catx(' ', _siz, '_len10 = max(_len10, lengthn(DSRAEFL));'); end;
  if varnum(_dsid, 'SAFFL') > 0 then do; _ren = catx(' ', _ren, 'SAFFL=_rz11'); _asg = catx(' ', _asg, 'SAFFL = _rz11;');
    _siz = catx(' ', _siz, '_len11 = max(_len11, lengthn(SAFFL));'); end;
  if varnum(_dsid, 'AVISIT') > 0 then do; _ren = catx(' ', _ren, 'AVISIT=_rz12'); _asg = catx(' ', _asg, 'AVISIT = _rz12;');
    _siz = catx(' ', _siz, '_len12 = max(_len12, lengthn(AVISIT));'); end;
  if varnum(_dsid, 'VISIT') > 0 then do; _ren = catx(' ', _ren, 'VISIT=_rz13'); _asg = catx(' ', _asg, 'VISIT = _rz13;');
    _siz = catx(' ', _siz, '_len13 = max(_len13, lengthn(VISIT));'); end;
  if varnum(_dsid, 'PARAM') > 0 then do; _ren = catx(' ', _ren, 'PARAM=_rz14'); _asg = catx(' ', _asg, 'PARAM = _rz14;');
    _siz = catx(' ', _siz, '_len14 = max(_len14, lengthn(PARAM));'); end;
  if varnum(_dsid, 'PARAMCD') > 0 then do; _ren = catx(' ', _ren, 'PARAMCD=_rz15'); _asg = catx(' ', _asg, 'PARAMCD = _rz15;');
    _siz = catx(' ', _siz, '_len15 = max(_len15, lengthn(PARAMCD));'); end;
  if varnum(_dsid, 'PARCAT1') > 0 then do; _ren = catx(' ', _ren, 'PARCAT1=_rz16'); _asg = catx(' ', _asg, 'PARCAT1 = _rz16;');
    _siz = catx(' ', _siz, '_len16 = max(_len16, lengthn(PARCAT1));'); end;
  if varnum(_dsid, 'ANL01FL') > 0 then do; _ren = catx(' ', _ren, 'ANL01FL=_rz17'); _asg = catx(' ', _asg, 'ANL01FL = _rz17;');
    _siz = catx(' ', _siz, '_len17 = max(_len17, lengthn(ANL01FL));'); end;
  if varnum(_dsid, 'ANRIND') > 0 then do; _ren = catx(' ', _ren, 'ANRIND=_rz18'); _asg = catx(' ', _asg, 'ANRIND = _rz18;');
    _siz = catx(' ', _siz, '_len18 = max(_len18, lengthn(ANRIND));'); end;
  if varnum(_dsid, 'BNRIND') > 0 then do; _ren = catx(' ', _ren, 'BNRIND=_rz19'); _asg = catx(' ', _asg, 'BNRIND = _rz19;');
    _siz = catx(' ', _siz, '_len19 = max(_len19, lengthn(BNRIND));'); end;
  if varnum(_dsid, 'ABLFL') > 0 then do; _ren = catx(' ', _ren, 'ABLFL=_rz20'); _asg = catx(' ', _asg, 'ABLFL = _rz20;');
    _siz = catx(' ', _siz, '_len20 = max(_len20, lengthn(ABLFL));'); end;
  if varnum(_dsid, 'AENTMTFL') > 0 then do; _ren = catx(' ', _ren, 'AENTMTFL=_rz21'); _asg = catx(' ', _asg, 'AENTMTFL = _rz21;');
    _siz = catx(' ', _siz, '_len21 = max(_len21, lengthn(AENTMTFL));'); end;
  if varnum(_dsid, 'LBNRIND') > 0 then do; _ren = catx(' ', _ren, 'LBNRIND=_rz22'); _asg = catx(' ', _asg, 'LBNRIND = _rz22;');
    _siz = catx(' ', _siz, '_len22 = max(_len22, lengthn(LBNRIND));'); end;
  _rc = close(_dsid);
  if _ren ne '' then _ren = cats('(rename=(', _ren, '))');
  call symputx('_ren', _ren);
  call symputx('_asg', _asg);
  call symputx('_siz', _siz);
run;
data _null_;
  set work._final end=_end;
  retain _len1 1 _len2 1 _len3 1 _len4 1 _len5 1 _len6 1 _len7 1 _len8 1 _len9 1 _len10 1 _len11 1 _len12 1 _len13 1 _len14 1 _len15 1 _len16 1 _len17 1 _len18 1 _len19 1 _len20 1 _len21 1 _len22 1;
  &_siz
  if _end then do;
    call symputx('_len1', _len1);
    call symputx('_len2', _len2);
    call symputx('_len3', _len3);
    call symputx('_len4', _len4);
    call symputx('_len5', _len5);
    call symputx('_len6', _len6);
    call symputx('_len7', _len7);
    call symputx('_len8', _len8);
    call symputx('_len9', _len9);
    call symputx('_len10', _len10);
    call symputx('_len11', _len11);
    call symputx('_len12', _len12);
    call symputx('_len13', _len13);
    call symputx('_len14', _len14);
    call symputx('_len15', _len15);
    call symputx('_len16', _len16);
    call symputx('_len17', _len17);
    call symputx('_len18', _len18);
    call symputx('_len19', _len19);
    call symputx('_len20', _len20);
    call symputx('_len21', _len21);
    call symputx('_len22', _len22);
  end;
run;
data adam.adlbh(label="Analysis Dataset Lab Hematology");
  attrib
    STUDYID  length=$&_len1 label="Study Identifier"
    SUBJID   length=$&_len2 label="Subject Identifier for the Study"
    USUBJID  length=$&_len3 label="Unique Subject Identifier"
    TRTP     length=$&_len4 label="Planned Treatment"
    TRTPN    length=8 label="Planned Treatment (N)"
    TRTA     length=$&_len5 label="Actual Treatment"
    TRTAN    length=8 label="Actual Treatment (N)"
    TRTSDT   length=8 label="Date of First Exposure to Treatment" format=DATE9.
    TRTEDT   length=8 label="Date of Last Exposure to Treatment" format=DATE9.
    AGE      length=8 label="Age"
    AGEGR1   length=$&_len6 label="Pooled Age Group 1"
    AGEGR1N  length=8 label="Pooled Age Group 1 (N)"
    RACE     length=$&_len7 label="Race"
    RACEN    length=8 label="Race (N)"
    SEX      length=$&_len8 label="Sex"
    COMP24FL length=$&_len9 label="Completers of Week 24 Population Flag"
    DSRAEFL  length=$&_len10 label="Discontinued due to AE?"
    SAFFL    length=$&_len11 label="Safety Population Flag"
    AVISIT   length=$&_len12 label="Analysis Visit"
    AVISITN  length=8 label="Analysis Visit (N)"
    ADY      length=8 label="Analysis Relative Day"
    ADT      length=8 label="Analysis Date" format=DATE9.
    VISIT    length=$&_len13 label="Visit Name"
    VISITNUM length=8 label="Visit Number"
    PARAM    length=$&_len14 label="Parameter"
    PARAMCD  length=$&_len15 label="Parameter Code"
    PARAMN   length=8 label="Parameter (N)"
    PARCAT1  length=$&_len16 label="Parameter Category 1"
    AVAL     length=8 label="Analysis Value"
    BASE     length=8 label="Baseline Value"
    CHG      length=8 label="Change from Baseline"
    A1LO     length=8 label="Analysis Range 1 Lower Limit"
    A1HI     length=8 label="Analysis Range 1 Upper Limit"
    R2A1LO   length=8 label="Ratio to Analysis Range 1 Lower Limit"
    R2A1HI   length=8 label="Ratio to Analysis Range 1 Upper Limit"
    BR2A1LO  length=8 label="Base Ratio to Analysis Range 1 Lower Lim"
    BR2A1HI  length=8 label="Base Ratio to Analysis Range 1 Upper Lim"
    ANL01FL  length=$&_len17 label="Analysis Flag 01"
    ALBTRVAL length=8 label="Amount Threshold Range"
    ANRIND   length=$&_len18 label="Analysis Reference Range Indicator"
    BNRIND   length=$&_len19 label="Baseline Reference Range Indicator"
    ABLFL    length=$&_len20 label="Baseline Record Flag"
    AENTMTFL length=$&_len21 label="Last value in treatment visit"
    LBSEQ    length=8 label="Sequence Number"
    LBNRIND  length=$&_len22 label="Reference Range Indicator"
    LBSTRESN length=8 label="Numeric Result/Finding in Standard Units"
  ;
  set work._final&_ren;
  &_asg
  if not missing(VISITNUM) then VISITNUM = round(VISITNUM, 1e-1);
  if not missing(AVAL) then AVAL = round(AVAL, 1e-5);
  if not missing(BASE) then BASE = round(BASE, 1e-5);
  if not missing(CHG) then CHG = round(CHG, 1e-5);
  if not missing(A1LO) then A1LO = round(A1LO, 1e-5);
  if not missing(A1HI) then A1HI = round(A1HI, 1e-5);
  if not missing(R2A1LO) then R2A1LO = round(R2A1LO, 1e-1);
  if not missing(R2A1HI) then R2A1HI = round(R2A1HI, 1e-1);
  if not missing(BR2A1LO) then BR2A1LO = round(BR2A1LO, 1e-1);
  if not missing(BR2A1HI) then BR2A1HI = round(BR2A1HI, 1e-1);
  if not missing(ALBTRVAL) then ALBTRVAL = round(ALBTRVAL, 1e-3);
  if not missing(LBSTRESN) then LBSTRESN = round(LBSTRESN, 1e-5);
  keep STUDYID SUBJID USUBJID TRTP TRTPN TRTA TRTAN TRTSDT TRTEDT AGE AGEGR1 AGEGR1N RACE RACEN SEX COMP24FL DSRAEFL SAFFL AVISIT AVISITN ADY ADT VISIT VISITNUM PARAM PARAMCD PARAMN PARCAT1 AVAL BASE CHG A1LO A1HI R2A1LO R2A1HI BR2A1LO BR2A1HI ANL01FL ALBTRVAL ANRIND BNRIND ABLFL AENTMTFL LBSEQ LBNRIND LBSTRESN;
run;
proc sort data=adam.adlbh; by USUBJID PARAMCD AVISIT LBSEQ; run;

Data (first 20 of 25,014 records, uploaded)

STUDYIDSUBJIDUSUBJIDTRTPTRTPNTRTATRTANTRTSDTTRTEDTAGEAGEGR1AGEGR1NRACERACENSEXCOMP24FLDSRAEFLSAFFLAVISITAVISITNADYADTVISITVISITNUMPARAMPARAMCDPARAMNPARCAT1AVALBASECHGA1LOA1HIR2A1LOR2A1HIBR2A1LOBR2A1HIANL01FLALBTRVALANRINDBNRINDABLFLAENTMTFLLBSEQLBNRINDLBSTRESN
CDISCPILOT01101501-701-1015Placebo0Placebo02014-01-022014-07-0263<651WHITE1FYNullYBaseline0-72013-12-26SCREENING 11AnisocytesANISO13HEM11Y4ABNORMAL1
CDISCPILOT01101501-701-1015Placebo0Placebo02014-01-022014-07-0263<651WHITE1FYNullYBaseline0-72013-12-26SCREENING 11Basophils (GI/L)BASO10HEM0.050.0500.20.30.3NNY6NORMAL0.05
CDISCPILOT01101501-701-1015Placebo0Placebo02014-01-022014-07-0263<651WHITE1FYNullYEnd of Treatment991682014-06-18WEEK 2412Basophils (GI/L)BASO10HEM0.040.05-0.0100.20.20.3NN263NORMAL0.04
CDISCPILOT01101501-701-1015Placebo0Placebo02014-01-022014-07-0263<651WHITE1FYNullYWeek 1212842014-03-26WEEK 129Basophils (GI/L)BASO10HEM0.040.05-0.0100.20.20.3NN168NORMAL0.04
CDISCPILOT01101501-701-1015Placebo0Placebo02014-01-022014-07-0263<651WHITE1FYNullYWeek 16161262014-05-07WEEK 1610Basophils (GI/L)BASO10HEM0.030.05-0.0200.20.20.3NN203NORMAL0.03
CDISCPILOT01101501-701-1015Placebo0Placebo02014-01-022014-07-0263<651WHITE1FYNullYWeek 22152014-01-16WEEK 24Basophils (GI/L)BASO10HEM0.030.05-0.0200.20.20.3NN43NORMAL0.03
CDISCPILOT01101501-701-1015Placebo0Placebo02014-01-022014-07-0263<651WHITE1FYNullYWeek 20201402014-05-21WEEK 2011Basophils (GI/L)BASO10HEM0.030.05-0.0200.20.20.3NN233NORMAL0.03
CDISCPILOT01101501-701-1015Placebo0Placebo02014-01-022014-07-0263<651WHITE1FYNullYWeek 24241682014-06-18WEEK 2412Basophils (GI/L)BASO10HEM0.040.05-0.0100.20.20.3NN263NORMAL0.04
CDISCPILOT01101501-701-1015Placebo0Placebo02014-01-022014-07-0263<651WHITE1FYNullYWeek 26261822014-07-02WEEK 2613Basophils (GI/L)BASO10HEM0.030.05-0.0200.20.20.3NN298NORMAL0.03
CDISCPILOT01101501-701-1015Placebo0Placebo02014-01-022014-07-0263<651WHITE1FYNullYWeek 44292014-01-30WEEK 45Basophils (GI/L)BASO10HEM0.020.05-0.0300.20.10.3NN78NORMAL0.02
CDISCPILOT01101501-701-1015Placebo0Placebo02014-01-022014-07-0263<651WHITE1FYNullYWeek 66422014-02-12WEEK 67Basophils (GI/L)BASO10HEM0.040.05-0.0100.20.20.3NN108NORMAL0.04
CDISCPILOT01101501-701-1015Placebo0Placebo02014-01-022014-07-0263<651WHITE1FYNullYWeek 88632014-03-05WEEK 88Basophils (GI/L)BASO10HEM0.050.05-000.20.30.3NN138NORMAL0.05
CDISCPILOT01101501-701-1015Placebo0Placebo02014-01-022014-07-0263<651WHITE1FYNullYBaseline0-72013-12-26SCREENING 11Eosinophils (GI/L)EOS9HEM0.130.1300.570.20.2NNY15NORMAL0.13
CDISCPILOT01101501-701-1015Placebo0Placebo02014-01-022014-07-0263<651WHITE1FYNullYEnd of Treatment991682014-06-18WEEK 2412Eosinophils (GI/L)EOS9HEM0.090.13-0.0400.570.20.2NN272NORMAL0.09
CDISCPILOT01101501-701-1015Placebo0Placebo02014-01-022014-07-0263<651WHITE1FYNullYWeek 1212842014-03-26WEEK 129Eosinophils (GI/L)EOS9HEM0.130.13000.570.20.2NN177NORMAL0.13
CDISCPILOT01101501-701-1015Placebo0Placebo02014-01-022014-07-0263<651WHITE1FYNullYWeek 16161262014-05-07WEEK 1610Eosinophils (GI/L)EOS9HEM0.090.13-0.0400.570.20.2NN211NORMAL0.09
CDISCPILOT01101501-701-1015Placebo0Placebo02014-01-022014-07-0263<651WHITE1FYNullYWeek 22152014-01-16WEEK 24Eosinophils (GI/L)EOS9HEM0.080.13-0.0500.570.10.2NN52NORMAL0.08
CDISCPILOT01101501-701-1015Placebo0Placebo02014-01-022014-07-0263<651WHITE1FYNullYWeek 20201402014-05-21WEEK 2011Eosinophils (GI/L)EOS9HEM0.060.13-0.0700.570.10.2NN241NORMAL0.06
CDISCPILOT01101501-701-1015Placebo0Placebo02014-01-022014-07-0263<651WHITE1FYNullYWeek 24241682014-06-18WEEK 2412Eosinophils (GI/L)EOS9HEM0.090.13-0.0400.570.20.2NN272NORMAL0.09
CDISCPILOT01101501-701-1015Placebo0Placebo02014-01-022014-07-0263<651WHITE1FYNullYWeek 26261822014-07-02WEEK 2613Eosinophils (GI/L)EOS9HEM0.070.13-0.0600.570.10.2NN306NORMAL0.07