ニボルマブの公表レジメンには、240 mgを2週ごと、480 mgを4週ごとに投与する方式があります[1]。
1日あたりの投与量は、どちらも約17.1 mg。同じ濃度曲線になるのでしょうか。公開PopPKモデルをPythonで計算してみます。
図で見る
青は240 mgを2週ごと、破線は480 mgを4週ごとです。4週投与では、一度に入る量が多いため山が高くなり、次の投与まで長く待つため谷が低くなります。
数字で比べる
以下は今回の計算値です。単位はmg/Lで、µg/mLと同じ数値になります。
| 投与方式 | 28日間の平均濃度 | 同期間の最高濃度 | 最終日の投与直前濃度 |
|---|---|---|---|
| 240 mg・2週ごと | 101.9 | 147.2 | 81.4 |
| 480 mg・4週ごと | 101.9 | 199.0 | 67.2 |
平均濃度はほぼ同じですが、最高濃度は約35%高く、最終日の投与直前濃度は約17%低くなりました。
線形のPKで、薬の消失速度がほぼ落ち着いた時期では、1日あたりの投与量が同じなら平均濃度も近くなります。それでも、平均が同じことと、山や谷が同じことは別です。
何を計算したか
BajajらのPopPKモデル[2]の基準条件(80 kg、女性、eGFR 90、PS 0、白人)を使いました。個人間のばらつきと測定誤差は加えていません。集団の平均曲線でも、実測患者の結果でもなく、基準条件での一本の予測曲線です。
投与は日0から始め、各回30分の点滴としました。比較期間は日364〜392の28日間です。時刻に応じて薬の消失速度が変わる原モデルの式を残し、初回投与時の消失速度へ固定していません。厳密な定常状態と同一とは扱いません。
元の研究では集団を使った曝露比較も行われています[1]。今回の小さな計算は、そこで報告された集団の数値を再現する解析ではありません。
再計算用コード
Python 3.12、NumPy 1.26.4、SciPy 1.14.0、Matplotlib 3.9.1で実行しました。コードをsimulate.pyとして保存し、python simulate.pyで図と数値を生成できます。実装を見たい場合だけ、以下を開いてください。
Pythonコードを表示
"""Typical-reference simulation of the Bajaj 2017 nivolumab PopPK model."""
from pathlib import Path
import json
import numpy as np
from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt
ROOT = Path(__file__).resolve().parent
START, END = 364.0, 392.0
V1, V2, Q = 3.63, 2.78, 32.1 * 24 / 1000
def clearance(day):
hour = day * 24
return 9.4 * 24 / 1000 * np.exp(-0.295 * hour**3.15 / (1410**3.15 + hour**3.15))
def simulate(dose, interval, duration=0.5 / 24, rtol=1e-9):
state = np.zeros(4) # central, peripheral, cumulative AUC, eliminated amount
times, states = [0.0], [state.copy()]
for day in np.arange(0.0, END, interval):
for left, right, rate in [(day, day + duration, dose / duration),
(day + duration, min(day + interval, END), 0.0)]:
def rhs(t, y):
c1, c2 = y[0] / V1, y[1] / V2
cl = clearance(t)
return [rate - cl*c1 - Q*(c1-c2), Q*(c1-c2), c1, cl*c1]
solution = solve_ivp(rhs, (left, right), state, rtol=rtol, atol=1e-10,
t_eval=np.linspace(left, right, 121), max_step=1)
if not solution.success:
raise RuntimeError(solution.message)
state = solution.y[:, -1]
times.extend(solution.t[1:])
states.extend(solution.y.T[1:])
t, y = np.array(times), np.array(states)
window = t >= START
auc_start = np.interp(START, t, y[:, 2])
summary = dict(dose_mg=dose, interval_day=interval,
cavg=float((y[-1, 2]-auc_start)/(END-START)),
cmax=float(np.max(y[window, 0]/V1)),
predose=float(y[-1, 0]/V1))
return t, y, summary
def main():
results, curves = [], []
for dose, interval in [(240, 14), (480, 28)]:
t, y, result = simulate(dose, interval)
results.append(result)
curves.append((t, y))
ratio = {key: results[1][key]/results[0][key] for key in ['cavg', 'cmax', 'predose']}
(ROOT/'results').mkdir(exist_ok=True)
(ROOT/'figures').mkdir(exist_ok=True)
report = dict(window_day=[START, END], typical_reference=True,
interindividual_and_residual_variation=False, results=results, ratios=ratio)
(ROOT/'results'/'summary.json').write_text(json.dumps(report, indent=2), encoding='utf-8')
plt.rcParams.update({'font.size': 12, 'axes.spines.top': False, 'axes.spines.right': False})
fig, ax = plt.subplots(figsize=(8, 4.8), layout='constrained')
for (t, y), label, color, style in zip(curves, ['240 mg every 2 weeks', '480 mg every 4 weeks'],
['#0072B2', '#D55E00'], ['-', '--']):
window = t >= START
ax.plot(t[window]-START, y[window, 0]/V1, label=label, color=color, ls=style, lw=2)
ax.set(xlim=(0, 28), ylim=(0, None), xlabel='Days from treatment day 364',
ylabel='Serum concentration (mg/L)')
ax.set_title('Nivolumab: two dosing intervals', pad=30, fontsize=14, loc='left')
ax.text(0, 1.02, 'One reference profile; days 364–392; 30-minute infusions',
transform=ax.transAxes, fontsize=10)
ax.legend(frameon=False, loc='upper right', fontsize=10)
ax.grid(axis='y', color='#dddddd', lw=0.6)
fig.savefig(ROOT/'figures'/'nivolumab-interval.png', dpi=180)
print(json.dumps(report, indent=2))
if __name__ == '__main__':
main()
この図から言えること
投与方式を比べるときは、平均濃度だけでなく、最高濃度と投与直前濃度も見ると違いが分かります。
ただし、この図だけでは効果や安全性の差は分かりません。 今回は濃度を比べる学習用の計算であり、患者の投与量や間隔を決めるためのものではありません。
参考文献
- Long GV, et al. Assessment of nivolumab exposure and clinical safety of 480 mg every 4 weeks flat-dosing schedule in patients with cancer. Annals of Oncology. 2018. doi:10.1093/annonc/mdy408
- Bajaj G, et al. Model-Based Population Pharmacokinetic Analysis of Nivolumab in Patients With Solid Tumors. CPT: Pharmacometrics & Systems Pharmacology. 2017. doi:10.1002/psp4.12143
