언제 쓰나
거의 모든 프로젝트에서 쓴다(Excel 취급 파일 1,816개). 원본 여러 개를 합치거나 LLM으로 처리한 뒤 "몇 건이 어디로 샜는지"를 확인해야 할 때. 검증 없이 넘어간 결과는 나중에 반드시 문제가 된다.
바로 실행
python ~/.claude/skills/excel-case-validator/scripts/validate.py \
--sources wos.xlsx pubmed.xlsx koreamed.xlsx \
--final consolidated.xlsx \
--key PMID --key DOI \
--required Title Year \
--year-col Year --year-range 1963 2026마크다운 표로 리포트를 내고, FAIL이 있으면 exit code 1. 원본을 절대 수정하지 않는다(read-only).
python .../validate.py --self-check # 내장 테스트scripts/dedup.py — 중복 제거와 세대 관리.
python3 scripts/dedup.py --file data.xlsx --key clinicExamSeq --latest-by 승인일 --out clean.xlsx
python3 scripts/dedup.py --latest-in ./excel_old # 파일명 날짜로 최신 파일 찾기norm_title(NFKC+공백 정규화) · dedup(승인일 최신 → 정보량 순 선택) · diff_by_key(회차 간 신규/제거) · find_latest_by_date.
검사 항목
| 검사 | 내용 |
|---|---|
| 건수 | 원본별 건수 + 통합 ≤ 원본 합계 |
| 키 중복 | --key 컬럼의 중복. 빈값은 중복으로 세지 않는다 |
| 필수 컬럼 완전성 | --required 컬럼의 채움 비율 |
| 누락 | 원본에는 있는데 통합에 없는 키 (예시 3건까지 표시) |
| 값 범위 | 연도 등 수치 범위 밖 값 |
빈 키를 중복으로 세지 마라. PMID 없는 논문이 여러 건인 건 정상이다. 이걸 놓치면 검증이 항상 FAIL로 나와 아무도 안 보게 된다.
비교는 정규화 후에 한다
_norm() — NFKC 정규화 → 앞뒤 공백 제거 → 연속 공백 축약 → 소문자.
제목으로 비교할 때는 공백까지 전부 제거하는 옵션이 필요하다. 정본 구현(ctrial-auto/app/utils/compare_utils.py의 norm_title(s, remove_all_spaces=True))을 참고. 공백·괄호·전각문자 차이로 같은 레코드가 "신규"로 잡히는 사고가 실제로 반복됐다.
프로젝트별 검증 항목은 별도로 정의한다
범용 스크립트로는 도메인 규칙을 못 잡는다. 프로젝트마다 검증 목록을 문서로 고정하고 전용 스크립트를 둔다. 좋은 예:
~/Documents/IMOK/AML260130_Korea AML MDS 30y/
.claude/agents/data-validator.md 검증 10항목을 명시 (건수·중복·완전성·초록 보유율 93.5%·연도 1963~2026·색상 코딩)
scripts/validate_data.py
docs/VALIDATION_REPORT.md기대값을 숫자로 박아둔다(WoS 1,679건 / PubMed 1,914건 / KoreaMed 761건 → 통합 2,583건). "대충 맞는 것 같다"로는 회귀를 못 잡는다.
중복 제거·세대 관리
ctrial-auto/app/utils/compare_utils.py에 실전에서 다듬어진 함수들이 있다:
| 함수 | 역할 |
|---|---|
dedup_file2_by_seq | 신규 파일을 일련번호 기준 중복 제거 |
dedup_and_label_file1 | 기존 파일 중복 제거 + 라벨 부착 |
_pick_latest_by_approval | 중복 그룹에서 승인일 최신 건 선택 |
_info_richness | 정보가 더 많은 행을 남기는 기준 |
extract_date_from_filename / find_latest_file_by_date | 파일명 날짜로 세대 관리 |
read_older_excels_newest_to_oldest | 과거 파일을 최신순으로 순회 |
중복 제거 시 어느 행을 남길지는 규칙이 필요하다. 아무거나 남기면 정보가 적은 행이 살아남는다. _info_richness(채워진 필드 수)나 _pick_latest_by_approval(최신 승인일) 같은 명시적 기준을 써라.
함정
~$파일명.xlsx임시 파일이 있으면 Excel이 열려 있다는 뜻이다. 그 상태로 스크립트를 돌리면 깨진다.신희정_교수님/pathology_processing/에 실제로 남아 있다.- 결과 파일명에 날짜시각을 박아라(
result_..._20260312_012900.xlsx). 여러 번 돌리면 어느 게 어느 설정 결과인지 알 수 없어진다. - 검증은 반드시 read-only. 검증 스크립트가 원본을 고치면 검증의 의미가 없다.
연관 skill
ctrial-collect(회차 비교), biblio-analysis(서지 통합 검증), pathology-llm-extract·medical-code-extract(추출 결과 검증)