在SAS中,where和if的区别,应该算是一个经典问题了,论坛中也有各位大神做了较为详细的解释……
准确来说if语句应该是指有筛选观测功能的子集if语句。其实where和if的主要区别主要体现在两者不同的作用区域。
在DATA步中,SAS处理数据主要通过PDV这个数据结构,而且where和if的区别就围绕着PDV来进行的。
where语句的作用范围在PDV之前,也就是数据进入PDV前先行筛选,未满足where条件的不会进入PDV,也就不会进行后续处理。
这也是楼主所举例中题目的核心。 BMI不是set语句后输入数据集中存在的变量,是用赋值语句新建立的变量,where语句在PDV前先行筛选数据,此时BMI对于where语句是不可见的,也就会报错了。总结为简单一句话,where语句后条件表达式中所出现的变量必须是输入数据集中所存在的变量。也正因为如此,如果非要使用新建立的变量进行筛选,可以考虑使用子集if语句代替。这样也可以解释,为什么子集if语句同if.then.else条件选择语句长得很像,但是作用却完全不一样了……这个扯远了,以后有机会再议……
而if语句是作用在PDV之上的,所有进行计算的变量全部都存在于PDV里。简单一句话,if语句对于其后的变量没有任何限制要求。
说到这里,肯定会有疑问了,如果if语句这么好,为什么不完全用if来代替where呢……正因为where语句作用在PDV前,所以可以极大的提升程序执行的效率。比如原输入数据集有1000万条观测,而只需要对其中满足条件的50条观测进行计算,用where语句进行观测筛选,进入PDV计算的只有50条观测数据。而用if的话,1000万条观测需要都进入PDV后才会开始筛选,效率孰优孰劣,一目了然……
而除去DATA步以外,其他PROC步并没有PDV这种数据结构,所以相应的也就只能使用where不能使用if,或者说不能使用提供筛选观测能力的子集if语句了……
如果简单记忆,不想了解原理,熟记下面这个表的用法就够了……
另,附上sas论文中关于where和if的解释,还有supersasmacro大神的博客解释。
where vs if------where与if的区别 http://blog.sina.com.cn/s/blog_5d3b177c0100b67o.html
WHERE vs. IF Statements
http://www2.sas.com/proceedings/sugi31/238-31.pdf