4. 源数据接入与解析自动化
临床研究报告的数据来源天然是异构的:EDC系统导出的是带注释的SAS数据集或CSV,中心实验室回传的是固定宽度的文本或Excel,PK/PD分析方给的是XPT传输文件,外部安全数据库可能只提供JSON接口,而研究者发起的问卷又常常是手工整理的Excel。源数据接入与解析自动化的目标,就是把这些形态各异的输入统一收敛为一份结构一致、类型正确、可追溯的中间数据集,让后续的SDTM映射和统计分析不必反复处理格式差异。
一、先建立“接入契约”,再写解析代码
接入自动化的第一步不是打开文件,而是为每个数据源定义一份接入契约。契约至少包含六项:源系统标识、传输方式(SFTP共享目录/API/邮件附件/对象存储)、文件命名规则、格式与编码、期望的列结构与类型、以及到达时间窗口。例如某中心实验室每周三凌晨通过SFTP推送 LAB_<STUDY>_<YYYYMMDD>.csv,UTF-8编码,含 USUBJID、VISIT、LBTESTCD、LBORRES、LBORRESU、LBDTC 等列,其中 LBDTC 为ISO 8601日期时间。把这份契约写成机器可读的配置(YAML或JSON),解析器就能按配置驱动,而不是为每个源硬编码一套逻辑。
契约中特别要明确三件事:一是主键与去重规则,比如实验室数据以 USUBJID + VISIT + LBTESTCD + LBDTC 为唯一键,重复到达时以最新文件覆盖;二是缺失值表示,SAS的 .、CSV的空字符串、JSON的 null 必须统一映射为同一缺失标记;三是日期与数值的解析约定,避免 01/02/2024 被误读为1月2日还是2月1日。
二、按格式选择解析策略
不同格式的解析难点差异很大,下面这张图概括了五类常见格式的读取要点与统一收敛路径。
以SAS7BDAT为例,它保留了变量标签、格式(如 DATE9.)和长度信息,用 pyreadstat.read_sas7bdat() 读取后可通过 meta 对象拿到列标签,这对后续映射到SDTM的变量标签很有价值。XPT是SAS的传输格式,V5版本对字符变量有200字节上限,长文本(如不良事件描述)可能被静默截断,解析后应检查最大长度是否触及上限。CSV的坑集中在分隔符与引号:当字段内含逗号时必须有引号包裹,若源文件用分号分隔则需显式指定 sep=';'。Excel要警惕日期被存为序列号(如 45292 实为2024-01-01),以及多Sheet中只有第一个Sheet是数据、其余是说明页。JSON常见于外部安全数据库,往往嵌套 subject 对象和 events 数组,需要 json_normalize 展开并统一键名大小写。
三、把解析写成可复现的管道
解析代码不应是一次性脚本,而应组织为“读取器 + 规范化 + 校验”三段式管道。读取器只负责把文件变成原始DataFrame;规范化负责列名对齐(统一大写、去空格、替换非法字符)、类型转换和缺失归一;校验负责业务规则。下面是一个可参考的配置片段,用YAML描述一个实验室CSV源的接入契约:
source_id: CENTRAL_LAB_A
transport: sftp
path: /upload/lab/
filename_pattern: "LAB_<STUDY>_<YYYYMMDD>.csv"
encoding: utf-8
delimiter: ","
key: [USUBJID, VISIT, LBTESTCD, LBDTC]
columns:
USUBJID: {type: string, required: true}
VISIT: {type: string, required: true}
LBTESTCD: {type: string, required: true}
LBORRES: {type: string}
LBORRESU: {type: string}
LBDTC: {type: datetime, format: "%Y-%m-%dT%H:%M:%S"}
missing_values: ["", ".", "NA", "NULL"]
解析器读取该配置后,按 columns 逐列转换类型,遇到无法转换的值记录到日志并置为缺失,而不是让整批数据失败。校验阶段先检查主键是否唯一,再检查 USUBJID 是否存在于受试者主表,最后检查 LBDTC 是否落在知情同意日期之后、数据截止日期之前。任何一条不通过,该文件整体进入隔离目录并触发告警,人工确认后再决定是否放行。
四、结果如何判断与追溯
一次成功的接入应当能回答四个问题:读了多少行、丢了多少行、哪些列发生了类型转换、数据从哪个文件来。建议在中间数据集旁维护一张接入清单,字段包括 source_id、file_name、file_hash、rows_in、rows_out、rows_quarantined、parsed_at、parser_version。当后续统计分析发现某受试者的实验室值异常时,可以凭 file_hash 回溯到原始文件,确认是源数据问题还是解析问题。这种可追溯性是临床数据自动化区别于普通ETL的关键要求。
. 被读成字符串、Excel日期被读成整数、XPT长文本被截断,这些都不会报错,但会污染下游分析。类型与长度校验必须显式执行。