楼主: foocares
2797 8

[问答] 用If和Where实现subset的异同? [推广有奖]

  • 0关注
  • 5粉丝

博士生

93%

还不是VIP/贵宾

-

威望
0
论坛币
548 个
通用积分
0
学术水平
28 点
热心指数
26 点
信用等级
24 点
经验
10891 点
帖子
299
精华
0
在线时间
158 小时
注册时间
2017-4-12
最后登录
2018-2-26

相似文件 换一批

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
近来复习时有一点疑惑,望各位老师解答。
给人的感觉似乎If和Where语句都可用来控制分类。

用where实现subset例子可见于sas base 70题里的第25题:
proc print data=SASHELP.CLASS(firstobs=5 obs=15);
where Sex='M';
-------------------
run;

这里我们知道只有性别为男才会被proc print执行。

用if来实现subset例子同样可见于sas base 70题里的第20题:
data WORK.OUTDOOR WORK.CLOTH WORK.EQUIP;
set WORK.PRODUCTS;
if Sales GT 30;

------------------
这里我们知道只有sales大于30的才会往下执行。

那么,这两者能互换使用吗?还是说,where来控制subset时只能在proc step里,而用if来筛选时只能在data step?
手头机器SAS被卸载了不能跑,所以求解惑一下,多谢!

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:Subset Where HERE subs Set

回帖推荐

lava_mb 发表于4楼  查看完整内容

在SAS中,where和if的区别,应该算是一个经典问题了,论坛中也有各位大神做了较为详细的解释…… 准确来说if语句应该是指有筛选观测功能的子集if语句。其实where和if的主要区别主要体现在两者不同的作用区域。 在DATA步中,SAS处理数据主要通过PDV这个数据结构,而且where和if的区别就围绕着PDV来进行的。 where语句的作用范围在PDV之前,也就是数据进入PDV前先行筛选,未满足where条件的不会进入PDV,也就不会进行后续处理。 ...
沙发
foocares 发表于 2017-4-15 00:07:38 |只看作者 |坛友微信交流群
正好在看base 95题里的第94题,似乎印证了这个疑问:

94. Given the following SAS error log
44 data WORK.OUTPUT;
45 set SASHELP.CLASS;
46 BMI=(Weight*703)/Height**2;
47 where bmi ge 20;
ERROR: Variable bmi is not on file SASHELP.CLASS.
48 run;
What change to the program will correct the error?
A. Replace the WHERE statement with an IF statement
B. Change the ** in the BMI formula to a single *
C. Change bmi to BMI in the WHERE statement
D. Add a (Keep=BMI) option to the SET statement

所以答案是A吗?where用来实现subset的条件是放在proc step里?

使用道具

藤椅
foocares 发表于 2017-4-15 01:06:52 |只看作者 |坛友微信交流群
自己又思考了下base的第94题。
其实问题不在where作用的范围,where是既可以在proc也可以用在data step里的(反之,if subset却只能作用于data step)
症结在于,bmi是这个data step里新创建的变量。而where语句试图从前头的SASHELP.CLASS这个set里去筛选,可bmi压根不在原set里所以报错。
因此换成if才能做判断筛选新变量。

答案C有一定的诱惑性,但SAS根本不在乎执行时变量的大小写。(除非是严格的字符比较)

这题真是满满的恶意和坑呐!

使用道具

板凳
lava_mb 发表于 2017-4-17 14:45:29 |只看作者 |坛友微信交流群
在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语句了……

如果简单记忆,不想了解原理,熟记下面这个表的用法就够了……
where.png

另,附上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
已有 2 人评分论坛币 学术水平 热心指数 信用等级 收起 理由
admin_kefu + 20 热心帮助其他会员
foocares + 1 + 1 + 1 精彩帖子,很有帮助

总评分: 论坛币 + 20  学术水平 + 1  热心指数 + 1  信用等级 + 1   查看全部评分

使用道具

报纸
foocares 发表于 2017-4-17 22:47:13 |只看作者 |坛友微信交流群
楼上解释得太棒了,很详尽,我要打出来对着看。
拜谢!

使用道具

地板
foocares 发表于 2017-4-17 22:56:20 |只看作者 |坛友微信交流群
再向大佬追问一句,我发现put也只能作用在data步里面,用于调试时临时打印验证下数据值,功能类似万能的python print语句。
那如果我想在proc步里做类似的事,该用啥?这纯粹是因为之前的编程习惯,就喜欢在调试时分段到处打印标记来看程序跑到哪段了,大致结果对不对。

使用道具

7
lava_mb 发表于 2017-4-19 11:07:06 |只看作者 |坛友微信交流群
[quote]foocares 发表于 2017-4-17 22:56 http://blog.sina.com.cn/s/blog_5d3b177c0100bqny.html
已有 1 人评分学术水平 热心指数 信用等级 收起 理由
foocares + 1 + 1 + 1 精彩帖子

总评分: 学术水平 + 1  热心指数 + 1  信用等级 + 1   查看全部评分

使用道具

8
foocares 发表于 2017-4-20 01:03:17 |只看作者 |坛友微信交流群
lava_mb 发表于 2017-4-19 11:07
foocares 发表于 2017-4-17 22:56 http://blog.sina.com.cn/s/blog_5d3b177c0100bqny.html
已收藏该博客文章备用,多谢!

使用道具

9
lava_mb 发表于 2017-4-20 12:15:06 |只看作者 |坛友微信交流群
不好意思,之前的帖子不知道为什么被改动过了,内容全没了,只剩下外链……我再尝试着回忆一下内容吧……

程序的调试和除虫是编程人员最为常用也是很需要经验积累的一项工作。在SAS中使用Debug功能主要是针对DATA步而言,因为DATA步是一次执行完所有程序,所以需要设置断点或者使用你提到的put语句,把程序的执行过程和变量变化过程呈现出来,便于调试。所以在SAS中Debug功能大多是针对DATA步的。Debug过程没有一定之规,怎么方便排查错误怎么操作,当然除了简单使用put语句在日志中显示变量的值或者提示语句,也可以用DATA步中标准的Debugger工具,会使用到一系列的语句和操作。具体用法详见SAS论文。
How to Use the Data Step Debugger(http://www2.sas.com/proceedings/sugi25/25/btu/25p052.pdf)
An Animated Guide : The Data Step Debugger (http://www.lexjansen.com/nesug/nesug04/hw/hw05.pdf)
(貌似有点跑题,不过DATA中的debug确是重头戏)……

除了DATA步中的Debug功能,也可以使用Options中的一些选项,进行调试功能,比如针对宏变量和宏语句的MLOGIC,MPRINT,SYMBOLGEN等等……或者使用程序员编好的一些自制宏debugger,比如(
自制SAS代码Debugger,调试利器 https://bbs.pinggu.org/thread-2503861-1-1.html)

对于楼主所说的PROC过程步,因为本身就是交互执行的,这点与DATA步不同。不执行quit语句,程序会一直处在运行状态。而PROC步中默认一般是不生成数据集或者表的,每执行一段程序会直接呈现结果。所以一般调试PROC步,可以尝试一段代码一段代码的运行,根据结果进行修改,当调试完成后,再把结果保存成数据集或打印报表,并运行quit结束程序。当然这个做法可能更适合PROC SQL和PROC IML步……对于不同的PRCO步,还有不同调试方法,比如在PROC SQL中,可以使用VALIDATE关键字和NOEXEC选项进行调试。对于其他PROC步,其具体选项和参数要参阅help文档进行查询。关于PROC步中的Debug技巧,我也再继续积累经验……

最后还是推荐大神的博客:
SAS Debug测试专题之一:SAS Debug测试初级手册
http://blog.sina.com.cn/s/blog_5d3b177c0100bqny.html
(博客中并没有翻译完全,所以建议还是看原SAS论文。另,SAS论文库中关于Debug的文章不太多也可以查看一下。借鉴一下别人的技巧和经验……)

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-4-26 17:32