2025年6月27日金曜日

抄録登録

 抄録を書いていた。

いや、正確には「抄録を送る準備をしていた」と言った方がいい。

ワードを開いては閉じ、また開いては別のファイルに寄り道する。そんな日々が続いていた。何も生み出さない時間が、画面の奥で静かに膨張していくようだった。

最初の一文が書けたのは、夜の書類整理がひと段落してからだった。いつもならNOBANACLINIC labo動画を創りだすところだったが、思いとどまった。そして、抄録を書き出した。締め切りが近いのだ。

「IL-6阻害薬導入患者におけるLDL-Cの変化について」

もうそれ以上、余計な言葉はいらなかった。

そこからは、手が勝手に動いた。データを並べ、数字を整え、統計処理の跡を踏み直すように、文を削ぎ落としていった。気づけばWordの文字カウントが「605文字」を指していた。日本語500文字以内、まだだ。もう少し、もう少しそぎ落とす。

それは、なにか小さな祈りのようにも見えた。

そして、朝。

学会の登録フォームにログインし、必要事項を淡々と入力し、「送信」ボタンを押した。あっけないほど軽やかなクリック音がした。

それだけのことだった。だけど、その一瞬に、幾夜もの葛藤と、何杯ものコーヒーと、机の上の散らかったポストイットたちが、すべて吸い込まれていった。

提出完了のメールを受信トレイで見つけたとき、思わず笑ってしまった。小さく、だれにも聞こえないくらいに。

あとは、待つだけだ。採択されるかどうかは、もう僕の手の中にはない。

でも、送ったことは事実だ。送れたことが、今はただ、嬉しい。

身体が軽い。

2025年6月25日水曜日

推測統計(Script ナグリガキ)

 サクサクとメインの表を作っていく作業はダイナミックで楽しいところ

まずはLDLの変化量をありのまま出してみる 対応のあるt検定

> with(Dataset, (t.test(LDL0, LDL3, alternative='two.sided', conf.level=.95, paired=TRUE)))


Paired t-test


data:  LDL0 and LDL3

t = -2.748, df = 12, p-value = 0.01767

alternative hypothesis: true mean difference is not equal to 0

95 percent confidence interval:

 -29.789220  -3.441549

sample estimates:

mean difference 

      -16.61538


Paired t-test

P=0.01767 よし、とりあえず差はありそうだ。

いや、新しい変数をつくってみよう 3か月でのLDL上昇

Dataset$LDL_diff <- with(Dataset, LDL3- LDL0)

ヒストグラムをつくってみよう。

with(Dataset, Hist(LDL_diff, scale="frequency", breaks="Sturges", col="darkgray"))



併用ステロイドの減量によってならLDLは下がるはずだが上がっているな。

交絡と考えているPSL、CRPの変化も変数として作成。

Dataset$PSL_diff <- with(Dataset, PSL3- PSL0)
Dataset$CRP_diff <- with(Dataset, CRP3- CRP0)

PSLの変化量を箱ひげ図にしてみよう。

Boxplot( ~ PSL_diff, data=Dataset, id=list(method="y"))

回帰分析してみようとしたらIL6阻害薬が認識されていない。

IL6阻害薬をカテゴリカル変数に指定。

editDataset(Dataset)
Dataset <- within(Dataset, {
  IL6 <- as.factor(IL6)
})

うまくいかない。ダミー変数をつくろう。TCZ、SARをデータセットに直接編集して追加。

そもそもモデルの作り方が間違っているな。

LDLの変化量=IL6阻害薬の種類+CRP変化量+PSL変化量

これじゃ、IL6阻害薬の種類の比較になってしまうので、ダミー変数を使おうがそこにはほとんど差がないという結果しかでないよな。

さて、ではどのようにしよう。岡山大学の津田先生から多変量解析の出発点は層別分析だ。丁寧に解析してみなさい。そう言われたことを思い出した。

PSL使用例8例と未使用例5例に分けてまずLDL変化量を解析しなおしてみよう。

> numSummary(Dataset[,"LDL_diff", drop=FALSE], groups=Dataset$PSLumu, statistics=c("mean", "sd", "IQR", "quantiles"), quantiles=c(0,

+   .25,.5,.75,1))

      mean       sd  IQR  0%   25% 50%   75% 100% LDL_diff:n

ari  15.25 22.35269 36.5 -17 -4.75  25 31.75   39          8

nasi 18.80 23.27445 21.0  -3  2.00  16 23.00   56          5

とりあえずやはりPSLがない症例のほうがLDL上昇は高そうにみえる。これはPSL併用症例はPSL減量によりLDL低下効果がありそうにみえる。とりあえず定性的に評価してみる。

> t.test(LDL_diff~PSLumu, alternative='two.sided', conf.level=.95, var.equal=FALSE, data=Dataset)


Welch Two Sample t-test


data:  LDL_diff by PSLumu

t = -0.27164, df = 8.3546, p-value = 0.7925

alternative hypothesis: true difference in means between group ari and group nasi is not equal to 0

95 percent confidence interval:

 -33.46568  26.36568

sample estimates:

 mean in group ari mean in group nasi 

             15.25              18.80 

統計的には有意差ないが、とりあえずこれを箱ひげ図で比較
> Boxplot(LDL_diff ~ PSLumu, data=Dataset, id=list(method="y"))
他にCRPでの層別もしたいから、開始前CRPの分布も確認しておこう。

> with(Dataset, Hist(CRP0, scale="frequency", breaks="Sturges", col="darkgray"))

意外と開始前CRPは低めに偏っていることがわかる。要約。
> numSummary(Dataset[,"CRP0", drop=FALSE], statistics=c("mean", "sd", "IQR", "quantiles"), quantiles=c(0,.25,.5,.75,1))
     mean      sd  IQR   0%  25% 50% 75%  100%  n
 1.736154 3.42934 2.46 0.01 0.04 0.1 2.5 12.49 13

CRPを2層に分離、中央値の0.1でわけます。
> Dataset$CRPsou <- with(Dataset, ifelse(CRP0 >= 0.1, "0.1以上", "0.1未満")
+ )

さてLDLの解析です。
> t.test(LDL_diff~CRPsou, alternative='two.sided', conf.level=.95, var.equal=FALSE, data=Dataset)

Welch Two Sample t-test

data:  LDL_diff by CRPsou
t = -0.49162, df = 10.526, p-value = 0.6331
alternative hypothesis: true difference in means between group 0.1以上 and group 0.1未満 is not equal to 0
95 percent confidence interval:
 -32.87932  20.92693
sample estimates:
mean in group 0.1以上 mean in group 0.1未満 
             13.85714              19.83333 

箱ひげ図で比較
> Boxplot(LDL_diff ~ CRPsou, data=Dataset, id=list(method="y"))

こうみるとCRPの層でわけて解析すると平均は差があるが、分散が大きいだけで中央値は同じくらいなのだ。
CRPはPSLとの関係もあるので結果の解釈はとても複雑怪奇だ。
もう少し数が増えればさらに層を増やしてみることができるのだが。
PSL未使用でCRPが0.1未満の症例はどれだけいるだろう。
一応3症例いる。一応この3症例でLDL変化量をみてみよう。理論上はこれで炎症やPSLによる影響を排することができる。

とりあえず手動でデータセットをいじってみる。まず今までのデータセットを保存。
> save("Dataset", file="C:/Users/Owner/OneDrive/デスクトップ/Lipid paradox/Dataset20250625.RData")

もとデータのEXCELで3症例を限定して再度データセット取り込み、LDL 変化量の変数作成
それぞれ-3、16、2。ばらつきがすごい。
そして、要約。
> numSummary(nasinasi[,"LDLDif", drop=FALSE], statistics=c("mean", "sd", "IQR", "quantiles"), quantiles=c(0,.25,.5,.75,1))
 mean       sd IQR 0%  25% 50% 75% 100% n
    5 9.848858 9.5 -3 -0.5   2   9   16 3
3症例の要約に意味があるかまったくわからない。いやまったくない。
いちおう検定。
> with(nasinasi, (t.test(LDL0, LDL3, alternative='two.sided', conf.level=.95, paired=TRUE)))

Paired t-test

data:  LDL0 and LDL3
t = -0.87932, df = 2, p-value = 0.472
alternative hypothesis: true mean difference is not equal to 0
95 percent confidence interval:
 -29.46592  19.46592
sample estimates:
mean difference 
             -5 

やはり有意差なし。これはさすがに数の問題だろう。

さて、そろそろ一旦終わるか。LDLに関しては様々なことが影響しているが、少なくともIL6阻害薬使用によって、PSLが減ろうがCRPが陰性だろうが、上昇する方向であることに間違いはないだろう。そろそろ材料は揃ってきた。だんだん抄録を書いていかないと締め切りに間に合わなくなるぞ。

2025年6月22日日曜日

患者背景を眺める

データの森に迷い込んだ。年齢、性別、血液検査の数値。薬の種類、併用薬剤とその用量。人の数だけ物語があり、数字の数だけ、暮らしがにじむ。

僕たちが「患者背景」と呼んでいるものは、決してただの表やリストではない。むしろそれは、出会ってきた人たちの時間の積み重ねでできた、静かな年輪のようなものだ。

『Epidemiology: An Introduction』(Kenneth J. Rothman著)の第1版・第2版いずれでも、患者背景の要約(descriptive statistics / descriptive epidemiology)については以下のように記載してある。

「研究対象者の特徴を記述することは、結果の適用可能性を理解するためだけでなく、バイアスや交絡の可能性を評価するうえでも不可欠である」

かみ砕けば、「だれを対象にしたかってことは、研究の“顔”みたいなもので、それをちゃんと見てないと、あとで迷子になるよ」ということだと思う。

たとえば、ある薬の効果を調べるとき。

年齢が高めの人ばかりに使っていたら、その薬の印象も年齢と一緒に変わって見えてしまうかもしれない。ACPA陽性の人ばかりだったら、それはそれで偏った物語になるかもしれない。そういうとき、数字の中に目をこらす。平均、中央値、分散、四分位範囲。バラバラに見える人たちの横顔を、少しずつ立体にしていく。数字は、人を測るものじゃない。けれど、数字に宿る「ひと気(け)」を感じることはできる。そこには生活があり、痛みがあり、選択がある。「この人たちに、薬はどう届いたか」その問いの前には、「この人たちは、どんな時間を生きてきたのか」という問いが、必ず先にある。

患者背景をまとめるというのは、つまり、そういう「前のめりな敬意」のかたちなのかもしれない。データという森の中に、一本ずつ木の名前をつけていくような。研究という旅路の最初に、地図を描くような。今日もまた、EXCELとRを開きながら、そんなことを思う。

さて、患者背景もどうやってまとめるんだっけな。そうそう、そんな時は丁寧に大学院時代に作成した自分の論文を見返すわけだ。やっぱり、ひとめで文章から10年以上前のことが鮮明に浮かび上がってくる。本気で向き合った時間は宝物以外の何物でもない。

 【2025年臨床リウマチ学会総会へ向けて-18】

2025年6月17日火曜日

あの日閉じたソフトが、また口をひらく

 

カチカチと、古い錠前を開けるような気分だった。

久しぶりに統計ソフトを起動しようとして、まず気づいたのは、手元のPCにRが入っていないということだった。

思えばここ数年、それが必要な場面は少なかった。


クリニックを開いてから、僕の作業の多くは症例報告だった。

ひとりの患者さんの物語を、丁寧に拾い上げて、ページの上に並べていくような作業。あるいは、複数のケースを組み合わせて共通項を見出す、小さな連作短編のようなケースシリーズ。


そんななかで、統計という名の道具は、あまりに大きく、そして鋭すぎることがあった。

統計処理をすれば、たしかに「有意」とか「傾向」とかいう言葉が手に入る。

でも逆に、人の顔をした細部や、わずかなゆらぎは、その数式の影にかくれてしまう。


だから僕は、あえて統計処理を避けてきた。

定規で世界を測るよりも、手でなぞる曲線のほうが、患者さんの実感に近い気がしていたから。


でも、今回は少しちがう。

数がある。ばらつきがある。仮説がある。そして、答えが遠い。

ならばやはり、定規を手に取る必要があるだろう。


Rのインストールを終え、最初に手をつけたのは、Excelで用意したデータの読み込みだった。

ここで、思わぬ落とし穴に足を取られる。


変数名の上に、「開始時」や「3か月後」といった分類の行を足していたのだ。

見た目には整っていたけれど、Rにはそれが「2行のヘッダー」として読み込まれてしまう。

当然、うまくいかない。読み込んだはずの変数が、謎のNAとして並ぶ。


やれやれ、と思いながら、僕はExcelに戻る。

行を削除し、変数名を修正する。

「CRP」のような項目には「CRP0」や「CRP3」と番号をつけることにした。

0が開始時、3が3か月後という意味だ。地味な工夫だけれど、こうしておけばRは迷わない。

人にやさしい形式は、意外とソフトには厳しい。


その後、僕はRの「パッケージ」という概念を思い出す。

Rは本体だけでは最低限の機能しか持っていない。

グラフを描いたり、統計処理をしたり、フロー図を作ったり——それらはすべて「パッケージ」という形で追加される。

そして、使いたいパッケージを「読み込む」のが、library()という命令だ。


たとえば、グラフを描くための ggplot2、データ加工の dplyr、統計処理をGUIで操作できる Rcmdr、

そして今回使った、フロー図を描くための DiagrammeR も、すべて道具箱のようなパッケージたち。


僕ははじめて DiagrammeR を使って、患者フローを描いてみた。

これまではPowerPointで矢印を引いて、テキストボックスを並べて、文字を揃えて……と、手作業に神経を使っていた。

けれど今回、Rでフロー図のコードを書いてみて驚いた。


graph TD

  A[IL-6阻害薬使用症例 89人] --> B[RA以外の基礎疾患 4人除外]

  B --> C[転院症例 30人除外]

  C --> D[First bioでない症例 40人除外]

  D --> E[3か月未満で終了 2人除外]

  E --> F[解析対象症例 13人]


このわずかなコードで、すっと1本の流れが描かれた。

図はきれいで、矢印は迷いがなく、書き直すのも一瞬。

なんでもっと早く知っておかなかったのか、と思いながら、それでも少し嬉しかった。


こうして、久しぶりにひらいた統計ソフトは、思っていたよりも柔らかく、そして開放的だった。

数字の向こうに流れる物語を、もう一度、描いていこうと思う。

【2025年臨床リウマチ学会総会へ向けて-17】

2025年6月13日金曜日

交絡因子×媒介変数○

データセット完成。


さて、IL6阻害薬の使用がどれだけLDLに変化を与えるかという命題に答えるには単純に

LDLの変化量=IL-6阻害薬使用3か月後のLDL値-使用前LDL値

で答えが出る気がします。

しかし、IL-6阻害薬だけが、LDLに変化を与えるのでしょうか?

そうではなさそうです。


例えば「傘と長靴」の話


ある小学校で、こんな観察がありました。

 傘を持ってくる子が多い日には、長靴を履いてくる子も多い。


これだけ聞くと、「傘を持つと長靴を履くようになるのかな?」と思ってしまいそうです。

でも実際は、どちらも「雨が降っているから」ですよね。

 雨の日 → 傘を持ってくる子が多い

 雨の日 → 長靴を履いてくる子も多い

この「雨」が、交絡因子です。

つまり、「傘」と「長靴」の関係に見えて、実はどちらも“雨”の影響を受けていただけなのです。


例えば「アイスと日焼け」の話


 アイスクリームを食べる人ほど、日焼けしている人が多い。


これも「アイスを食べると日焼けするのか!?」と思ってしまいそうですが、違います。

実際は、

 暑い日 → アイスを食べたくなる

 暑い日 → 外に出ることが多くなり、日焼けしやすくなる

つまり「暑い日」が交絡因子です。


一見すると、2つのことが直接つながっているように見える。

でも実は、共通の「原因」が背後にある。

その「見えにくい原因」のことを、交絡因子と呼びます。


さて、話は戻ると。

「IL-6阻害薬を使うとLDLはあがるのか?」

IL-6阻害薬を使う→炎症がおさまる→LDLがあがる

IL6阻害薬を使う→PSLが減る→LDLがさがる


おっと。これは媒介変数(中間因子)だな。。。いずれにしても直接効果の解析が目的だからPSL変化量を含めた回帰分析で補正すればよさそうだけれども。

今日はこのへんで。

【2025年臨床リウマチ学会総会へ向けて-16】

2025年6月11日水曜日

ピースを埋める

とても地味な作業だ。

ひとり終えては、椅子から腰を上げ、少し身体をひねる。

ひとり終えては、本のページをめくり、指先の乾きを感じる。


データセットをつくる。

この作業は、どこかパズルに似ている。


縦軸には患者の名もなきID。

横軸には、変数たちの沈黙。

それらの交点に、数字をひとつずつ埋めていく。

抗体の有無、罹病期間、ステロイドの量、LDL、CRP、…

そのひとつひとつが、誰かの時間の痕跡だ。


目を凝らし、過去の記録に触れながら、

空白のセルを埋めるたびに、わずかな充実が灯る。

数字はただの記号じゃない。

それは、診察室の沈黙の中で交わされた視線のひとつだ。


全体のちょうど半分が終わった。

まだ道のりは遠いけれど、

こうして少しずつ、見えない全体像の輪郭が浮かび上がってくる。


データという名のパズル。

ピースは静かに、しかし確実に、所定の場所へと嵌まりはじめている。


【2025年臨床リウマチ学会総会へ向けて-15】

「足りないものを、足りないままにしてはいけない」——副腎と関節の話

なんとなく、という言葉は不思議だ。 なんとなく疲れる、なんとなく食欲が出ない、なんとなく朝がつらい——そういう“なんとなく”の体調不良は、いつも言葉の後ろに小さく居座っていて、明確な病名を持たずにただ、そこにいる。 関節リウマチという病気は、名前だけは強そうだけれど、その実、地味...