(一):数据的导入、数据结构
标题有些噱头,不过这里的重点是: speak SAS in 7 days。也就是说,知识是现成的,我这里只是要学会如何讲这门语言,而不是如何边学SAS边学模型。顺便发现我最近喜欢写连载了,自从西藏回来后…..
之所以下定决定学SAS,是因为周围的人都在用SAS。为了和同事的沟通更有效率,还是多学一门语言吧。R再灵活,毕竟还是只有少数人能直接读懂。理论上语言是不应该成为障碍的~就像外语一样,多学一点总是好的,至少出门不发怵是不是?
最后一根稻草则是施老师传给我的一个link:http://blog.softwareadvice.com/articles/bi/3-career-secrets-for-data-scientists-1101712/,据说有数据分析师的职业秘笈…我就忍不住去看了看。其中一句话还是蛮有启发的:
如果有人问你要学什么工具,是SAS,R,EXCEL,SQL,SPSS还是?直接回答:所有。
这个答案一方面霸气,一方面也是,何必被工具束缚呢?
这东西宜突击不宜拖延,所以还是集中搞定吧。七天应该是个不错的时间段。
大致分配如下:
1. 熟悉SAS的数据结构,如基本的向量,数据集,数组;熟悉基本的数据类型,如文本,数字。
2. 熟悉基本的数据输入与输出。
3. 熟悉基本的逻辑语句:循环,判断
4. 熟悉基本的数据操作:筛选行列,筛选或计算变量,合并数据集,计算基本统计量,转置
5. 熟悉基本的文本操作函数
6. 熟悉基本的计量模型函数
7. 熟悉基本的macro编写,局部变量与全局变量
其实这大概也是按照我常用的R里面完成的任务来罗列的。基本计划是完成就可以大致了解SAS的语法了,其他的高级功能现用现学吧。
书籍方面,中文的抢了同事的一本《SAS编程与数据挖掘商业案例》,英文的找了一本「Applied Econometrics Using The SAS System」和「The Little SAS Book」,先这么看着吧。
后知后觉的补充:其实这一系列笔记都是先写再发布的,主要是方便我调整顺序什么的。事实证明绝大多数时间我在看(或者更直接的,抄)「The Little SAS Book」这本书,姚老师的《SAS编程与数据挖掘商业案例》简单看了一晚,作为对于SAS语法的预热。最后那本「Applied Econometrics Using The SAS System」更多是看具体模型的用法了,不是熟悉语法的问题了。例子都是第一本little book上的,很好用。
——-笔记开始——-
SAS的数据类型
首先,sas的编程大概就两块:Data和PROC,这个倒是蛮清晰的划分。然后目前关注data部分。
SAS的数据类型还真的只有两种:数字和文本。那么看来日期就要存成文本型了。变量名称后面加$代表文本型。
SAS的数据读入
手动输入这种就不考虑了,先是怎么从本地文件读入。比如我们有文本文件如下:
Lucky 2.3 1.9 . 3.0 Spot 4.6 2.5 3.1 .5 Tubs 7.1 . . 3.8 Hop 4.5 3.2 1.9 2.6 Noisy 3.8 1.3 1.8 1.5 Winner 5.7 . . .
然后SAS里面就可以用
* Create a SAS data set named toads; * Read the data file ToadJump.dat using list input; DATA toads; INFILE ’c:MyRawDataToadJump.dat’; INPUT ToadName $ Weight Jump1 Jump2 Jump3; RUN; * Print the data to make sure the file was read correctly; PROC PRINT DATA = toads; TITLE ’SAS Data Set Toads’; RUN;
这样就建立了一个名为toads的临时数据集,然后读入外部文件ToadJump.dat,然后告诉SAS有四个变量,其中第一个是文本型。这样就OK了。缺失值用一个点.标记。
偶尔数据没那么规范,比如长成:
----+----1----+----2----+----3----+----4 Columbia Peaches 35 67 1 10 2 1 Plains Peanuts 210 2 5 0 2 Gilroy Garlics 151035 12 11 7 6 Sacramento Tomatoes 124 85 15 4 9 1
那么就要有点类似正则表达式的感觉,告诉SAS更多的参数:
* Create a SAS data set named sales; * Read the data file OnionRing.dat using column input; DATA sales; INFILE ’c:MyRawDataOnionRing.dat’; INPUT VisitingTeam $ 1-20 ConcessionSales 21-24 BleacherSales 25-28 OurHits 29-31 TheirHits 32-34 OurRuns 35-37 TheirRuns 38-40; RUN; * Print the data to make sure the file was read correctly; PROC PRINT DATA = sales; TITLE ’SAS Data Set Sales’; RUN;
这样SAS就可以正确的读数据了—类似于excel的导入文本-固定宽度分隔。
再不规则的话,比如有日期型的:
Alicia Grossman 13 c 10-28-2008 7.8 6.5 7.2 8.0 7.9 Matthew Lee 9 D 10-30-2008 6.5 5.9 6.8 6.0 8.1 Elizabeth Garcia 10 C 10-29-2008 8.9 7.9 8.5 9.0 8.8 Lori Newcombe 6 D 10-30-2008 6.7 5.6 4.9 5.2 6.1 Jose Martinez 7 d 10-31-2008 8.9 9.510.0 9.7 9.0 Brian Williams 11 C 10-29-2008 7.8 8.4 8.5 7.9 8.0
那么接下来就是:
* Create a SAS data set named contest; * Read the file Pumpkin.dat using formatted input; DATA contest; INFILE ’c:MyRawDataPumpkin.dat’; INPUT Name $16. Age 3. +1 Type $1. +1 Date MMDDYY10. (Score1 Score2 Score3 Score4 Score5) (4.1); RUN; * Print the data set to make sure the file was read correctly; PROC PRINT DATA = contest; TITLE ’Pumpkin Carving Contest’; RUN;
就是说,name是一个长度为16的字符;age是长度为3、无小数点的数字;+1跳过空列;type是长度为1的文本;date是MMDDYY长度为10的日期;score1-5是长度为4,小数部分为1位的数字。
还有若干更复杂的,可以遇到时侯回来查手册。此外还有@可用来直接指定开始读的列。鉴于我接触的数据一般比较规范,这些就不细看了。
此外SAS可以指定开始读的行数,读取的行数等。
DATA icecream; INFILE ’c:MyRawDataIceCreamSales.dat’ FIRSTOBS = 3; INPUT Flavor $ 1-9 Location BoxesSold; RUN;
SAS读取CSV数据
以我最关心的CSV文件为例,如下数据:
Lupine Lights,12/3/2007,45,63,70, Awesome Octaves,12/15/2007,17,28,44,12 "Stop, Drop, and Rock-N-Roll",1/5/2008,34,62,77,91 The Silveyville Jazz Quartet,1/18/2008,38,30,42,43 Catalina Converts,1/31/2008,56,,65,34
只需要:
DATA music; INFILE ’c:MyRawDataBands.csv’ DLM = ’,’ DSD MISSOVER; INPUT BandName :$30. GigDate :MMDDYY10. EightPM NinePM TenPM ElevenPM; RUN; PROC PRINT DATA = music; TITLE ’Customers at Each Gig’; RUN;
其实,貌似更简单的办法是:
DATA music; INFILE ’c:MyRawDataBands.csv’ DLM = ’,’ DSD MISSOVER; INPUT BandName :$30. GigDate :MMDDYY10. EightPM NinePM TenPM ElevenPM; RUN; PROC PRINT DATA = music; TITLE ’Customers at Each Gig’; RUN;
好吧,import果然更直接一点…excel文件也可以如法炮制。
SAS读取excel数据
* Read an Excel spreadsheet using PROC IMPORT; PROC IMPORT DATAFILE = 'c:MyExcelFilesOnionRing.xls' DBMS=XLS OUT = sales; RUN; PROC PRINT DATA = sales; TITLE 'SAS Data Set Read From Excel File'; RUN;
如果需要SAS永久存着这些数据,则需要先指定libname:
LIBNAME plants ’c:MySASLib’; DATA plants.magnolia; INFILE ’c:MyRawDataMag.dat’; INPUT ScientificName $ 1-14 CommonName $ 16-32 MaximumHeight AgeBloom Type $ Color $; RUN;
后期就可以直接调用啦:
LIBNAME example ’c:MySASLib’; PROC PRINT DATA = example.magnolia; TITLE ’Magnolias’; RUN;
SAS 读取Teradata数据
最后就是从teradata里面读数据,可以利用teradata fastexport特性:
libname tra Teradata user=terauser pw=XXXXXX server=boom; proc freq data=tra.big(dbsliceparm=all); table x1-x3; run;
等价于:
proc sql; connect to teradata(user=terauser password=XXXXXX server=boom dbsliceparm=all); select * from connection to teradata (select * from big); quit;
暂时没有fastload的需求,就先这样吧。可以参见SAS的TD手册:http://support.sas.com/resources/papers/teradata.pdf
(二):基本操作(判断、运算、基本函数)
SAS生成新变量
SAS支持基本的加减乘除,值得一提的是它的**代表指数,而不是^。
* Modify homegarden data set with assignment statements; DATA homegarden; INFILE 'c:MyRawDataGarden.dat'; INPUT Name $ 1-7 Tomato Zucchini Peas Grapes; Zone = 14; Type = 'home'; Zucchini = Zucchini * 10; Total = Tomato + Zucchini + Peas + Grapes; PerTom = (Tomato / Total) * 100; RUN; PROC PRINT DATA = homegarden; TITLE 'Home Gardening Survey'; RUN;
但是如果有缺失值的话,SAS的加法会生成缺失值而不是自动按0处理。为了避免这一点,应该调用sum()函数而不是直接写+。
SAS的函数调用很简单:
AvgScore = MEAN(Scr1, Scr2, Scr3, Scr4, Scr5); DayEntered = DAY(Date); Type = UPCASE(Type);
函数有文本类、数字类、日期类等等。
SAS文本类函数
- ANYALNUM(arg,start):返回第一次出现任意数字或字母的位置,可选开始位置start。
- ANYALPHA(arg,start):返回第一次出现任意字母的位置,可选开始位置start。
- ANYDIGIT(arg,start):返回第一次出现任意数字的位置,可选开始位置start。
- ANYSPACE(arg,start):返回第一次出现任意空白的位置,可选开始位置start。
- CAT(arg-1,arg-2,…arg-n):连接字符串,留下头尾空白。
- CATS(arg-1,arg-2,…arg-n):连接字符串,删除头尾空白。
- CATX(‘separator-string’, arg-1,arg-2,…arg-n):连接字符串,删除头尾空白并用指定标点连接。
- COMPRESS(arg, ‘char’):移除字符串中的空格和可选字符。
- INDEX(arg, ‘string’) :返回指定字符在变量中的位置。
- LEFT(arg) :字符串左对齐。
- LENGTH(arg):返回字符串长度,不考虑尾部空格。
- PROPCASE(arg) :首字母大写。
- SUBSTR(arg,position,n):从字符串中提取指定开始位置指定长度字符。
- TRANSLATE(source,to-1, from-1,…to-n,from-n):替换字符。
- TRANWRD(source,from,to) :替换字符串。
- TRIM(arg):删除尾部空白。
- UPCASE(arg):替换成大写。
SAS数值函数
- INT(arg):返回整数。
- LOG(arg):自然对数。
- LOG10(arg) :10为底对数。
- MAX(arg-1,arg-2,…arg-n) :最大值
- MEAN(arg-1,arg-2,…arg-n) :均值
- MIN(arg-1,arg-2,…arg-n) :最小值
- N(arg-1,arg-2,…arg-n) :非缺失值个数
- NMISS(arg-1,arg-2,…arg-n) :缺失值个数。
- ROUND(arg, round-off-unit) :保留几位小数。
- SUM(arg-1,arg-2,…arg-n):求和。
SAS日期函数
- DATEJUL(julian-date) :标准julian日期到SAS日期。
- DAY(date):返回「日」。
- MDY(month,day,year) :年月日到SAS日期。
- MONTH(date) :返回「月」。
- QTR(date):返回季度。
- TODAY():今日
- WEEKDAY(date):返回周几(周日为1)。
- YEAR(date):返回「年」。
- YRDIF(start-date,end- date,’ACTUAL’):返回相差年份。
SAS中判断语句
如果,则:
IF then: IF Model = 'Mustang' THEN Make = 'Ford';
还可以执行多项命令,需要嵌套do;可以用and和or:
IF Year IF Model = 'Corvette' OR Model = 'Camaro' THEN Make = 'Chevy'; IF Model = 'Miata' THEN DO; Make = 'Mazda'; Seats = 2; END;
还可以if else:
IF Cost = . THEN CostGroup = 'missing'; ELSE IF Cost ELSE IF Cost ELSE CostGroup = 'high';
用if可以选择数据子集:
IF Sex = 'f'; IF Sex = 'm' THEN DELETE;
SAS中保留和累加
比如要求累加值(等价于R里面的cumsum),需要:
* Using RETAIN and sum statements to find most runs and total runs; DATA gamestats; INFILE 'c:MyRawDataGames.dat'; INPUT Month 1 Day 3-4 Team $ 6-25 Hits 27-28 Runs 30-31; RETAIN MaxRuns; MaxRuns = MAX(MaxRuns, Runs); RunsToDate + Runs; RUN; PROC PRINT DATA = gamestats; TITLE "Season's Record to Date"; RUN;
看一眼最终数据:
累加效果出来了~还有一栏是迄今最大值。这也是我觉得sas和R很不同的一点:sas是指针式操作,一行行往下读;而在R里面我们更多是向量或者矩阵式运算,感觉还是有所区别的…
SAS的数组操作
这个就更有点矩阵的味道了,不过还是偶尔感觉怪怪的…感觉数据整理和操纵方面,SAS还是比不上R灵活…
例子为替换为缺失值:
* Change all 9s to missing values; DATA songs; INFILE 'c:MyRawDataWBRK.dat'; INPUT City $ 1-15 Age domk wj hwow simbh kt aomm libm tr filp ttr; ARRAY song (10) domk wj hwow simbh kt aomm libm tr filp ttr; DO i = 1 TO 10; IF song(i) = 9 THEN song(i) = .; END; RUN; PROC PRINT DATA = songs; TITLE 'WBRK Song Survey'; RUN;
这样9就全部替换为缺失值了。把后面10列认为是一个数组,可以直接操作。
SAS还有若干变量名的快捷方式,暂不赘述了…
(三):基本模块调用(格式、计数、概要统计、排序等)
搞定基本的函数之后,开始鼓捣SAS里面的模型。也就是说,要开始写PROC了。说实话,越学SAS,越觉得SAS像Stata…无论是从输出的样式,还是语法。好不习惯没有()的模型调用呀。若是说SAS和Stata的区别,怕只是Stata更侧重于计量模型而SAS则是服务于大多数统计模型吧。
PROC的基本内容:CONTENT
先是一个最基本的PROC:content,可以显示数据集的主要特性。比如,
这里主要是两个声明:TITLE和FOOTNOTE。前者输出时候会产生一个标题,后者会产生尾注。用法也是比较直接的:
最后还有一个很像Stata的LABEL声明:
可以变量加注释。其实R里面给变量加注释是一件非常麻烦的事情,只有少数几个包可以搞定,还非常不值的。一般说来,我尽量在变量命名的时候长一点,这样直接可以读懂;再就是重建一个新的表,存储变量名和label。
SAS PROC求子集:WHERE
如果要在PROC里面先求子集的话,可以直接调用WHERE。感觉这里和SQL的思路比较像。用法也算是比较简单(SAS里面的用法都不是很麻烦,除了某些模型):
这样最终得到的结果就是:
SAS PROC 数据进行排序:SORT
排序就更简单了,直接PROC SORT就可以了。
这样数据就按照Family、Length(递减)排序了。
SAS PROC 输出数据:PRINT
最简单的数据输出怕就是PRINT了,顾名思义,直接打印数据出来。这里可以进行便啦的选择,还就可以选择统计量:
得到的结果为:
SAS PROC里面改变输出格式:FORMAT
基本就是FORMAT一下就可以了,再就是PUT的时候也可以调整。
输出结果为:
常用的格式有:
输出的样本见下:
当然FORMAT还可以自定义factor型变量的输出格式,比如:
就可以把数字型的1,2转换为对应的文本male和female等,还可以把变量离散化,得到的输出为:
最终可以实现的自定义输出还包括简单的文本连接,比如:
可以给出若干连续的输出(注意DATA _NULL_;将不生成任何SAS的数据表):
SAS里面总结数据:MEANS
SAS当然还有类似于excel的数据透视表和R的data.table的模块,就是MEANS。可以输出的summary statistics包括最大值、最小值、平均值、中位数、余非缺失值个数、缺失值个数、范围、标准差、和等等。此外,还可以使用BY或者CLASS进行分组统计,VAR选择变量等。
比如:
可以实现:
当然这些统计量也可以直接的写入一个SAS数据表,只需要加上一个OUTPUT就可以了。原数据:
SAS代码:
最终结果为:
SAS PROC统计频率:FREQ
计数的话,就要靠SAS里面的FREQ模块了。比如我们有一个数据集:
然后可以用FREQ来统计一些基本量:
最终会得到一个2×5的表格:
SAS PROC汇报表格:TABULATE
基本看到TABULATE就可以想到那个著名的软件Tabular了…不过貌似SAS也自带了一个类似的表格模块。这个东西可以变得非常复杂,不过鉴于我一时半会儿还用不到,所以也没有细细看。抄个例子吧。
原数据:
SAS代码:
最终结果:
类似的,还可以增加统计量(类似于MEANS那里):
可以得到:
最后还可以混合FORMAT等等,可以变得相当的复杂。貌似这东西是美国劳工部鼓捣出来的格式…
BOSS级汇报表格呈现了…
我只能感慨,不愧是商业软件啊,用户需求考虑的真的是特别的周到…这种费时费力做汇报表格的事情也被搞定了,强悍。
SAS里面的报告:REPORT
还有一个REPORT,看到有TABULATE的时候我已经不奇怪并略略的有些期待一个做报告的模块出现了。这东西基本就是前面几个的超级混合体,反正你想搞到的汇报模式总是能够搞出来的。
又是一堆数据:
然后一堆SAS代码:
然后一堆交叉计数的结果就出来了:
当然,简单的计算和分类统计也不在话下:
可以得到一个看起来很fancy的表格:
SAS数据总结综述
我的感觉是,MEANS, TABULATE和REPORT这三个模块各有千秋,基本就是可以替代EXCEL的数据透视表,虽然效率上说不好谁比谁高…随便哪一个用习惯了就好,反正又不是天天出政府报告的,我就懒得深究了。
(四):数据输出
弄清楚了基本的PROC之后,开始研究SAS的输出…毕竟有了数据处理的结果之后,还要有一个比较舒服的输出格式才可以嘛。
SAS的结果发送系统:ODS
SAS里面的输出叫的比较好听: Output Delivery System (ODS),结果发送系统。也就是说,要不停的开始研究ODS这个东西了。输出的方向包括:
基本满足要求了?当然,SAS还有模板可以选,还有追踪和选择…不着急,我们一个个来研究。
模板的话,需要调用PROC TEMPLATE:
自带了若干模板:
然后TRACE会在日志文件里面跟踪输出的对象:
这样就有日志中的记录:
最后,还可以选择ODS输出的对象:
这样就只有第一组的统计数据了。
SAS中建立输出数据表:OUTPUT
很多时候我们希望直接把结果放在另外一个SAS的数据表中,这样就需要OUTPUT声明了。
最终可以得到:
很显然,对于下面那个SAS表格的输出,我们可以像操纵普通表格一样来操纵它,各种方便省事对吧?毕竟有的时候SAS给我们的并不是我们想要的最终结果,还要各种小小加工一番才好。
SAS的输出:HTML
有的时候HTML格式的报告会更加方便传播,或者放在服务器上、自动定期更新什么的,便于大家远程直接查看。代码其实也不麻烦:
最终可以得到HTML网页截屏如下:
SAS输出富文本:RTF
RTF是一种可以直接被WORD等office软件读取的格式,支持图文表格混排什么的。有的时候直接输出出来也会各种方便(吐槽:相比于R的knitr直接各种文件格式混搭、数据随处可以插入,SAS还是有很长的一段路要走哇)。
输出的文档大概长成这样:
勉强可以看看吧。SAS的默认配色真心丑陋,像上世纪win 98时代的…
SAS的输出样式自定义
对于PRINTER输出和REPORT、TABULATE加STYLE选项,就不赘述了,目测不会有用到的需求——一般SAS都不会给我最终拿去给partner或者boss汇报的格式,再者就算SAS里面能做,也实在是太麻烦了,成本太高。我的观点就是,做统计的软件还是做统计吧,那些花里胡哨的修饰还是交给excel这种所见即所得的软件来搞定吧。各有所长才是~
不过SAS有个高亮单元格的功能,可以简单说一下。
这样最终的结果就会有单元格高亮效果了:
勉强可以一看吧。EXCEL的条件格式(conditional formatting)更顺手强大。
SAS的导出模块:EXPORT
如果说ODS是结果的发送,那么export则是更加原始的数据输出(数据而不一定是分析结果)、供其他软件读取。
SAS图形界面下有一步步向导式的export,但是可惜我悲催的一开始就要接触命令行下面的SAS…跳过。
EXPORT可以输出文本格式,最常用的就是逗号或者tab分割的。
这里就输出了一个tab分割的文本文件。
当然也可以输出excel文件:
这个和ODS有点重复了呢。不过R也是啊,有各种各样输出的方式,任君选取。
(五):数据操作与合并
数据集操作永远是逃不掉的问题,最简单的就是两个数据集的合并——当然不是简简单单的行列添加,按照某一主键或者某些主键合并才是最常用的。在SAS中,要熟悉的就是SET这个声明,可以用改变数据集等等。
生成新变量
这里一个比较简单的例子,就是有一个现成的数据集,我们想增加一个变量。
这样的结果就是增加了一个新的变量PeoplePerCar:
行合并
这里比较类似于R里面的rbind()函数,就是直接在尾部附上后面的数据。当SET指定了两个或多个数据集的时候,可以进行这样的操作。距离如下:
然后结果输出为:
这里很容易看出,对于第一个数据集没有的变量LOT,会自动添加缺失值。
SET还可以进一步结合BY对数据排序:
这样返回的结果就是按照PassNumber排序的了:
SAS一对一合并数据集
类似于SQL的join和R的merge,SAS也可以合并数据集。先从最简单的一对一合并说起:
这样就可以得到按照CodeNum来合并这两个数据集了,返回结果为:
当然一对多也是可行的。
原数据为:
然后代码为:
最后得到的结果就是:
有的时候我们还想把一些统计量也合并进来,比如PROC MEANS得到的那些,这样自然也是不怎么麻烦的。
这里用到了OUTPUT输出统计结果到SAS数据集,这样最后结果就是:
还有一些特定的情况,可以不用MERGE而是UPDATE,这个就得稍稍小心一点了…
基本就是把patientmaster这个数据集用transactions里面有的数据覆盖掉相应的记录。
SAS里面拆分数据
在读入数据的时候,SAS还可以自动按照某些条件把其拆分为两个数据集,这里需要调用OUTPUT声明。
得到的就是两个数据集(虽然我们读入的只有一个…你也可以理解为生成了两个原数据集的子集):
这里就类似于R里面的split()函数了。
还有一些数据格式比较不稳定,比如一行多条记录:
这个时候就可以利用OUTPUT的操作,来逐行读取并输出:
最后得到的数据就相当规范了(我在想为啥SAS可以有这么多奇葩的数据输入…真折磨人啊):
SAS里面变量选取等参数
其实DATA里面的参数还是蛮多的,除了以前提到过的KEEP,DROP,还有可以重命名的RENAME等。还有一个比较有用的可能就是IN了:
这样可以增加一个新的变量Recent,来记录某条记录是否被合并。
WHERE的用法也可以稍稍赘述一下:
这样得到的结果为:
SAS中数据的转置:TRANSPOSE
数据的转置有时候也是逃不掉的。这里就有些类似于R里面的reshape()函数了,但是肯定没有reshape2里面的melt and cast强大…我一度觉得reshape2的用法很麻烦,后来才发现原来这东西真的强大到一定程度了…
结果为:
SAS里面自带的变量
SAS里面有些默认自带的变量,有时候用起来还是蛮方便的,类似于R会自带一个row.names这种变量。
比如_N_就会加上行号(当然有时候也不是,呃,准确的说应该是SAS执行的循环顺序,说了SAS是一行行操作数据的嘛):
这样得到的结果就是排序后的次序了:
类似的变量还有FIRST.variable和LST.variable,这里由于我们用到了 FIRST.AgeGroup,所以第二次输出的时候只有第一个AGE GROUP的结果。
(六):宏的编写、程序调错
在SAS各种繁杂的PROC之后,还要来看看MACRO才可以嘛。又不能写函数…
SAS中的MACRO:宏编写
MACRO主要是DO和%LET的各种组合,前者负责循环后者负责变量。
一个例子:
这段代码可以做什么呢?很简单,替换文字。我们指定了一个SAS MACRO中的变量flowertype,在执行MACRO的时候他会被自动翻译成标准的SAS代码。这样执行的结果就是:
看到了吧,标题已经被替换了。
一段MACRO以%macro开始,然后以%mend结束。
这样执行之后的结果就是:
虽然SAS不可以直接写函数,但是MACRO还是有参数可以传入的。
这样传入的参数会自动作为变量被替换掉。结果如下:
当然MACRO中也会有需要判断的时候,这就是IF上场之时啦:
比如周二,那么翻译出来的SAS代码就是:
最终得到的结果为:
SAS中使用CALL SYMPUT:用数据值赋予变量
如果有的时候需要数据集中的值来给MACRO中的变量赋值,我们就需要使用CALL SYMPUT了。
这样的结果就成了:
看出来这里面的逻辑了么?我们先对数据集flowersales进行了排序,然后选择第一名的订单用户,赋值给selectedcustomer这个变量,然后就可以直接在后面用&selectedcustomer调用这个变量值,去查找属于他的观测记录了。
SAS MACRO的DEBUG调试
这里就是一些基本的找错技巧了:
SAS常见程序错误
最常见的大概就是少了结尾的分号…这里的报错一般是:
或者其他类似的语句无法被SAS理解的。
还有就是输入数据不正确或者有缺失值什么的…这个我觉得在数据源是数据库管理系统的时候,不是什么问题…
还有就是数值型被转换成文本型…报错类似于:
我们利用PUTLOG可以一步步的输出SAS计算的过程:
这样也有利于查错。
其他的可以直接看报错信息来判断,不赘述了。
(七):常用统计模型
其实最后一天,反而是任务最繁重的。这一天,需要纵览SAS的各个常用的统计模块。BTW,在用惯了ggplot2之后,再也不认为有任何理由用其他软件画图了…所以SAS的图形模块自动被我无视(貌似很多SAS用户也一直在吐槽这东西着实不好使)。
SAS里面的概要统计:PROC MEANS
其实前几天也说过了PROC MEANS,不过这里稍稍补充一点置信区间的东西吧。其实它的参数真的挺多的:
ode variance
在调用CLM的时候需要指定ALPHA:
结果如下:
SAS里面的相关性分析:PROC CORR
虽然correlation一直被各种批判,但是往往在拿到数据的第一步、毫无idea的时候,correlation还是值得一看的参考指标。SAS里面的PROC CORR提供了相应的功能。
SAS的相关性分析结果输出如下:
SAS里面的基本回归分析:PROC REG
类似于R中的lm(),这个实在是没什么好说的了,最基本的最小二乘法。
SAS的输出结果如下:
包含了回归模型的基本统计量。我们一般更关注的回归系数:
到这里,我的感慨就是:真的很像Stata呀!值得注意的是,REG有很多可选的参数,对于这些参数是干嘛用的,最权威的自然还是SAS官方的文档:http://support.sas.com/documentation/cdl/en/statug/63033/HTML/default/viewer.htm#statug_reg_sect007.htm。其实熟悉了SAS的语法和工作模式之后,具体到某个模型还是看官方文档比较舒服。不愧是商业软件啊,文档写的都很专业,有很多模型选择问题其实看看文档就能多少明白一些了。
比如PROC REG的参数就有:
model fit summary statistics
OUTEST= data set
and the model to the OUTEST= data set
OUTEST= data set
set. Use only with the RIDGE= or PCOMIT= option.
Use only with the RIDGE= or PCOMIT= option.
estimates to the OUTEST= data set
OUTEST= data set
statistics of the parameter estimates to the OUTEST= data set
VAR statements
VAR statements
SAS里面的基本方差分析:PROC ANOVA
方差分析也就不赘述了,其实我感觉没有回归分析更用的普遍…这俩东西某种程度上也是一回事儿,看怎么理解了。
SAS的输出如下:
先是用作分类的变量的基本统计。然后是模型的基本统计:
最后是各个组的分析结果(两两比较,由于指定了SCHEFFE参数):
SAS中的离散被解释变量模型:PROC LOGISTIC和PROC GENMOD
最简单的离散被解释变量模型就是logit了,在SAS里面有直接的PROC LOGISTIC。官方文档在此:http://support.sas.com/documentation/cdl/en/statug/63033/HTML/default/viewer.htm#logistic_toc.htm
语法自然是一如既往的简单:
结果返回:
首先自然是模型的统计信息。然后是数据的统计:
Value
Frequency
然后是假设检验:
Only
and
Covariates
最后是参数估计:
Error
Chi-Square
而对于泊松模型,则需要PROC GENMOD。我觉得我一一个列出这些模型已经超出了这篇笔记的范围了…所以干脆就改成简单翻译一下各个PROC的主要模型吧。说过了,学习模型不是主要的目的——模型终究不该通过软件来学…虽然SAS的user guide真的还算是比较好的统计学教材呢。
SAS里面的PROC一览
除了上面说到的PROC,SAS当然还有更多强大的模块。我就顺手一一点开看看这些东西都能做什么…