# 의료 데이터 정규화 방법

> 튜토리얼: 여러 소스의 의료 데이터를 하나의 비교 가능한 형태로 변환합니다. LOINC 조회, UCUM 단위, ISO 날짜, 참조 범위, 재시도 시 중복 없음, 유럽 실험실 프로필에 대한 유효성 검사를 포함합니다.

Source: https://developers.anpheros.com/ko/guides/normalize-medical-data

**의료 데이터 정규화는 다양한 형태로 들어오는 값을 하나의 비교 가능한 형태로 변환하는 것을 의미합니다. 즉, 동일한 검사에 대해 동일한 코드, 동일한 단위 시스템, 하나의 형식으로 된 날짜, 각 값에 대한 참조 범위 및 출처, 그리고 중복이 없어야 합니다.** 이 튜토리얼에서는 HL7 FHIR R4 레코드에 데이터가 도달하기 전에 LOINC 및 ATC 코드를 조회하고, UCUM 단위를 사용하며, 모호한 날짜를 거부하고, 범위를 유지하고, 재시도 시 중복을 피하고, 유럽 실험실 프로필에 대해 결과를 확인하는 방법을 보여줍니다. 표시되는 모든 응답은 Anpheros API에서 제공됩니다.

## 왜 중요한가

동일한 HbA1c 결과가 "HbA1c 6,4 %", "Hemoglobina glicozilata: 6.4", "Glycated haemoglobin 46 mmol/mol" 또는 특정 실험실만 이해하는 실험실 코드로 전달될 수 있습니다. 이러한 값들이 하나의 단위로 된 하나의 코드가 되기 전까지는 다음과 같은 문제가 발생합니다.

- 환자의 HbA1c 추세를 보여주는 차트가 세 개의 관련 없는 선으로 표시됩니다.
- "HbA1c 6.5 % 초과"에 대한 알림이 두 개의 값을 놓칩니다.
- AI 모델이 하나의 추세 대신 네 개의 사실로 인식합니다.
- 해당 기록을 수신하는 다른 시스템이 이를 해석할 수 없습니다.

정규화는 데이터가 레코드에 들어가는 시점에 한 번 수행되어야 하며, 나중에 이를 읽는 모든 애플리케이션에서 수행되어서는 안 됩니다.

## 정규화된 값의 구성 요소

| 부분 | 정규화된 형식 | 예시 |
|---|---|---|
| 측정 대상 | 표준 시스템의 코드 | LOINC `4548-4` (HbA1c), RxNorm `6809` (metformin), ICD-10 `E11` (type 2 diabetes) |
| 값 | 숫자로 표현하거나, 결과가 숫자가 아닌 경우에만 텍스트로 표현 | `6.4` |
| 단위 | UCUM | `%`, `mg/dL`, `mm[Hg]`, `kg` |
| 시점 | 시간대가 중요한 경우 시간대 정보 포함된 ISO 8601 날짜-시간 | `2026-10-01T07:30:00Z` |
| 정상 범위 | 동일한 단위를 사용한 최저값 및 최고값 | `4.0`–`5.6` |
| 출처 | 생성 주체 및 시스템 | `labx`의 `import` |
| 식별자 | 반복을 인식할 수 있게 하는 요소 | Idempotency key 또는 출처 식별자 |

어떤 코드 시스템이 어떤 리소스 유형과 함께 사용되는지는 [FHIR 코드 시스템](https://developers.anpheros.com/ko/guides/fhir-code-systems)에서 확인할 수 있습니다.

## 1단계: 코드 찾기

플랫폼의 용어를 영어 또는 루마니아어 이름 또는 약어로 검색합니다.

```bash
curl "https://platform.anpheros.com/v1/terminology/loinc?q=hba1c" -H "Authorization: Bearer $KEY"
curl "https://platform.anpheros.com/v1/terminology/loinc?q=hemoglobina%20glicozilata" -H "Authorization: Bearer $KEY"
```

둘 다 동일한 개념을 반환합니다.

```json
{"data": [{"system": "http://loinc.org", "code": "4548-4", "display": "Hemoglobin A1c/Hemoglobin.total in Blood",
           "display_ro": "Hemoglobină glicozilată (HbA1c)", "category": "laboratory", "unit": "%"}], "total": 1}
```

의약품의 경우 [Anpheros Search](https://developers.anpheros.com/ko/guides/anpheros-search)는 이름 또는 브랜드로 물질을 찾아 RxNorm 성분 코드와 EMA 제품 번호를 제공합니다.

```bash
curl "https://platform.anpheros.com/v1/search?q=metformin&type=treatment" -H "Authorization: Bearer $KEY"
```

`unit` 필드는 해당 검사에 대해 LOINC가 예상하는 단위입니다. 수신한 내용을 확인하는 데 사용하십시오. 각 소스의 자체 이름에서 코드로의 매핑을 소스별로 한 번 빌드하고 통합에 유지하십시오. 작성 시점에 추측하지 마십시오. 이름이 모호하고 소스에서 해결할 수 없는 경우 매핑되지 않은 상태로 두고 소스에 문의하십시오. [FHIR 레코드에 실험실 결과 가져오기](https://developers.anpheros.com/ko/guides/import-lab-results-fhir)는 매핑되지 않은 실험실 마커를 유지하고 보고하는 방법을 보여줍니다.

## 2단계: 코드, 단위 및 범위로 작성

```bash
curl -X POST "https://platform.anpheros.com/v1/patients/$PID/observations" -H "Authorization: Bearer $KEY" \
     -H "Content-Type: application/json" -H "Idempotency-Key: lab-77-hba1c" -d '{
  "code": "4548-4", "category": "laboratory",
  "value": 6.4, "unit": "%", "effective_at": "2026-10-01T07:30:00Z",
  "reference_range": {"low": 4.0, "high": 5.6},
  "author_type": "import"
}'
```

```json
{"id": "3296315c-…", "code": "4548-4", "system": "http://loinc.org", "display": "Hemoglobin A1c/Hemoglobin.total in Blood",
 "category": "laboratory", "effective_at": "2026-10-01T07:30:00Z", "value": 6.4, "unit": "%",
 "reference_range": {"low": 4.0, "high": 5.6}, "status": "final", "fhir": "Observation/3296315c-…"}
```

코드만 보내면 플랫폼은 REST API와 FHIR API(`/fhir/R4`) 모두에서 표준 LOINC 이름을 채워주므로 모든 애플리케이션이 동일한 `display`을 읽게 됩니다. 직접 보내는 `display`은 그대로 유지됩니다.

원본 문구도 유지하십시오. 검사 보고서의 경우, FHIR Observation의 `code.text`은 LOINC 코딩 옆에 검사실 이름("Hemoglobina glicozilata (HbA1c)")을 보유합니다. 환자는 여전히 종이 보고서를 인식할 수 있으며, 매핑이 의문시되더라도 아무것도 손실되지 않습니다.

## 3단계: 단위

UCUM 코드를 사용하세요: `mg/dL`, `mmol/L`, `%`, `mm[Hg]`, `kg`, `cm`, `/min`, `Cel`. 대부분의 오류를 방지하는 두 가지 규칙이 있습니다:

- **자동으로 변환하지 마세요.** 검사실에서 `mmol/L` 단위로 포도당을 보고하고 앱에서 `mg/dL` 단위로 표시하는 경우, 검사실에서 측정한 값을 저장하고 표시할 때 변환하세요. 저장된 값은 보고서에 추적 가능하게 유지됩니다.
- **단위를 코드와 대조하세요.** LOINC 코드는 구체적입니다: `%` 단위의 HbA1c는 `4548-4`이지만, `mmol/mol` 단위의 HbA1c는 다른 LOINC 코드입니다. 코드의 예상 단위와 일치하지 않는 단위를 가진 값은 변환 문제가 아니라 매핑 오류입니다.

Anpheros는 단위를 자동으로 변환하지 않고, 전송된 단위를 저장합니다.

## 4단계: 날짜

소스에서 알려진 형식을 사용하여 ISO 8601로 날짜를 변환한 후 작성하십시오. `01.10.2026`은 루마니아 및 많은 유럽 국가에서 10월 1일이지만, `10/01/2026`은 미국에서만 10월 1일입니다. API는 추측하는 대신 ISO 형식이 아닌 것은 거부합니다.

```json
{"error": {"type": "invalid", "message": "Input should be a valid datetime or date, invalid character in year (at effective_at)", "field": "effective_at"}}
```

실험실 커넥터는 예외입니다. 유럽 보고서를 읽고 있다는 것을 알기 때문에 `DD.MM.YYYY` 및 `DD/MM/YYYY`을 허용합니다.

시간대가 중요한 측정값(혈압, 포도당, 약물 복용량)의 경우 시간대와 함께 시간을 보내십시오. 부쿠레슈티에서 23:30에 측정한 값은 UTC에서는 전날이며, 환자는 복용한 날짜로 인식합니다.

## 5단계: 중복 제거

중복은 재시도, 동일한 보고서가 두 번 전송되는 경우, 그리고 동일한 값이 두 경로를 통해 도착하는 경우에 발생합니다.

- **재시도:** 예를 들어 보고서 ID와 검사를 식별하는 `Idempotency-Key`를 전송합니다. 동일한 키로 동일한 요청을 다시 보내면 첫 번째 응답이 반환되고 새로운 내용은 저장되지 않습니다. SDK는 생성 시마다 1을 추가합니다.
- **동일한 보고서 두 번 전송:** 랩 커넥터는 보고서, 코드, 날짜 및 값을 기반으로 행별로 안정적인 식별자를 구축하고 이미 가져온 행은 건너뜁니다.
- **두 경로:** 소스 시스템 자체 ID를 `X-Anpheros-Origin-Id` (또는 FHIR 리소스의 `identifier`)에 저장하고, 다른 경로를 통해 다시 올 수 있는 값 쓰기 전에 해당 ID를 검색합니다.

## 6단계: 프로필 검사

검사 결과의 경우, 해당 리소스가 HL7 Europe 검사 보고서 프로필에 얼마나 부합하는지 플랫폼에 문의한 후 신뢰하십시오.

```bash
curl -X POST "https://platform.anpheros.com/fhir/R4/Observation/\$validate?profile=eu-lab" -H "Authorization: Bearer $KEY" \
     -H "Content-Type: application/fhir+json" -d '{
  "resourceType": "Observation", "status": "final",
  "category": [{"coding": [{"system": "http://terminology.hl7.org/CodeSystem/observation-category", "code": "laboratory"}]}],
  "code": {"text": "HbA1c"}, "subject": {"reference": "Patient/'$PID'"},
  "valueQuantity": {"value": 6.4, "unit": "%"}
}'
```

이 정규화되지 않은 결과는 정확한 목록을 제공합니다:

```json
{"resourceType": "OperationOutcome", "issue": [
  {"severity": "error", "code": "invalid", "diagnostics": "Observation.code must carry a LOINC coding.", "expression": ["Observation.code"]},
  {"severity": "error", "code": "required", "diagnostics": "Observation.effective[x] is required.", "expression": ["Observation.effective"]},
  {"severity": "warning", "code": "business-rule", "diagnostics": "valueQuantity should carry a UCUM system and code.", "expression": ["Observation.valueQuantity"]},
  {"severity": "warning", "code": "informational", "diagnostics": "No referenceRange: interpretation will need the laboratory's ranges.", "expression": ["Observation.referenceRange"]},
  {"severity": "information", "code": "informational", "diagnostics": "No performer (laboratory) recorded.", "expression": ["Observation.performer"]},
  {"severity": "information", "code": "informational", "diagnostics": "No issued time (when the laboratory released the result).", "expression": ["Observation.issued"]}]}
```

각 문제는 위의 단계 중 하나에 해당합니다. 각 소스의 실제 샘플을 사용하여 통합 테스트에서 `$validate`을 실행하십시오.

## 7단계: 소스 유지

정규화는 값의 표기 방식을 변경하지만, 출처는 변경하지 않습니다. 쓰기 작업 시마다 `author_type`(`device`, `import`, `practitioner`, `patient`) 및 `X-Anpheros-Source-System`을 함께 보내십시오. 이를 통해 의사, 감사자 또는 AI 모델이 실험실 결과와 집에서 입력한 값을 구분할 수 있습니다. [Medical data provenance explained](https://developers.anpheros.com/ko/guides/medical-data-provenance)를 참조하십시오.

## 체크리스트

- [ ] 각 소스는 통합 내에서 유지되는 LOINC / ATC / ICD-10으로의 이름 매핑을 가집니다.
- [ ] 모호한 이름은 매핑되지 않은 상태로 유지되고 보고되며, 절대 추측되지 않습니다.
- [ ] UCUM 단위는 코드와 일치하며, 암묵적인 변환은 없습니다.
- [ ] 시간대가 중요한 경우 시간대와 함께 ISO 8601 날짜를 사용합니다.
- [ ] 검사값과 함께 참조 범위를 유지합니다.
- [ ] 원본 문구는 유지됩니다 (`code.text`).
- [ ] 모든 쓰기 작업에 대해 멱등성 키 또는 소스 ID를 사용합니다.
- [ ] 모든 쓰기 작업에 대해 `author_type` 및 소스 시스템을 사용합니다.
- [ ] 검사 결과 테스트 시 `$validate`을 사용합니다.

## 자주 묻는 질문

### 의료 데이터 정규화란 무엇인가요?
다양한 출처의 건강 데이터를 하나의 표준 형식으로 변환하는 것입니다. 공유 코드(검사 및 측정에는 LOINC, 진단에는 ICD-10, 약물에는 ATC), UCUM 단위, ISO 날짜, 참조 범위 및 기록된 출처를 사용하여 서로 다른 시스템의 값을 비교, 결합 및 교환할 수 있도록 합니다.

### 모든 값을 하나의 단위로 변환해야 하나요?
소스가 측정한 단위를 저장하되, 해당 코드가 유효한 UCUM 단위와 일치하는 한, 표시하거나 분석할 때 변환합니다. 이렇게 하면 저장된 모든 값이 원본 보고서로 추적 가능하게 유지됩니다.

### 정규화는 완전히 자동화될 수 있나요?
대부분 가능합니다. 소스의 코드, 알려진 이름 및 잘 구성된 단위는 자동으로 매핑될 수 있습니다. 모호한 이름과 알 수 없는 로컬 코드는 소스당 한 번의 사람의 결정이 필요하며, 그 후에는 매핑이 자동으로 이루어집니다.

## 관련 자료

- [FHIR 코드 시스템](https://developers.anpheros.com/ko/guides/fhir-code-systems)
- [FHIR 레코드에 검사 결과 가져오는 방법](https://developers.anpheros.com/ko/guides/import-lab-results-fhir)
- [의료 데이터 출처 설명](https://developers.anpheros.com/ko/guides/medical-data-provenance)
- [의료 데이터 상호 운용성](https://developers.anpheros.com/ko/guides/interoperability)
- [의료 데이터 API](https://developers.anpheros.com/ko/guides/medical-data-api)
