第一批试填数据从六座虚拟城市合并回来,“份量”这一列立刻失去了意义。海川填整份早餐的总克数,锦城把油条、豆浆和鸡蛋分开称,江州有人写“1 碗”,临安在店家不允许称重时留空。六地使用的是同一张表,每个人也都认真填写,得到的值却无法放在一起比较。
问题并不在于有人忘记按保存键,而在于工具没有说明“份量”究竟指什么。表格格式统一,只能保证数据落在相同位置;如果现场判断仍由每个人自行补充,同一列会装进几种不同含义。等 1,200 行全部收完,再让分析人员把它们“清洗一致”,很多原始事实已经无法恢复。
数据质量因此不是分析末端的一次美容。它在调查员看见一份早餐、判断一件食物、选择一个单位和留下一个空白时,就已经开始形成。六城、240 家店、1,200 份早餐和 120 份复核记录仍然是教学模拟,不包含现实店铺或个人资料;案例要说明的是,一个可解释的空白往往比一个来源不明的完整数字更可靠。
数据质量首先是含义能够共同执行
表单、操作手册和数据字典承担不同责任。表单把值录入正确位置,手册说明现场遇到具体情形时怎样判断,数据字典则规定字段名称、含义、单位、允许值、空白规则、来源和版本。缺少任何一项,团队都会用口头理解填补空缺,最后留下格式相同、含义不同的数据。
例如,combo_id 是一份早餐组合的唯一编号,应由系统生成且全库不重复;shop_id 必须从抽样名单带入,并能在店铺表中找到。store_type 只能使用早餐摊点、独立门店、连锁门店和食堂窗口四个冻结选项,不能有人写“餐馆”,另一个人写“小吃店”,事后再猜它们属于哪类。编号和分类看似是管理细节,实际上决定一行数据能否回到它的抽样来源。
price_cny 记录整份组合售价,单位是元。门店未标价且无法确认时应留作缺失并写明原因,不能填 0,因为 0 元会被分析成真实免费。protein_g 保存整份早餐的蛋白质克数,也必须带着来源;未知不等于 0。has_vegetable = 0 只表示调查员确认没有符合定义的蔬菜。若看不清配料,应当记作无法判断,而不是替早餐作出“没有”的结论。
“不适用”与“漏填”也不能只靠空白单元格表达。120 份复核子样本会有参照蛋白质和钠字段,另外 1,080 份按照设计本来就不接受这项测量,它们的空白是结构性不适用;若复核样本中的参照值为空,才是需要追查的缺失。两种空白外观一样,研究含义完全不同。
原始观察、估算值和派生结果也要分开。portion_measured 说明份量是否现场实测,recipe_estimated 说明配方是否依靠参照估算。即使蛋白质和钠已经有数值,质量标记也不能消失。nutrition_score 则由五个分项按冻结公式重算,不让调查员现场手填。公式出错时应修正代码,从原始材料重新生成分数,而不是逐行把总分改成看起来合理的值。
NIH 数据管理与共享网站面向受相关政策约束的研究项目,具体要求不必原样套给所有调查;它把数据、相关文档、保存和共享放到计划阶段考虑,却说明了一个普遍问题:如果字段含义等投稿前才补写,现场判断早已从数据中消失。
自动校验可以拦错,不能代替现场判断
电子表单适合阻止明确无效的输入。它可以自动带入城市和 shop_id,检查 combo_id 是否重复,只在 validation_subset = 1 时显示参照测量字段,并拒绝负价格。它也可以要求 portion_measured = 1 时存在称重记录,要求总分等于五个分项之和。
营养数值却不宜一律硬拦。有人输入 protein_g = 140,系统可以警告“是否把 14.0 误写成 140”,要求核对单位和来源;一份特别大的组合也可能真的很高。程序若未经确认自动改成 14,就把一个看得见的异常变成了没有痕迹的猜测。规则负责指出矛盾,不负责为了让页面全绿而选一个更顺眼的答案。
AI 可以在每天收工后整理疑似单位错误、字段冲突和待核照片,生成一张问题单。质控员仍要回到菜单照片、称重记录或店家补充资料判断。店家没有给配方时,钠值继续保持未知,不能让模型按照相似餐名填一个“合理数字”。问题单缩短的是寻找异常的时间,不是事实核对的责任。
有些异常只有把几列放在一起才看得见。validation_subset = 0 却出现参照蛋白质,可能是子样本标记错了,也可能是参照值贴到了错误早餐;portion_measured = 1 却找不到称重照片,也不能直接把标记或照片任选一个删掉。系统应把整行挂起,显示冲突来自哪两项,等待证据决定。逻辑校验的任务是保留问题,绝不是替研究者制造一致。
模拟数据中还有一列 latent_pattern,表示生成虚拟早餐时使用的隐藏模式。现实调查员看不见它,它也不是研究采集变量。若分析模型使用这列,就等于把数据生成者掌握的“出题答案”提前交给算法,造成信息泄漏。正式分析库必须排除它,模拟说明则应保留它的来源。删列和留档同时存在,才能既防止模型作弊,又不掩盖数据怎样生成。
结构化字段之外,现场还要允许备注和证据附件。固定选项使 1,200 份记录可以比较,照片和文字则保留新型组合或边界情形的原貌。只收标准选项,研究者以后不知道调查员看见了什么;只收照片,又无法稳定计算。数据质量来自两类材料相互核对,而不是一方取代另一方。
预测试就是要让手册先失败
预测试若只是确认按钮能不能点击,几乎一定会错过最有价值的问题。团队需要从四类门店取不同组合,让两名调查员独立记录,再比较食品分类、份量、价格和配方来源。豆沙包算不算明确蛋白质食物,咸豆花里的少量葱花算不算蔬菜,套餐里可以加购的鸡蛋是否属于原组合,这些争议才会暴露操作定义的空洞处。
遇到分歧,不能只在会上宣布一个答案。两人的原判断、争议原因、最后决定和修改过的手册版本都要留下,再拿一批新的早餐检验修订后的规则。若新调查员仍在同一边界上分歧,说明规则没有写清;若只让参加过会议的人重填,大家可能只是记住了答案,而不是学会了判断。
培训也应使用这些真实边界记录,让调查员先独立作答,再讨论依据。只演示输入框在哪里,测不出六地对“整份组合”“明确蛋白质食物”和“配方估算”的理解是否一致。预测试的成功,不是零分歧,而是正式采集前已经知道分歧会出现在哪里,并有办法记录它。
正式采集开始后,质控要看现场仍能补救的问题。若某个城市突然有 80% 的份量未实测,应当在调查员还在当地时检查设备、权限和规则理解,而不是全部结束后把该城删掉。抽样名单有多少店、完成店铺理论上有多少组合、数据库有多少唯一编号、关键字段为何为空,需要每天相互对上。
例如,当天完成 30 家店,按照每店五份应当对应 150 个唯一早餐编号,数据库却只有 147 行。缺少的三行可能仍在设备离线队列里,也可能有两个重复编号覆盖了提交,还可能是门店实际没有五份合格组合。质控员要沿同步日志和现场记录查清原因,不能为了让数字对上复制三行早餐。流程数字不是业绩目标,而是寻找数据断点的线索。
调查员之间的差异也不能见到就判错。负责摊点较多的调查员可能自然有更高配方估算率,应先在城市和店铺类型相近的情况下比较,再抽查原始材料。120 份复核子样本同样按预先随机名单执行,不能因为某份早餐难称,就换成旁边更整齐的一份。否则复核只会证明容易测的早餐容易测。
修改没有问题,让旧值消失才有问题
现场或质控发现错误,当然应该修改。sodium_mg 从 720 改成 1,020 时,需要保存原值、新值、修改时间、修改人、理由和证据链接,让后来的人知道是店家补发配方,还是单位换算被纠正。若新值直接覆盖旧值,论文只剩最后那个数字,无法判断它经历过什么。
原始提交库因此保持只读,核查后的修订进入清洁版本,派生字段由代码重建。分析库冻结为 v1.0 后若发现一项确认错误,可以生成 v1.1,附上变更说明并重跑所有派生结果。冻结不是以后永远不许纠错,而是给每张表格一个稳定参照,避免同名文件在不同时刻悄悄改变。
这也意味着一次修正可能影响不止一格。钠值改变后,钠分项、营养总分和低于 6 分标记都要由同一脚本重新生成;相关表格和模型若已经运行,也要注明是否随新版本更新。手工只改最终标签,会让同一行里的原始营养值与总分互相矛盾,问题从一个录入错误变成整套结果无法复算。
数据版本还要与代码、字典和生成时间对应。文件可以计算一种只要内容改变就会随之改变的校验值,用来发现传输或手工打开后发生的意外修改。相比 final_final2.xlsx 这样的文件名,版本号、校验值和变更记录真正回答了“论文使用的是哪一份数据”。
FAIR 原则强调数据及说明信息应当可发现、可访问、可互操作、可重用。这不等于所有内容无条件公开。门店精确位置、联系人和未公开配方可以放在受控映射表中,对外分析数据只保留编码店铺号,同时提供字典、计算规则、版本和访问条件。可追溯与隐私保护并不冲突,关键是权限本身也被说明。
STROBE要求观察性研究交代变量、数据来源、偏倚、缺失和分析样本。报告阶段能否回答这些问题,取决于采集时是否留下依据。等写论文才发现缺失原因从未记录,任何写作技巧都补不回来。
分析人员最后收到的,可以包含尚无法确认的空白,却不能包含一批找不到来源的漂亮数字。数据是否“干净”,不看每格是否填满,而看每个值和每个空白能否说明自己怎样来到这里。清洗只能处理已经留下的材料;真正的数据质量,早在现场有人决定这一格该填什么时就已经发生。