07.IF和WHERE语句(一)IF-THEN语句一、基础语法做选择时需要用到条件语句:若满足……条件,则执行……语法:if条件then执行语句;若有多个执行语句,则用if条件thenDO;执行语句1;执行语句2;END;多选择分支,则用if条件then执行语句;elseif条件then执行语句;else执行语句;SAS中常用的比较、逻辑算符(也见系列02):符号含义示例=或eq等于name='Jones,C.';^=或ne不等于temp^=212;或gt大于income20000;或lt小于partnoBG05;=或ge大于等于id='1543';=或le小于等于pulse=85contains或?包含firstnamecontains'Jon';in属于actlevelin('LOW','MOD');feein(124.80,178.20);and且age=55andpulse75;or或area='A'orregion='S';二、数据步中使用IF-THEN语句赋值数据步中经常需要有选择地赋值新变量或修改原数值。例1稀有古董汽车拍卖的数据文件(C:\MyRawData\Auction.dat)包含了品牌、型号、制造年份、座位数、价格(百万美元):使用IF-THEN语句填满缺失值,并创建一个新变量Veteran.代码:dataoldcars;infile'c:\MyRawData\Auction.dat';inputMake$1-13Model$15-29YearMadeSeatsMillionsPaid;ifYearMade1890thenVeteran='Yes';ifModel='F-88'thenDO;Make='Oldsmobile';Seats=2;end;run;procprintdata=oldcars;title'CarsSoldatAuction';run;运行结果:二、数据步中使用IF-THEN语句创建子数据集(也见系列03)1.数据步读入数据时,用IF-THEN语句选择满足条件的数据读入。语法:if条件;如果“条件”为真,则数据步将继续执行。还可以使用DELETE语句,来删除哪些不要的数据:下面这两句话是等价的:ifSex='f';ifSex='m'thenDELETE;例2莎士比亚歌剧的清单(C:\MyRawData\Shakespeare.dat),包含歌剧名、首次表演年份、类型:读取数据,并且用IF语句构造一个只包含喜剧(comedies)的子集:代码:datacomedy;infile'c:\MyRawData\Shakespeare.dat';inputTitle$1-26YearType$;ifType='comedy';run;procprintdata=comedy;title'ShakespeareanComedies';run;运行结果:2.数据步中用IF-THEN语句创建多个数据集若想在一个数据步中创建多个数据集,在DATA语句后面多接几个数据集名即可。用IF-THEN语句可以分别将数据写入不同的数据集。例3动物园给动物喂食的数据(C:\MyRawData\zoo.dat),变量为动物类型、生物学分类、居住区域、喂食时间(上午/下午/两者):读入数据并输出两个列表,一个是早上喂食,一个是下午喂食。代码:datamorningafternoon;infile'c:\MyRawData\Zoo.dat';inputAnimal$1-9Class$11-18Enclosure$FeedTime$;ifFeedTime='am'thenoutputmorning;elseifFeedTime='pm'thenoutputafternoon;elseifFeedTime='both'thenoutput;/*每个数据集都输出,省略数据集名*/run;procprintdata=morning;title'AnimalswithMorningFeedings';procprintdata=afternoon;title'AnimalswithAfternoonFeedings';run;运行结果:三、用IF-THEN语句将观测值分组对观测值分组,实际上只是为每个观测值分配一个分组标签,用新的列变量存储分组标签,这样后续就可以借助分组关键词(class),对数据做分组处理。例4住房改善的数据(C:\MyRawData\home.dat),包括了姓名、改善工作、改善成本:读取数据,并新建了一个CostGroup的变量。根据Cost的值将数据分成high、medium、low和missing三类。代码:datahomeimprovements;infile'c:\MyRawData\Home.dat';inputOwner$1-7Description$9-33Cost;ifCost=.thenCostGroup='missing';elseifCost2000thenCostGroup='low';elseifCost10000thenCostGroup='medium';elseCostGroup='high';run;procprintdata=homeimprovements;title'HomeImprovementCostGroups';run;运行结果:程序说明:缺省值要单独分组,否则将归类到low类(缺省值默认是最小值,甚至比负数都小)。(二)WHERE语句二、基本语法WHERE语句和IF语句作用基本相同,不同在于IF语句只用于数据步,WHERE语句还可用于过程步(不创建新数据集),作用是让“只有满足条件的观测值被proc过程处理”。语法:where条件;例5画家信息的数据文件(C:\MyRawData\Artists.dat),包括画家姓名、流派、国别:读入数据,只输出流派为Impressionism的画家。代码:datapainters;infile'c:\MyRawData\Artists.dat';inputName$1-21Genre$23-40Origin$42;run;procprintdata=painters;whereGenre='Impressionism';title'MajorImpressionistPainters';footnote'F=FranceN=NetherlandsU=US';run;运行结果:二、更灵活的应用:“(WHERE=(条件))”作为选项同样的功能,WHERE语句作为选项,用起来更加灵活。语法:(WHERE=(条件))示例:datagone;setanimals(WHERE=(Status='Extinct'));datauncommon(WHERE=(StatusIN('Endangered','Threatened')));setanimals;procimportdatafile='c:\MyRawData\Wildlife.csv'out=animals(WHERE=(Class='Mammalia'))REPLACE;procprintdata=animals(WHERE=(Habitat='Riparian'));procexportdata=animals(WHERE=(Status='Threatened'))outfile='c:\MyRawData\Wildlife.xls';注意:set关键词表示从数据集animals中创建数据。例6山脉数据(C:\MyRawData\Mountains.dat)包括名称、位置、高度:读入数据,分别输出高度6000,以及位于美洲的山脉。代码:datatallpeaks(WHERE=(Height6000))american(WHERE=(ContinentCONTAINS('America')));infile'c:\MyRawData\Mountains.dat';inputName$1-14Continent$15-28Height;run;procprintdata=tallpeaks;title'MembersoftheSevenSummitsabove6,000Meters';run;procprintdata=american;title'MembersoftheSevenSummitsintheAmericas';run;运行结果:(三)IF与WHERE的区别将数据集SASHELP.workers第10到15条观测中满足条件ELECTRIC260的观测提取出来,生成新的数据集tmp。代码1:datatmp;setSASHELP.workers(firstobs=10obs=15);ifELECTRIC260;run;procprintdata=tmp;title'IFStatement';run;运行结果(4条记录):代码2:datatmp;setSASHELP.workers(firstobs=10obs=15);whereELECTRIC260;run;procprintdata=tmp;title'WHEREStatement';run;运行结果(6条记录):上述两种方法为什么输出结果不一样?请注意IF语句和WHERE语句的区别:(1)IF语句是面向“程序数据向量”(ProgramDataVector)的,对当前PDV中的数据进行判断,满足条件时将其写入到外部数据集;WHERE语句也是面向PDV的,它使用于从外部数据源读数据到PDV之前进行判断,当满足条件时才被写入到PDV。显然一个在写入PDV之前,一个在写入PDV之后,两者是有差异的。(2)当没有数据集选项firstobs=10obs=15时,IF语句和WHERE语句用法和结果相同,但有这两个选项时效果就不同了。有这两个选项,IF语句是从原数据集(或数据源)的观测记录进行计算个数,即从原数据集的第10个观测开始读入到PDV中,然后再判断是否满足IF条件,若满足则输出到外部数据集,直到原数据集的第15个观测结束(满足条件的只有4个)。而WHERE语句是在读入到PDV之前就进行判断的,所以这里的firstobs的意思是从使得满足WHERE条件的第10个观测开始,而不是原数据集的第10个观测开始,直到满足WHERE条件的第15个观测结束(共6个)。