| name | sequence-validity |
| description | Validate temporal ordering of date variables in a QUIQ-format table. Uses Claude CLI to automatically identify start/end date variable pairs, then checks whether start_date <= end_date for each matched record. No API key required. Use for LYDUS data quality assessment of chronological consistency. |
| tier | community |
| category | lydus |
| parameters | {"quiq_path":{"description":"Path to QUIQ-format CSV file. Must contain rows where Mapping_info_1 contains 'date'.","type":"string"},"save_path":{"description":"Directory path to save output files.","type":"string"}} |
Sequence Validity
Validates the chronological ordering of date variables in a QUIQ-format table. Claude CLI automatically identifies meaningful (start, end) date pairs (e.g., admission โ discharge), then checks whether start_date โค end_date for each matched patient record.
When to Use This Skill
- After QUIQ conversion, to detect records where events occur in impossible or illogical order (e.g., discharge before admission)
- To assess chronological consistency of temporal data
- As part of LYDUS quality management assessment
SQL Support
Not applicable. Claude CLI is required to identify date-variable pairs.
Filtering Logic
| Condition | Value |
|---|
Mapping_info_1 | contains date (case-insensitive) |
Value | parsed as datetime |
Pipeline
- Extract date rows โ filter
Mapping_info_1 contains date, parse Value as datetime
- Collect unique identifiers โ
Original_table_name - Variable_name for all date variables
- LLM pair identification โ send identifier list to Claude CLI; receive
timepoint_pairs list
- LLM exclusion rules:
- Non-time variables excluded
- Unpaired time variables excluded
- Sensitive/complex variables excluded (death_time, year_of_birth, diagnosis_date, etc.)
- Additional-context-required pairs excluded
- Validation โ for each pair: merge on
(Patient_id, Original_table_name, Primary_key), check Start_date โค End_date
- Summary โ per-(table, start_var, end_var): Total_num, Invalid_num, Sequence_Validity (%)
Output
| File | Description |
|---|
sequence_validity_total.txt | Overall Sequence Validity (%), Total Num, Invalid Num |
sequence_validity_summary.csv | Per-(table, start_var, end_var): counts and Sequence_Validity (%) |
sequence_validity_detail.csv | Per-record: Start_date, End_date, Is_valid |
How to Run
import pandas as pd
from scripts.sequence_validity import get_sequence_validity
quiq = pd.read_csv("/path/to/quiq.csv")
df_total, df_summary = get_sequence_validity(
quiq=quiq
)
total_num = df_summary['Total_num'].sum()
invalid_num = df_summary['Invalid_num'].sum()
seq_validity = round((total_num - invalid_num) / total_num * 100, 2)
print(f"Sequence Validity (%) = {seq_validity}")
print(df_summary)
As a script with config
quiq_path: /path/to/quiq.csv
save_path: /path/to/output
python scripts/sequence_validity.py --config config.yaml
Critical Notes
-
Same-table constraint โ pairs spanning different tables are skipped. Start and end variables must be from the same Original_table_name.
-
LLM ์๋ต ํ์ฑ โ Claude CLI๋ timepoint_pairs = [(...), ...] ํ์์ผ๋ก ์๋ตํด์ผ ํจ. = ๊ธฐ์ค์ผ๋ก ๋ถ๋ฆฌ ํ ast.literal_eval ํ์ฑ. ํ์ ๋ถ์ผ์น ์ ValueError ๋ฐ์. ์๋ต์ด ๋งํฌ๋ค์ด ์ฝ๋๋ธ๋ก์ ํฌํจํ๋ฉด ํ์ฑ ์คํจํ ์ ์์ผ๋ system prompt์ output format ์์๋ฅผ ๊ทธ๋๋ก ๋ฐ๋ฅด๋๋ก ์ค๊ณ๋จ.
-
๋ ์ง ๋ณํ ์คํจ โ pd.to_datetime(..., errors='coerce')๋ก ๋ณํ ๋ถ๊ฐํ ๊ฐ์ NaT โ dropna() ๋ก ์ ์ธ๋จ.
-
์๋ณธ ์ฝ๋ ๊ฐ์ ์ฌํญ:
combined_time_df['Value'] = ... SettingWithCopyWarning โ .copy() ํ ํ ๋น
- LLM ์๋ต ํ์ฑ
try/except ์ถ๊ฐ (์๋ณธ์ ํ์ฑ ์คํจ ์ unhandled exception)
_validate_sequence ๋ด pd.concat loop โ list ์์ง ํ ํ ๋ฒ์ concat
os.path.join ์ฌ์ฉ (๋ฌธ์์ด ์ฐ๊ฒฐ ๋์ )
required=True for --config
-
Dependencies โ pandas, numpy (LLM: Claude CLI via subprocess, timeout 180s)
References
- LYDUS ํ์ง๊ด๋ฆฌ ํ๋ก๊ทธ๋จ ํ์ฉ ๊ฐ์ด๋๋ผ์ธ (๋น๊ณต๊ฐ ๋ด๋ถ ๋ฌธ์)
- Original Python implementation: LYDUS_Sequence_Validity.py (์ด์ฑ๋ฏผ ์์ฑ)