## u-chartとは
u-chartは、発生率を時系列で監視するための管理図です。月ごとの患者数(分母)が変動しても、それに応じて管理限界の幅を自動で調整してくれます。
感染管理の文脈では「管理限界を超えた月があるかどうか」を視覚的に示すことができ、アウトブレイクの検出や、介入前後の比較に適しています。
u-chartは [[Stat - SPCと管理図の種類|SPC(Statistical Process Control)]] の一種です。
## 数式
u-chartの計算式はシンプルです。$c_i$ は月 $i$ の発生件数、$n_i$ は月 $i$ の患者数を表します。
### ベースライン期間の設定
中心線と管理限界は、ベースライン期間のデータから算出します。ベースライン期間とは「通常の状態」を代表する期間のことで、以下のような考え方で設定します。
- 介入の前後を比較したい場合は、介入前の期間をベースラインとする(例:監視培養を停止する前の1年間)
- アウトブレイクが疑われる期間はベースラインから除外する
- 季節変動がある場合は、12ヶ月以上の期間を含めることが望ましい
- 一般的には12〜24ヶ月程度が使われることが多いが、データの安定性に応じて判断する
ベースライン期間に異常値(アウトブレイク等)が含まれていると、中心線が実態よりも高くなり、本来検出すべき異常を見逃す原因になります。
### 中心線
中心線($\bar{u}$)は、ベースライン期間全体の平均発生率です。
$
\bar{u} = \frac{\sum c_i}{\sum n_i}
$
### 管理限界
各月の管理限界は以下のとおりです。
$
UCL_i = \bar{u} + 3\sqrt{\frac{\bar{u}}{n_i}}
$
$
LCL_i = \max\left(\bar{u} - 3\sqrt{\frac{\bar{u}}{n_i}},\ 0\right)
$
$3\sigma$(3シグマ)は正規分布で99.7%の範囲に相当し、これを超えた点は偶然の揺らぎでは説明しにくいと判断します。
### 具体例:3ヶ月分を個別に計算してみる
ベースライン期間の平均発生率 $\bar{u} = 0.0202$ として、3ヶ月分の管理限界と判定を順に計算します。
#### 4月:患者180人、MRSA 5件
$
UCL = 0.0202 + 3\sqrt{\frac{0.0202}{180}} = 0.0202 + 3 \times 0.01059 \approx 0.0520
$
$
LCL = 0.0202 - 3 \times 0.01059 \approx 0 \quad (\text{負になるので0とする})
$
発生率は $5 \div 180 = 0.0278$ です。UCL(0.0520)を下回っているので正常範囲内です。
#### 5月:患者245人、MRSA 4件
$
UCL = 0.0202 + 3\sqrt{\frac{0.0202}{245}} = 0.0202 + 3 \times 0.00908 \approx 0.0475
$
$
LCL = 0.0202 - 3 \times 0.00908 \approx 0
$
発生率は $4 \div 245 = 0.0163$ です。正常範囲内です。患者数が4月より多いためUCLが0.0520→0.0475と狭まっている点に注目してください。
#### 6月:患者160人、MRSA 9件
$
UCL = 0.0202 + 3\sqrt{\frac{0.0202}{160}} = 0.0202 + 3 \times 0.01124 \approx 0.0539
$
$
LCL = 0.0202 - 3 \times 0.01124 \approx 0
$
発生率は $9 \div 160 = 0.0563$ です。UCL(0.0539)を超えているため、偶然のばらつきでは説明しにくいと判断され、アウトブレイクの疑いと判定されます。
このように、患者数が少ない月ほどUCLの幅が広がり、患者数が多い月ほど狭まります。これが「分母が変動するデータ」にu-chartが適している理由です。
## サンプルデータ
ICUにおけるMRSA発生率の監視を例として取り上げます。3年間を以下の3期間に分け、期間Aをベースラインとして期間B・Cを評価します。
| 期間 | 時期 | 検査方針 |
|------|------|---------|
| A | 2022年4月〜2023年3月 | 全入室患者に監視培養を実施(ベースライン) |
| B | 2023年4月〜2024年3月 | 監視培養を停止 |
| C | 2024年4月〜2025年3月 | リスク因子のある患者のみ監視培養を実施 |
```r
rm(list = ls())
mrsa <- c(
# Period A
5, 4, 2, 6, 4, 5, 4, 2, 5, 4, 6, 4,
# Period B
4, 5, 6, 2, 4, 5, 4, 6, 4, 5, 4, 5,
# Period C
4, 2, 5, 4, 5, 4, 6, 4, 2, 5, 4, 4
)
patients <- c(
# Period A
180, 195, 160, 200, 185, 190, 175, 165, 195, 180, 205, 170,
# Period B
210, 225, 195, 230, 245, 215, 235, 200, 220, 210, 190, 225,
# Period C
220, 200, 230, 215, 240, 210, 225, 195, 205, 220, 215, 230
)
months <- c(
paste0("2022/", sprintf("%02d", 4:12)), paste0("2023/", sprintf("%02d", 1:3)),
paste0("2023/", sprintf("%02d", 4:12)), paste0("2024/", sprintf("%02d", 1:3)),
paste0("2024/", sprintf("%02d", 4:12)), paste0("2025/", sprintf("%02d", 1:3))
)
```
`mrsa` は月ごとのMRSA検出件数、`patients` は月ごとのICU入院患者数です。1〜12ヶ月目が期間A、13〜24ヶ月目が期間B、25〜36ヶ月目が期間Cに対応します。
## qccパッケージを使う方法
`qcc` パッケージを使うと、数行でu-chartを描くことができます。
### ベースラインのみ(期間A)
```r
library(qcc)
qcc(mrsa[1:12], sizes = patients[1:12], type = "u",
xlab = "Month", ylab = "MRSA rate (per patient)",
title = "u-chart: MRSA rate in ICU (Period A)")
```
![[uchart_basic.png]]
`sizes` に各月の患者数を渡すことで、管理限界が月ごとに変動しているのが確認できます。UCLの線が波打っているのは、患者数の違いを反映しているためです。
### 新データの追加(期間B・C)
期間Aで確立したベースラインに対して、期間B・Cのデータを `newdata` として追加します。
```r
qcc(mrsa[1:12], sizes = patients[1:12], type = "u",
newdata = mrsa[13:36], newsizes = patients[13:36],
xlab = "Month", ylab = "MRSA rate (per patient)",
title = "u-chart: Period A (baseline) + Period B, C (new data)")
```
![[uchart_newdata.png]]
`qcc` は自動的にベースライン(Calibration data)と新データ(New data)を区別して描画します。期間B・Cのすべての点が管理限界内に収まっていれば、「方針変更後もアウトブレイクは発生していない」という客観的な根拠になります。
下部に表示される `Number beyond limits = 0` は、管理限界を超えた点がゼロであることを意味します。
## ggplot2で作成する方法
`qcc` パッケージに頼らず、自分で計算してggplot2で描画する方法も紹介します。管理限界の計算過程が見えるので、仕組みの理解に役立ちます。見た目のカスタマイズもしやすいです。
```r
library(ggplot2)
# 発生率と管理限界の計算
rate <- mrsa / patients
ubar <- sum(mrsa[1:12]) / sum(patients[1:12])
ucl <- ubar + 3 * sqrt(ubar / patients)
lcl <- pmax(ubar - 3 * sqrt(ubar / patients), 0)
period <- rep(c("A", "B", "C"), each = 12)
df <- data.frame(
month_idx = 1:36,
month = factor(months, levels = months),
period = period,
rate = rate,
patients = patients,
ucl = ucl,
lcl = lcl
)
ggplot(df, aes(x = month_idx)) +
# patient count bars (right axis)
geom_bar(aes(y = patients / 5000), stat = "identity",
fill = "grey85", color = NA) +
# control limits (dashed)
geom_line(aes(y = ucl), linetype = "dashed", linewidth = 0.5) +
geom_line(aes(y = lcl), linetype = "dashed", linewidth = 0.5) +
# center line (solid)
geom_hline(yintercept = ubar, linetype = "solid", linewidth = 0.6) +
# rate
geom_line(aes(y = rate), linewidth = 0.5) +
geom_point(aes(y = rate), size = 1.8, shape = 16) +
# period dividers
geom_vline(xintercept = 12.5, linetype = "dotted", color = "grey40") +
geom_vline(xintercept = 24.5, linetype = "dotted", color = "grey40") +
# period labels
annotate("text", x = 6.5, y = max(ucl) * 1.1, label = "Period A", size = 3.5) +
annotate("text", x = 18.5, y = max(ucl) * 1.1, label = "Period B", size = 3.5) +
annotate("text", x = 30.5, y = max(ucl) * 1.1, label = "Period C", size = 3.5) +
scale_y_continuous(
name = "MRSA rate (per patient)",
sec.axis = sec_axis(~ . * 5000, name = "Patients")
) +
scale_x_continuous(breaks = 1:36, labels = months) +
theme_bw() +
theme(
axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5, size = 7),
panel.grid.major.x = element_blank(),
panel.grid.minor = element_blank()
) +
labs(x = NULL)
```
![[uchart_ggplot.png]]
実線が中心線、破線がUCL/LCL、グレーの棒が月ごとの患者数(右軸)です。患者数が多い月ほどUCLの破線が下がっているのが確認できます。
## 管理限界を超えた点の検出
実際のサーベイランスでは、管理限界を超えた月を自動的に検出して一覧表示する処理が必要になることがあります。
```r
# 管理限界を超えた月の検出
over_ucl <- which(rate > ucl)
under_lcl <- which(rate < lcl)
if (length(over_ucl) > 0) {
cat("UCL exceeded at:", months[over_ucl], "\n")
} else {
cat("No points exceeded UCL.\n")
}
```
```
No points exceeded UCL.
```
## 普通の折れ線グラフとの違い
u-chartと普通のトレンドグラフ(発生率の折れ線)は見た目が似ていますが、決定的な違いがあります。
- 折れ線グラフは値の推移を見せるだけで、ある月の値が「正常範囲か異常か」を判断する基準がありません
- u-chartは各月の患者数に応じた管理限界が引かれるため、「この値は統計的に偶然の範囲か否か」を客観的に判定できます
論文やレポートで「方針変更後もアウトブレイクは発生しなかった」と主張する場合、折れ線グラフだけでは根拠が弱いですが、u-chartで「すべての点が管理限界内にある」と示せば客観的な証拠になります。
## 参考文献
- Benneyan JC. Statistical quality control methods in infection control and hospital epidemiology. Infect Control Hosp Epidemiol. 1998;19(4):265-283.
- Morton AP, et al. Surveillance of healthcare-associated infections in Queensland, Australia. J Qual Clin Pract. 2001.
- Bear RA, et al. Process control charts in infection prevention: Make it simple to make it happen. Am J Infect Control. 2017.
- `qcc` パッケージ:[CRAN](https://cran.r-project.org/web/packages/qcc/index.html)
- 荒木孝治. qccパッケージの解説(関西大学):[PDF](http://www.ec.kansai-u.ac.jp/user/arakit/documents/qcc.pdf)