「え、薬って体内でこんな動きしてるの?」
そう思った方、多いんじゃないでしょうか。私も初めて薬物動態のシミュレーターを触った時、血中濃度のグラフがジグザグに上下しながら、だんだん安定していく様子を見て「これ、現実の体内で起きてるんだ…」と衝撃を受けました。
今回は、薬物動態シミュレーター(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
計算:
- 消失速度定数: $k_{el} = CL / V_d = 4 / 10 = 0.4$ /h
- 半減期: $t_{1/2} = 0.693 \times 10 / 4 = 1.73$ 時間
- 初回投与後の初期濃度: $C_0 = 500 / 10 = 50$ mg/L
- 1回目のピーク(投与直後): 50 mg/L
- 1回目のトラフ(8時間後): $50 \times e^{-0.4 \times 8} = 50 \times e^{-3.2} = 50 \times 0.0408 = 2.04$ mg/L
- 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患者など、病態が急変するケースでは、シミュレーションだけに頼るのは危険です。
まとめ
-
薬物動態は「分布」と「消失」の2つのプロセスで理解できる。1コンパートメントは単純な指数減少、2コンパートメントは分布相と消失相が現れる。
-
半減期は $V_d$ と $CL$ の両方に依存する。患者の状態(浮腫、腎機能低下など)でこれらの値が変わることを常に意識する。
-
シミュレーションは「傾向を見る道具」。治療ウィンドウの確認や投与スケジュールの事前検討には便利だが、必ず実測値と照合する。
実際に手を動かして試してみたい方は、こちらからどうぞ。
▶ 薬物動態シミュレーター(1/2コンパートメントモデル) — ブラウザで即動作、登録不要
NovaSolverでは1,600以上の工学シミュレーターを無料公開中 👉 一覧はこちら
「薬が体内でどう動くか」を可視化できるツールは、実務での投与設計はもちろん、薬理学の学習にも強力な武器になります。ぜひ一度、パラメータをいじりながら遊んでみてください。きっと新しい発見があるはずです。