SAS筛选FY17日期范围数据返回空表问题排查请求
首先,我们来拆解你遇到的问题:
1. 为什么最初的代码返回空表?
你写的 where date_occur between 10/01/2016 and 09/30/2017; 里,SAS把 10/01/2016 当成了数学除法运算,而不是日期。计算下来就是 10 ÷ 1 ÷ 2016 ≈ 0.00496,09/30/2017 是 9 ÷ 30 ÷ 2017 ≈ 0.000148。你的 date_occur 要么是字符型的日期字符串,要么是SAS标准日期值(比如'01oct2016'd对应的数值是20755,远大于这个小数范围),自然没有匹配的观测,所以返回空表。
2. 为什么用'10/01/2016'd也无效?
这说明你的 date_occur 并不是SAS标准日期值(数值型,存储的是从1960年1月1日开始的天数),而是字符型变量——也就是它存储的是类似"10/23/2014"这样的字符串,只是可能被你错误地赋予了MMDDYY10.格式(字符型变量不能使用数值日期格式,这种情况下格式不会生效)。当你用字符型变量和SAS日期值(数值)做比较时,SAS会自动把字符转换成数值,而大部分日期字符串转数值会变成缺失值,所以依然没有匹配的观测。
解决方案
首先,用proc contents确认date_occur的变量类型和格式:
proc contents data=y16_17; run;
情况A:date_occur是字符型变量
需要先把字符日期转换成SAS标准日期值,再进行筛选:
data fy17; set y16_17; /* 将字符日期转换为SAS日期值 */ date_occur_sas = input(date_occur, mmddyy10.); /* 筛选FY17:2016年10月1日到2017年9月30日 */ where date_occur_sas between '01oct2016'd and '30sep2017'd; run;
或者更简洁地直接在where语句里转换:
data fy17; set y16_17; where input(date_occur, mmddyy10.) between '01oct2016'd and '30sep2017'd; run;
情况B:date_occur是数值型,但不是SAS日期值
比如它存储的是类似10232014(MMDDYYYY格式的数字),那需要先把它转换成字符,再转成SAS日期值:
data fy17; set y16_17; date_occur_sas = input(put(date_occur, 8.), mmddyy10.); where date_occur_sas between '01oct2016'd and '30sep2017'd; run;
额外提示
SAS日期的'ddmmmyyyy'd格式(比如'01oct2016'd)比'mm/dd/yyyy'd更不容易出错,建议优先使用这种写法避免格式歧义。
内容的提问来源于stack exchange,提问作者mbs23

