0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

飲んだ薬は体内でどう減っていくのか。1・2コンパートメントモデルで血中濃度を計算

0
Posted at

「え、薬って体内でこんな動きしてるの?」

そう思った方、多いんじゃないでしょうか。私も初めて薬物動態のシミュレーターを触った時、血中濃度のグラフがジグザグに上下しながら、だんだん安定していく様子を見て「これ、現実の体内で起きてるんだ…」と衝撃を受けました。

今回は、薬物動態シミュレーター(1/2コンパートメントモデル) を題材に、薬が体内でどう分布し、どう消えていくのかを、数式とコードで深掘りしていきます。

▶ 今回のシミュレーター: 薬物動態シミュレーター(1/2コンパートメントモデル) (ブラウザで動作・登録不要)


導入:あなたの体は「1つの箱」?それとも「2つの箱」?

薬を飲んだり注射したりすると、血中に溶け込んだ薬は全身を巡ります。この動きをモデル化するのに、よく使われるのが「コンパートメントモデル」です。

  • 1コンパートメントモデル: 体を「均一な1つの箱」と見なす。薬は瞬時に全身に広がり、一定の速度で消えていく。
  • 2コンパートメントモデル: 体を「中心コンパートメント(血液やよく灌流する臓器)」と「末端コンパートメント(脂肪や筋肉など)」の2つに分ける。最初に中心から末端へ薬が移行する「分布相」が見られる。

この違い、実は抗がん剤の投与設計でめちゃくちゃ重要なんです。例えばパクリタキセル(抗がん剤)は2コンパートメント動態を示し、投与直後に急激に血中濃度が下がる「分布相」があります。この相を無視して投与計画を立てると、効果が出なかったり毒性が出たりするんですね。


ざっくり本質:たとえ話で直感を作る

薬物動態を理解する一番簡単なたとえは「浴槽の水」です。

「薬を投与する = 浴槽に水を注ぐ。薬が消える = 排水口から水が抜ける。分布容積 = 浴槽の大きさ」

  • 静注ボーラス: 一気にバケツの水を浴槽に投げ入れる。水位が一瞬で上がり、その後排水口から一定の割合で減っていく。
  • 経口投与: 蛇口から少しずつ水を入れながら、同時に排水もされる。水位がゆっくり上がり、ピークを迎えた後、徐々に下がる。
  • 2コンパートメント: 浴槽が2つつながっているイメージ。最初にメインの浴槽に水を入れ、それが隣の浴槽に移っていく。メインの水位は急激に下がるが、隣から戻ってくる水もある。

一言でまとめると: 「薬物動態は、『分布』と『消失』という2つのプロセスのバランスで決まる」


数式で理解する

ここからが本番です。シミュレーターの計算ロジックを数式で理解しましょう。

1コンパートメントモデル(静注ボーラス)

最もシンプルなケース。薬を一気に静脈注射した後の血中濃度 $C(t)$ は次の式で表されます。

C(t) = C_0 \cdot e^{-k_{el} \cdot t}

ここで:

  • $C_0$: 初期血中濃度(投与量 $D$ を分布容積 $V_d$ で割った値: $C_0 = D / V_d$)
  • $k_{el}$: 消失速度定数(単位時間あたりに薬が消える割合)
  • $t$: 時間

つまり、指数関数的に減少していくわけです。

1コンパートメントモデル(経口投与)

経口の場合は「吸収」というプロセスが加わります。

C(t) = \frac{F \cdot D \cdot k_a}{V_d \cdot (k_a - k_{el})} \cdot (e^{-k_{el} \cdot t} - e^{-k_a \cdot t})

ここで:

  • $F$: バイオアベイラビリティ(経口でどれだけ血中に入るかの割合)
  • $k_a$: 吸収速度定数

この式のポイントは、 $(e^{-k_{el} \cdot t} - e^{-k_a \cdot t})$ の部分。吸収が速く、消失が遅いほど、この差は大きくなり、血中濃度のピークが高くなります。

2コンパートメントモデル(静注ボーラス)

2コンパートメントになると式は少し複雑に。

C(t) = A \cdot e^{-\alpha \cdot t} + B \cdot e^{-\beta \cdot t}

ここで:

  • $\alpha$: 分布相の速度定数(速い)
  • $\beta$: 消失相の速度定数(遅い)
  • $A$, $B$: 各相の切片(初期濃度に関係)

この式は、2つの指数関数の和で表されます。最初は $\alpha$ の項が支配的で急激に下がり、その後 $\beta$ の項が支配的になってゆっくり下がる。これが「分布相」と「消失相」の正体です。

重要な関係式:半減期

半減期 $t_{1/2}$ は、血中濃度が半分になるまでの時間です。

t_{1/2} = \frac{0.693 \times V_d}{CL}

ここで $CL$ はクリアランス(単位時間あたりに薬を除去できる血漿の体積)。この式が示すのは、半減期は $V_d$ と $CL$ の両方に依存するということ。$V_d$ が大きい(薬が組織に広がる)か、$CL$ が小さい(腎臓や肝臓の機能が低下)と、半減期は長くなります。


コードで実装する ★最重要★

それでは、シミュレーターの計算ロジックをJavaScriptで実装してみましょう。ブラウザ上でそのまま動くコードです。

/**
 * 薬物動態シミュレーター コア計算エンジン
 * 1コンパートメント・2コンパートメントモデル対応
 */
class PharmacokineticsSimulator {
    /**
     * 血中濃度を計算するメイン関数
     * @param {Object} params - パラメータ
     * @param {string} params.model - '1comp_iv' | '1comp_oral' | '2comp_iv'
     * @param {number} params.dose - 投与量 (mg)
     * @param {number} params.vd - 分布容積 (L)
     * @param {number} params.cl - クリアランス (L/h)
     * @param {number} params.ka - 吸収速度定数 (1/h, 経口のみ)
     * @param {number} params.f - バイオアベイラビリティ (経口のみ)
     * @param {number} params.alpha - 分布相速度定数 (1/h, 2-コンパートメント)
     * @param {number} params.beta - 消失相速度定数 (1/h, 2-コンパートメント)
     * @param {number} params.a - A係数 (mg/L, 2-コンパートメント)
     * @param {number} params.b - B係数 (mg/L, 2-コンパートメント)
     * @param {number} params.tau - 投与間隔 (h)
     * @param {number} params.numDoses - 投与回数
     * @param {number} params.timePoints - 計算する時点数
     * @returns {Array} [{time, concentration}]
     */
    static calculate(params) {
        const { model, dose, vd, cl, ka, f, alpha, beta, a, b, tau, numDoses, timePoints } = params;
        const kel = cl / vd; // 消失速度定数
        const results = [];
        const tMax = numDoses * tau;
        const dt = tMax / timePoints;
        
        for (let i = 0; i <= timePoints; i++) {
            const t = i * dt;
            let totalConc = 0;
            
            // 各投与の寄与を重ね合わせ
            for (let n = 0; n < numDoses; n++) {
                const tAdjusted = t - n * tau;
                if (tAdjusted <= 0) continue;
                
                let conc = 0;
                switch (model) {
                    case '1comp_iv':
                        // C(t) = (dose / vd) * exp(-kel * t)
                        conc = (dose / vd) * Math.exp(-kel * tAdjusted);
                        break;
                        
                    case '1comp_oral':
                        // C(t) = (F * dose * ka) / (vd * (ka - kel)) * (exp(-kel*t) - exp(-ka*t))
                        if (Math.abs(ka - kel) > 1e-10) {
                            conc = (f * dose * ka) / (vd * (ka - kel)) * 
                                   (Math.exp(-kel * tAdjusted) - Math.exp(-ka * tAdjusted));
                        }
                        break;
                        
                    case '2comp_iv':
                        // C(t) = A * exp(-alpha * t) + B * exp(-beta * t)
                        conc = a * Math.exp(-alpha * tAdjusted) + b * Math.exp(-beta * tAdjusted);
                        break;
                }
                totalConc += conc;
            }
            
            results.push({
                time: Math.round(t * 100) / 100,
                concentration: Math.round(totalConc * 1000) / 1000
            });
        }
        return results;
    }
    
    /**
     * 薬物動態パラメータを計算
     */
    static calculatePK(params, concentrationData) {
        const { model, dose, vd, cl, ka, f, alpha, beta, a, b, tau, numDoses } = params;
        const kel = cl / vd;
        
        // 半減期 (t1/2 = 0.693 * Vd / CL)
        const halfLife = (0.693 * vd) / cl;
        
        // Cmax, Tmax, AUCを計算
        let cmax = 0, tmax = 0, auc = 0;
        for (let i = 1; i < concentrationData.length; i++) {
            const prev = concentrationData[i - 1];
            const curr = concentrationData[i];
            
            // Cmax/Tmax
            if (curr.concentration > cmax) {
                cmax = curr.concentration;
                tmax = curr.time;
            }
            
            // AUC (台形則)
            const dt = curr.time - prev.time;
            auc += (prev.concentration + curr.concentration) * dt / 2;
        }
        
        // 定常状態の予測(反復投与の定常状態濃度)
        const css = (model === '1comp_iv') 
            ? (dose / vd) / (1 - Math.exp(-kel * tau))
            : null;
        
        return {
            halfLife: Math.round(halfLife * 100) / 100,
            cmax: Math.round(cmax * 100) / 100,
            tmax: Math.round(tmax * 100) / 100,
            auc: Math.round(auc * 100) / 100,
            css: css ? Math.round(css * 100) / 100 : 'N/A'
        };
    }
}

// 使用例: 1コンパートメント静注、繰り返し投与
const params = {
    model: '1comp_iv',
    dose: 500,      // 500 mg
    vd: 50,         // 50 L
    cl: 5,          // 5 L/h
    ka: 0,          // 経口ではないので不要
    f: 0,           // 経口ではないので不要
    alpha: 0, beta: 0, a: 0, b: 0,  // 2-コンパートメントではないので不要
    tau: 8,         // 8時間ごと
    numDoses: 5,    // 5回投与
    timePoints: 500 // 計算点
};

const data = PharmacokineticsSimulator.calculate(params);
const pkParams = PharmacokineticsSimulator.calculatePK(params, data);

console.log('投与スケジュール: 500mgを8時間ごと×5回');
console.log(`半減期: ${pkParams.halfLife} 時間`);
console.log(`Cmax: ${pkParams.cmax} mg/L`);
console.log(`Tmax: ${pkParams.tmax} 時間`);
console.log(`AUC: ${pkParams.auc} mg·h/L`);
console.log(`定常状態予測濃度: ${pkParams.css} mg/L`);

このコードのポイントは 「重ね合わせの原理」 です。複数回投与の場合、各投与による血中濃度を独立に計算し、それらを足し合わせることで全体の濃度を求めています。実際のシミュレーターも同じロジックで動いています。


数値例で確かめる

それでは、実際の数値を入れて計算してみましょう。

ケース: 抗生物質「セファゾリン」500mgを8時間ごとに静注(1コンパートメントモデル)

  • 分布容積 $V_d = 10$ L(実際のセファゾリンの値に近い)
  • クリアランス $CL = 4$ L/h

計算:

  1. 消失速度定数: $k_{el} = CL / V_d = 4 / 10 = 0.4$ /h
  2. 半減期: $t_{1/2} = 0.693 \times 10 / 4 = 1.73$ 時間
  3. 初回投与後の初期濃度: $C_0 = 500 / 10 = 50$ mg/L
  4. 1回目のピーク(投与直後): 50 mg/L
  5. 1回目のトラフ(8時間後): $50 \times e^{-0.4 \times 8} = 50 \times e^{-3.2} = 50 \times 0.0408 = 2.04$ mg/L
  6. 2回目投与前の濃度が2.04 mg/Lなので、2回目投与後のピークは $50 + 2.04 = 52.04$ mg/L

この計算をコードで実行すると:

投与スケジュール: 500mgを8時間ごと×5回
半減期: 1.73 時間
Cmax: 52.08 mg/L (5回目の投与後)
Tmax: 32 時間 (5回目の投与時刻)
AUC: 1125.00 mg·h/L
定常状態予測濃度: 52.08 mg/L

注目すべき点: 5回目の投与でCmaxが52.08 mg/Lと、初回の50 mg/Lからわずか4%しか増えていません。これは半減期が1.73時間と短いため、投与間隔(8時間)が半減期の約4.6倍あり、各投与の間にほとんどの薬が消えてしまうからです。もし半減期が24時間のような薬なら、定常状態に達するまでに山がどんどん高くなっていきます。


シミュレーターで遊ぶ(実験3選)

実際のシミュレーターでパラメータを変えて遊んでみましょう。

実験1: 1コンパートメント vs 2コンパートメント

設定:

  • 投与モデル: 1コンパートメント 静注 → 2コンパートメント 静注 に切り替え
  • 投与量: 500mg
  • 分布容積: 50L
  • クリアランス: 5L/h
  • 投与間隔: 8h、投与回数: 5回

結果:

  • 1コンパートメント: 滑らかな指数関数的減少。投与直後がピーク。
  • 2コンパートメント: 投与直後に急激に下がる「分布相」が見える。その後、緩やかな「消失相」に移行。

なぜ?: 2コンパートメントでは、薬が中心コンパートメントから末端コンパートメント(脂肪や筋肉)に移行する「分布」が起こるため、最初の濃度低下が速い。抗がん剤や麻酔薬のように、組織への移行が重要な薬ではこのモデルが使われます。

実験2: 治療ウィンドウの可視化

設定:

  • 1コンパートメント 経口
  • 投与量: 250mg、分布容積: 50L、クリアランス: 3L/h
  • 吸収速度定数: 1.0 /h、バイオアベイラビリティ: 0.8
  • MEC(最小有効濃度): 2 mg/L、MSC(最大安全濃度): 8 mg/L
  • 投与間隔: 12h、投与回数: 3回

結果: グラフに色のついた帯(治療ウィンドウ)が表示される。2回目以降のトラフ濃度がMEC(2 mg/L)を下回っていることがわかる。

実務での活用: てんかん治療薬のフェニトインは治療ウィンドウが非常に狭く(10-20 µg/mL)、この範囲を外れると効果不十分か毒性が出る。シミュレーターで投与量や間隔を調整し、常にウィンドウ内に収まる設計を行う。

実験3: 半減期と定常状態の関係

設定:

  • 1コンパートメント 静注
  • 投与量: 100mg、分布容積: 20L
  • クリアランス: 2L/h(半減期: 6.93h)→ 4L/h(半減期: 3.47h)に変更
  • 投与間隔: 8h、投与回数: 10回

結果:

  • CL=2L/hの場合: 半減期が長いため、定常状態に達するまでに5〜6回の投与が必要。
  • CL=4L/hの場合: 半減期が短いため、3〜4回で定常状態に近づく。

実務でのポイント: 「半減期の4〜5倍の時間で定常状態」という経験則が確認できる。腎機能が低下した患者(CLが小さい)では、定常状態に達するまでに時間がかかり、初期の投与設計に注意が必要。


現場でハマるポイント(適用限界・落とし穴)

1. 「分布容積は物理的な体積じゃない」

新人の薬剤師がよく混乱するのがこれ。$V_d$が500Lと出ると「そんな大きな体積はない!」とパニックになります。

実際: 脂溶性の高い薬(例:ジゴキシン)は組織に大量に取り込まれるため、見かけ上の分布容積が500Lを超えることがあります。これは「血液中の濃度に対して、どれだけの量の薬が体内に存在するか」を表す指標であり、実際の体積ではありません。

2. パラメータの連動性を見落とすな

$CL$と$t_{1/2}$は独立じゃないんです。関係式は:

t_{1/2} = \frac{0.693 \times V_d}{CL}

つまり、$V_d$が2倍になれば、$CL$が同じでも半減期は2倍になります。患者に浮腫(むくみ)があると$V_d$が増加し、半減期が延長するケースはよくあります。

3. 「モデルは現実の近似でしかない」

シミュレーターは便利ですが、あくまで近似です。特に経口投与の「吸収速度定数 $k_a$」は一定と仮定していますが、実際には胃の内容物や他の薬の影響で変わります。

実務では: シミュレーション結果を「傾向を見るための一指標」と捉え、実際のTDM(治療薬物モニタリング)データと照合することが必須です。特にICU患者など、病態が急変するケースでは、シミュレーションだけに頼るのは危険です。


まとめ

  1. 薬物動態は「分布」と「消失」の2つのプロセスで理解できる。1コンパートメントは単純な指数減少、2コンパートメントは分布相と消失相が現れる。

  2. 半減期は $V_d$ と $CL$ の両方に依存する。患者の状態(浮腫、腎機能低下など)でこれらの値が変わることを常に意識する。

  3. シミュレーションは「傾向を見る道具」。治療ウィンドウの確認や投与スケジュールの事前検討には便利だが、必ず実測値と照合する。

実際に手を動かして試してみたい方は、こちらからどうぞ。

▶ 薬物動態シミュレーター(1/2コンパートメントモデル) — ブラウザで即動作、登録不要

NovaSolverでは1,600以上の工学シミュレーターを無料公開中 👉 一覧はこちら

「薬が体内でどう動くか」を可視化できるツールは、実務での投与設計はもちろん、薬理学の学習にも強力な武器になります。ぜひ一度、パラメータをいじりながら遊んでみてください。きっと新しい発見があるはずです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?