SAS中删除数据集中grade列为非数值的记录的问题咨询
SAS删除grade列非数值记录的解决方法
问题根源
你当前的代码在input阶段已经将grade定义为数值型变量,所有非数值内容(A/E/C等)在读入时就会被转换为数值缺失值.,因此直接对数值型grade使用anyalpha()函数本身就无法检测到原始的字母内容,同时你的判断逻辑也完全写反。
解决方案1:直接删除数值缺失行(适配现有读入逻辑)
你之前尝试的if grade=. then delete;逻辑本身是成立的,如果未生效可以检查是否逻辑写反,推荐使用更稳妥的nmiss()函数覆盖所有数值缺失场景:
data student_cleaned; set work.student; /* 只要grade是数值缺失就删除,覆盖普通缺失/特殊缺失类型 */ if nmiss(grade) > 0 then delete; run;
运行后保留的就是grade为合法数值的行。
解决方案2:先读为字符型再校验(更稳妥,无遗漏)
如果需要精准判断原始内容是否为纯数字,避免空格、特殊符号导致的误判,可以先将grade按字符型读入,校验通过后再转数值:
- 修改数据集读入代码,将grade设为字符型:
data student; infile datalines firstobs=2 dsd truncover; /* grade后加$,按字符型读入 */ input student$ class$ grade $; datalines; student, class, grade Jansen, Brave, A Yassin, Brave, 70 Benison, Brave, 67 Yan Jin, Brave, E James, Hero, 90 Michelle, Hero, 89 Hiroku, Hero, C Misoku, Hero, 93 ; run;
- 清洗时删除非纯数字的行:
data student_cleaned; set work.student; /* notdigit返回第一个非数字字符的位置,返回0则为纯数字,非0直接删除 */ if notdigit(trim(grade)) ^= 0 then delete; * 可选:将校验通过的grade转回数值型方便后续统计; grade_num = input(grade, best32.); drop grade; rename grade_num = grade; run;
原有代码不生效的原因
anyalpha()要求输入为字符型变量,你传入数值型grade时SAS会自动按默认格式转字符,结果不可控- 逻辑完全写反:你写的
if not (anyalpha(grade)) then delete;含义是「如果grade中没有字母就删除」,和你要删除非数值(带字母)行的需求完全相反 - 非数值内容在读入阶段已经被转为缺失值,
anyalpha()无法检测到原始的字母内容
内容的提问来源于stack exchange,提问作者xiaver vincent
相关产品推荐
相关产品推荐

