SAS条件输入语句疑问:Ruth对应的IDNUM为何是22而非11?
为什么Ruth的IDNUM取值是22而非11?
要搞懂这个问题,核心得掌握SAS 输入指针的移动规则 和 infile 默认的 flowover 选项行为:
1. 先明确原始数据的列结构
结合你给出的行号标记----I----10---I----20---I----30,原始数据的列位置对应关系如下:
- 第1-4列:员工姓名
- 第7-8列:员工年龄
- 第10-11列:员工ID
每一行的具体数据:
行1: Ruth 39 11 → 第10-11列对应值为11 行2: Jose 32 22 → 第10-11列对应值为22 行3: Sue 30 33 行4: John 40 44
2. 逐步骤拆解程序执行逻辑
我们聚焦Ruth所在行的处理流程:
- 读取姓名后指针的位置:执行
input employee_name $ 1-4;时,SAS读取第1-4列得到Ruth,此时输入指针停在第4列的末尾(也就是第5列的位置)。 - 条件分支的关键问题:因为
employee_name = 'Ruth'为真,程序执行input idnum 10-11;。- 这里的核心点:SAS的列输入是基于绝对列号定位的,但默认的
flowover选项有个特性——如果当前行的列数不足以满足input语句的读取需求,SAS会自动跳转到下一行继续读取数据。 - 你的第一行数据
Ruth 39 11实际长度不足11列(第11列没有有效内容),当SAS尝试读取第10-11列时,当前行无法提供足够数据,于是自动将第二行Jose 32 22加载到输入缓冲区。 - 此时第10-11列对应的就是第二行的ID值
22,所以idnum被赋值为22。
- 这里的核心点:SAS的列输入是基于绝对列号定位的,但默认的
- 对后续观测的影响:由于第二行的数据已经被提前读取,下一次data步循环会直接加载第三行(Sue的行),导致Jose的观测被跳过。
3. 如何修正得到预期结果
如果你希望Ruth的IDNUM能正确读取第一行的11,只需给infile语句添加truncover选项——这个选项会让SAS在当前行列数不足时,仅读取当前行存在的内容,不会跳转到下一行:
data test; infile 'employee' truncover; input employee_name $ 1-4; if employee_name = 'Ruth' then input idnum 10-11; else input age 7-8; run;
内容的提问来源于stack exchange,提问作者Yesh
相关产品推荐
相关产品推荐

