💡 この記事でわかること
  • CDISCとADaMの基本概念と規制上の位置づけ
  • AIへの効果的なプロンプト設計でSASマクロを自動生成する方法
  • ADLB(臨床検査解析データセット)のSASマクロ実装例
  • ADQS(質問票スコア解析データセット)のSASマクロ実装例
  • AI生成コードを実務で活用する際の品質管理ポイント

はじめに

臨床試験データの規制当局への提出において、CDISC標準に準拠したADaMデータセットの作成は、製薬企業の生物統計担当者・SASプログラマーにとって避けて通れない実務です。ADLBやADQSといったドメインは、標準的な変数構成を持ちながらも、試験ごとに異なる要件が加わるため、ゼロから手作業で構築するのは非常に手間がかかります。

前回の記事「SASマクロ自動生成とAI活用 ― ChatGPT・Claudeで製薬業務を効率化する実践ガイド」では、記述統計・MMRM・AE集計マクロの自動生成方法を紹介しました。本記事ではその続編として、ADLB・ADQSというADaMドメインの自動生成に焦点を当て、AIとSASマクロを組み合わせた実践的な手法を体系的に解説します。

CDISCとADaMの基礎知識

CDISCとは

CDISC(Clinical Data Interchange Standards Consortium)は、臨床試験データの標準化を推進する国際的な非営利団体です。FDAやPMDAなどの規制当局は、申請データにCDISCの標準フォーマットへの準拠を求めており、現在では多くの治験でCDISCへの対応が事実上必須となっています。

CDISCが定める主な標準は以下の2つです。

標準名正式名称役割
SDTMStudy Data Tabulation Model収集した生データを標準形式で格納するデータセット
ADaMAnalysis Data ModelSDTMをもとに解析用に加工・派生変数を追加したデータセット

SDTMは「収集データの標準格納」、ADaMは「解析データの標準構造」と理解するとわかりやすいです。ADaMはSDTMから派生変数(ベースライン、変化量、フラグ等)を追加したものと考えてください。

主要なADaMドメイン

ドメイン正式名称対応SDTMドメイン
ADSLSubject-Level Analysis DatasetDM / DS
ADAEAdverse Events Analysis DatasetAE
ADLBLaboratory Data Analysis DatasetLB
ADQSQuestionnaire Scores Analysis DatasetQS
ADEFFEfficacy Analysis Dataset各ドメイン

さらに詳しく学びたい方へ

ADaM Implementation Guide(ADaM IG)や各ドメインの詳細仕様は、CDISC公式サイト(https://www.cdisc.org/standards/foundational/adam)で無償公開されています。実務上の確認はここを参照することが基本です。

AIを使ったADaM作成の全体フロー

前回の記事で紹介したAIプロンプト設計の5要素(目的・入出力仕様・統計手法要件・業界標準準拠・エラー処理)は、ADaMマクロの自動生成でも同様に有効です。以下のフローで進めると効率的です。

  1. SDTM仕様書の確認:対象ドメイン(LBやQS)の変数一覧・コーディング規則を把握する
  2. ADaM仕様書の作成:必要な派生変数(BASE・CHG・フラグ等)と導出ルールを定義する
  3. AIへのプロンプト投入:仕様をプロンプトに整理してChatGPTまたはClaudeに入力する
  4. 生成マクロのレビュー:統計的妥当性・コーディング規則準拠を生物統計家が確認する
  5. テスト・検証:小規模データで動作検証し、期待値と出力を照合する
⚠️ 注意
AI生成マクロは「たたき台」であり、そのまま申請に用いることはできません。規制申請に提出する解析プログラムとして使用する前に、必ず資格を持つ生物統計家・SASプログラマーによるコードレビューと検証が必要です。

SASマクロとAIでADLBを自動生成する

ADLBの主要変数

ADLBはSDTMのLBドメインをベースに、ベースライン・変化量・正常範囲フラグなどの派生変数を加えたデータセットです。以下がコアとなる変数群です。

変数名ラベル導出元
PARAMCDParameter CodeLBTESTCD
PARAMParameterLBTEST
AVALAnalysis ValueLBSTRESN
BASEBaseline ValueVisit 1のAVAL
CHGChange from BaselineAVAL − BASE
PCHGPercent Change from Baseline(CHG / BASE) × 100
ANRINDAnalysis Normal Range IndicatorLBSTNRLO / LBSTNRHI との比較
ANL01FLAnalysis Flag 01ベースライン後の評価時点

AIへのプロンプト例(Claude向け)

以下のように仕様を明示してAIに渡すと、実務で使えるレベルのコードが生成されます。

あなたはSAS専門家です。以下の仕様でADLBデータセットを作成するSASマクロを作成してください。

【入力データセット】
- LB(SDTM LBドメイン):USUBJID, LBTESTCD, LBTEST, LBSTRESN, LBSTRESU,
  LBSTNRLO, LBSTNRHI, LBDTC, VISITNUM, VISIT
- ADSL:USUBJID, TRT01P, TRT01PN, ARM, ARMCD

【作成する派生変数】
- DOMAIN = 'ADLB'
- PARAMCD = LBTESTCD, PARAM = LBTEST
- AVAL = LBSTRESN, AVALU = LBSTRESU
- ADT = LBDTCを数値日付に変換
- BASE = VISITNUM=1のAVAL
- CHG = AVAL - BASE, PCHG = CHG/BASE*100
- ANRLO = LBSTNRLO, ANRHI = LBSTNRHI
- ANRIND:AVAL < ANRLO → 'LOW', > ANRHI → 'HIGH', それ以外 → 'NORMAL'
- BASEFL = 'Y'(VISITNUM=1のとき)
- ANL01FL = 'Y'(VISITNUM>1 かつ AVALが欠測でないとき)

【要件】
- CDISC ADaM IG v2.1に準拠すること
- マクロパラメータで入力・出力データセット名を変更できること
- エラーチェック(欠測値処理)を含めること

SASマクロのコード例

%macro create_adlb(
    lb   = LB,
    adsl = ADSL,
    out  = ADLB
);

  /* ---- Step 1: ソートとマージ ---- */
  proc sort data=&lb.  out=_lb_;   by USUBJID LBTESTCD VISITNUM; run;
  proc sort data=&adsl. out=_adsl_; by USUBJID;                  run;

  data _adlb_base_;
    length DOMAIN $4  PARAMCD $8  PARAM $200
           AVALU  $40 ANRIND  $6  BASEFL $1 ANL01FL $1;
    merge _lb_(in=a) _adsl_(in=b
          keep=USUBJID TRT01P TRT01PN ARM ARMCD);
    by USUBJID;
    if a and b;

    DOMAIN  = 'ADLB';
    PARAMCD = LBTESTCD;
    PARAM   = LBTEST;
    AVAL    = LBSTRESN;
    AVALU   = LBSTRESU;
    ANRLO   = LBSTNRLO;
    ANRHI   = LBSTNRHI;

    /* 解析日(ISO 8601 → SAS日付) */
    if LBDTC ne '' then ADT = input(LBDTC, yymmdd10.);
    format ADT yymmdd10.;

    /* 正常域判定 */
    if      nmiss(AVAL, ANRLO, ANRHI) = 0 then do;
      if      AVAL < ANRLO then ANRIND = 'LOW';
      else if AVAL > ANRHI then ANRIND = 'HIGH';
      else                      ANRIND = 'NORMAL';
    end;

    /* ベースラインフラグ */
    if VISITNUM = 1 and AVAL ne . then BASEFL = 'Y';
  run;

  /* ---- Step 2: ベースライン値を全レコードへ付与 ---- */
  proc sql;
    create table _adlb_base2_ as
      select a.*,
             b.AVAL as BASE
      from _adlb_base_ as a
      left join (
        select USUBJID, PARAMCD, AVAL
        from _adlb_base_
        where BASEFL = 'Y'
      ) as b
      on  a.USUBJID = b.USUBJID
      and a.PARAMCD = b.PARAMCD;
  quit;

  /* ---- Step 3: 変化量・解析フラグの計算 ---- */
  data &out.;
    set _adlb_base2_;

    if BASE ne . then do;
      CHG = AVAL - BASE;
      if BASE ne 0 then PCHG = (CHG / BASE) * 100;
    end;

    if VISITNUM > 1 and AVAL ne . then ANL01FL = 'Y';
  run;

  proc datasets nolist; delete _lb_ _adsl_ _adlb_base_ _adlb_base2_; run; quit;

%mend create_adlb;

/* 実行例 */
%create_adlb(lb=SDTM.LB, adsl=ADAM.ADSL, out=ADAM.ADLB);
📝 解釈・補足
このマクロの処理ポイントは3点です。

VISITNUM=1をベースラインと定義していますが、実試験では「Day 1のランダム化前」や「最後のベースライン評価」など試験デザインに応じた定義が必要です。
ANRINDはSDTMのLBNRINDと異なり、解析用基準値を使って再計算する点がADaMの特徴です。
ANL01FLは解析対象レコードを識別するフラグで、表作成プログラムでWHERE条件として使用します。試験ごとに定義を調整してください。

SASマクロとAIでADQSを自動生成する

ADQSの特徴と主要変数

ADQSは質問票・評価スケール(PANSS、HAMD、SF-36等)のスコアを格納するADaMドメインです。ADLBとの最大の違いは、個別項目スコアに加えて合計スコア(Total Score)を合成する点です。合成レコードには DTYPE='COMPOSITE' を設定します。

SASマクロのコード例

%macro create_adqs(
    qs     = QS,
    adsl   = ADSL,
    scale  = ,
    out    = ADQS
);

  /* ---- Step 1: 対象スケールの抽出とADSLマージ ---- */
  proc sort data=&qs.(where=(upcase(QSCAT)=upcase("&scale.")))
            out=_qs_; by USUBJID QSTESTCD VISITNUM; run;

  data _adqs_base_;
    length DOMAIN $4 PARAMCD $8 PARAM $200 DTYPE $10 BASEFL $1;
    merge _qs_(in=a)
          &adsl.(in=b keep=USUBJID TRT01P TRT01PN ARM ARMCD);
    by USUBJID;
    if a and b;

    DOMAIN  = 'ADQS';
    PARAMCD = QSTESTCD;
    PARAM   = QSTEST;
    AVAL    = QSSTRESN;
    DTYPE   = '';

    if QSDTC ne '' then ADT = input(QSDTC, yymmdd10.);
    format ADT yymmdd10.;

    if VISITNUM = 1 and AVAL ne . then BASEFL = 'Y';
  run;

  /* ---- Step 2: 合計スコアの計算(DTYPE=COMPOSITE)---- */
  proc means data=_adqs_base_ noprint nway;
    class USUBJID VISITNUM ADT TRT01P TRT01PN ARM ARMCD;
    var AVAL;
    output out=_adqs_total_(drop=_TYPE_ _FREQ_) sum=AVAL;
  run;

  data _adqs_total2_;
    set _adqs_total_;
    length DOMAIN $4 PARAMCD $8 PARAM $200 DTYPE $10;
    DOMAIN  = 'ADQS';
    PARAMCD = upcase("&scale.") || 'TOT';
    PARAM   = "&scale. Total Score";
    DTYPE   = 'COMPOSITE';
  run;

  /* ---- Step 3: 個別項目と合計スコアの結合 ---- */
  data _adqs_all_;
    set _adqs_base_ _adqs_total2_;
  run;

  /* ---- Step 4: ベースライン・変化量の付与 ---- */
  proc sql;
    create table _adqs_bsl_ as
      select a.*,
             b.AVAL as BASE
      from _adqs_all_ as a
      left join (
        select USUBJID, PARAMCD, AVAL
        from _adqs_base_
        where BASEFL = 'Y'
      ) as b
      on  a.USUBJID = b.USUBJID
      and a.PARAMCD = b.PARAMCD;
  quit;

  data &out.;
    length ANL01FL $1;
    set _adqs_bsl_;

    if BASE ne . then do;
      CHG = AVAL - BASE;
      if BASE ne 0 then PCHG = (CHG / BASE) * 100;
    end;

    if VISITNUM > 1 and AVAL ne . then ANL01FL = 'Y';
  run;

  proc datasets nolist;
    delete _qs_ _adqs_base_ _adqs_total_ _adqs_total2_ _adqs_all_ _adqs_bsl_;
  run; quit;

%mend create_adqs;

/* 実行例:PANSSスケールのADQSを作成 */
%create_adqs(qs=SDTM.QS, adsl=ADAM.ADSL, scale=PANSS, out=ADAM.ADQS);
📝 解釈・補足
ADQSの合計スコアはDTYPE='COMPOSITE'を設定した別レコードとして追加します。例えばPANSSの場合、PARAMCD=’PANSSTOT’のレコードが各Visit×被験者で1行ずつ追加されます。

個別項目(PANSS_P1〜P7等)のBASEは該当PARAMCDのVisit 1値から参照しますが、合計スコアはCompositeのため、BASEはVisit 1の合計値を別途参照する必要があります。実試験では試験のAnalysis Plan(SAP)に従って定義を調整してください。

実務でのポイント

🔑 AI×SASマクロ活用の実務ポイント

1. 仕様書の整備が品質の鍵
AIへのプロンプトの質はそのまま出力コードの質に直結します。ADaM仕様書(Variable Specification)を事前に整備し、ベースラインの定義・フラグ条件・欠測値ルールを明文化してからAIに投入することで、修正コストを大幅に削減できます。

2. AIツール別の使い分け
前回の記事で紹介した通り、ChatGPTはコード生成の安定性が高く、Claudeは規制要件への説明が詳細です。複雑なADaM仕様の場合は「Claudeで要件を整理し、ChatGPTでコード生成する」という使い分けも有効です。

3. 検証データセットの準備
AI生成マクロを検証する際は、期待値を手計算で求めた小規模テストデータセットを事前に用意します。実データで動かす前に、PROC COMPAREで出力を照合することが品質保証の基本です。

4. 統計的妥当性の最終判断は生物統計家が担う
ベースラインの定義やフラグ条件はSAPに依存します。AIが生成したコードが「仕様に合っているか」の判断は、必ず資格を持つ生物統計家が担当してください。

📚 この記事をより深く理解するための参考書籍

ADaMの実装とSASによる臨床試験解析をさらに深く学びたい方に、おすすめの書籍をご紹介します。

『医学への統計学 (統計ライブラリー) 』 丹後 俊郎

製薬開発で必要な統計手法を網羅した実務書です。臨床検査値の解析(ADLBで扱う内容)や評価スケールの解析(ADQSで扱う内容)についても実務的な視点から解説されており、ADaM仕様書を書く際の考え方を整理するのに最適です。

『臨床試験のデザインと解析 薬剤開発のためのバイオ統計 (バイオ統計シリーズ)』 角間辰之

製薬業界の生物統計家が読むべき定番書です。本記事のADQSで扱う評価スケールの解析設計や、ADLBにおける正常範囲の取り扱いといった判断基準の背景となる、臨床試験デザインの基礎を体系的に学ぶことができます。

関連記事・次のステップ

まとめ

本記事では、AIとSASマクロを組み合わせてADLB・ADQSというADaMドメインを自動生成する方法を実践的に解説しました。

CDISCのADaM標準に準拠したデータセット作成は、ベースライン定義・変化量計算・フラグ設定といった定型的な処理が多く、AIによるコード生成の恩恵を受けやすい領域です。特に本記事で示したADLBマクロはそのまま活用できる水準のコードですが、各試験のSAPに基づいたベースライン定義や解析フラグの条件を必ず確認・調整してください。

ADaM作成の効率化は、その後の帳票作成・解析プログラム開発にも波及します。AIを活用したSAS開発の取り組みを積み重ねることで、製薬業務全体の生産性向上を実現していただければと思います。

次回は、AIを使ったTLF(Tables, Listings, Figures)出力プログラムの自動生成についても紹介予定です。

ABOUT ME
tomokichi
外資系製薬会社で生物統計家として働ている1児のパパ。生物統計家とは何か、どのようなスキルが必要か、何を行っているのかを共有していきたいと思っております!生物統計に関する最新情報を皆様にお届けすべく、日々奮闘中です。趣味は筋トレ、温泉巡り、家族と散歩。