iT邦幫忙

2026 iThome 鐵人賽

DAY 4
0
自我挑戰組

Medical Data Cleaner系列 第 12 篇

整合醫療資料品質檢查功能

  • 分享至 

  • xImage
  •  

前幾天已經陸續完成缺失值、資料格式、數值範圍、重複資料以及資料一致性的檢查。
不過目前這些功能都是分開測試的,如果之後真的要拿來檢查一份醫療資料,每一個檢查都要分別執行會比較麻煩。
所以今天的目標,就是把前面完成的功能整合起來,讓PHP可以一次讀取CSV,並同時進行多種資料品質檢查,最後統一整理出檢查結果。
一、整合五種資料品質檢查
首先先建立各種問題的計數變數:

$missingCount = 0; 
$formatCount = 0; 
$rangeCount = 0; 
$duplicateCount = 0; 
$consistencyCount = 0;

另外也建立了$affectedPatients,用來記錄有哪些病人有發現問題。

$affectedPatients = [];

這樣可以避免同一位病人有多個問題時,被重複計算成不同的人。
二、整合缺失值檢查
首先檢查每一個欄位是不是空白。

foreach ($row as $index => $value) {

    if (trim($value) === '') {

        $missingCount++;
        $affectedPatients[$row[0]] = true;

        echo '【缺失值】' . $row[0] . ' → '
            . $header[$index] . '<br>';
    }
}

如果發現空白資料,就會增加$missingCount,並記錄這筆資料所屬的病人。
例如目前的測試資料中,P002的gender 空白,因此會被判定為缺失值。
三、整合資料格式檢查
接著檢查年齡、性別和就診日期的格式。
例如年齡必須是數字:

if (!is_numeric($row[1])) {

    $formatCount++;
    $affectedPatients[$row[0]] = true;

    echo '【格式錯誤】' . $row[0]
        . ' → age = ' . $row[1] . '<br>';
}

性別則限制為「男」或「女」:

if ($row[2] !== ''
    && $row[2] !== '男'
    && $row[2] !== '女') {

    $formatCount++;
    $affectedPatients[$row[0]] = true;

    echo '【格式錯誤】' . $row[0]
        . ' → gender = ' . $row[2] . '<br>';
}

日期則檢查是否符合YYYY-MM-DD的格式:

if ($row[8] !== ''
    && !preg_match('/^\d{4}-\d{2}-\d{2}$/', $row[8])) {

    $formatCount++;
    $affectedPatients[$row[0]] = true;

    echo '【格式錯誤】' . $row[0]
        . ' → visit_date = ' . $row[8] . '<br>';
}

四、整合數值範圍檢查
除了確認資料是不是數字,也需要確認數值是否落在這次測試設定的合理範圍內。
目前設定:
age:0~120
heart_rate:30~200
例如:

if (is_numeric($row[1])) {

    if ($row[1] < 0 || $row[1] > 120) {

        $rangeCount++;
        $affectedPatients[$row[0]] = true;

        echo '【數值異常】' . $row[0]
            . ' → age = ' . $row[1] . '<br>';
    }
}

心率也是使用相同的方式:

if (is_numeric($row[6])) {

    if ($row[6] < 30 || $row[6] > 200) {

        $rangeCount++;
        $affectedPatients[$row[0]] = true;

        echo '【數值異常】' . $row[0]
            . ' → heart_rate = ' . $row[6] . '<br>';
    }
}

這裡設定的範圍主要是為了這次資料品質檢查的測試,並不是醫療診斷標準。
五、整合重複資料檢查
接下來是前一天完成的重複資料檢查。把整列資料組合成一個字串,再利用陣列確認之前是否已經出現過。

$data = implode('|', $row);

if (isset($rows[$data])) {

    $duplicateCount++;
    $affectedPatients[$row[0]] = true;

    echo '【重複資料】' . $row[0] . '<br>';

} else {

    $rows[$data] = true;
}

目前測試資料中,P009有兩筆完全相同的資料,因此會被判定為重複資料。
六、整合資料一致性檢查
最後加入資料一致性的檢查。
例如性別雖然有些資料代表的是男性,但寫法不一致:

if ($row[2] === '男性' || $row[2] === 'M') {

    $consistencyCount++;
    $affectedPatients[$row[0]] = true;

    echo '【格式不一致】' . $row[0]
        . ' → gender = ' . $row[2]
        . ' → 建議修正為:男<br>';
}

日期也是一樣,如果使用/而不是-,就會提示建議修改的格式:

if ($row[8] !== ''
    && preg_match('/^\d{4}\/\d{2}\/\d{2}$/', $row[8])) {

    $consistencyCount++;
    $affectedPatients[$row[0]] = true;

    $standardDate = str_replace('/', '-', $row[8]);

    echo '【格式不一致】' . $row[0]
        . ' → visit_date = ' . $row[8]
        . ' → 建議修正為:' . $standardDate . '<br>';
}

七、統計最後的檢查結果
完成所有檢查後,再統一計算總問題數以及有問題的病人數。

$totalIssues = $missingCount
    + $formatCount
    + $rangeCount
    + $duplicateCount
    + $consistencyCount;

$affectedPatientCount = count($affectedPatients);

$affectedRate = ($affectedPatientCount / $totalRows) * 100;

最後將結果顯示在網頁上:

echo '<h3>資料品質問題統計</h3>';

echo '資料總筆數:' . $totalRows . ' 筆<br>';

echo '缺失值:' . $missingCount . ' 筆<br>';
echo '格式錯誤:' . $formatCount . ' 筆<br>';
echo '數值異常:' . $rangeCount . ' 筆<br>';
echo '重複資料:' . $duplicateCount . ' 筆<br>';
echo '一致性問題:' . $consistencyCount . ' 筆<br>';

echo '<br>';

echo '有問題的病人數:' . $affectedPatientCount . ' 人<br>';

echo '有問題的資料比例:'
    . number_format($affectedRate, 1) . '%<br>';

echo '<strong>總問題數:'
    . $totalIssues . ' 筆</strong><br>';

上一篇
檢查資料一致性與標準化建議
下一篇
處理缺失值與建立清理後資料
系列文
Medical Data Cleaner 共 16 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言