[转载]SAS语言抛砖引玉·第2章(1)
(2011-11-29 13:53:42)
标签:
转载 |
分类: 统计学 |
第二章语言基础
(程序结构、数据类型、表达式与语句)
——如果你曾经学过一门语言的话,就应该知道语言基础这里会讲些什么内容了。其实各种语言的语法套路是差不多的,无非就是数据类型、变量、常量、运算符、流程结构、函数以及输入输出等。
1.第一个SAS程序(SAS program)
title "My first SAS program";
data temp;
A 54.0 B 50.2 A 56.6 B 53.8 A 57.3 A 51.2
…
;
proc ttest data=temp;
run;
这个程序是用t检验来检验6-7岁的城市儿童与农村儿童的胸围是否不同。
SAS程序中,每一行以分号(;)结尾的称为语句,语句是SAS程序最基本的单位,这跟其他语言是一致的。
SAS程序的层次是非常清楚的,因为它是模块化的。每一个SAS程序是有若干个语句组成,看起来可能非常复杂松散,而实际上SAS程序是两个模块化的结构构成即数据步和过程步,以及一些设置环境变量的全程语句。上面程序中,第一个语句是标题语句,也即是全程语句。data语句到第7行单独的分号被称为数据步,proc语句到run;语句被称为过程步。而且有些语句是专用于数据步的,比如input语句和cards语句;而有些语句是专用于过程步,如var语句和class语句;还有些语句是可以单独放在任何位置,称为全程语句。
1.1 程序结构:
数据步(Data
step):用来创建和修改用于统计分析的数据集,实现基础的编程功能;每个data步以data语句开始,可以包含任意多个SAS程序语句。
过程步(Proc
step):利用已创建的数据集完成特定的统计分析任务、结果输出及部分数据集整理功能。proc步以proc语句开始,数据集作为输入;其他语句给出用户想得到有关结果的更多信息的程序语句,这些语句依赖于用户调用的具体的过程。
数据步只要求以data步开始,没有其他限制;而proc步则更像一个模板,每一个过程有确定可用的语句,用户根据需要往上面填写。所以,说到SAS编程,大多的技巧和艺术都集中在数据步,过程步几乎没有任何的技巧可言,过程步应用的好坏一方面取决于你前面数据处理的好坏,另一方面取决于用户的统计基础。
1.2 数据步的自循环(Data step's Built-in
Loop):
个人觉得,如果要学习SAS,最首先要掌握的就是SAS程序的结构及运行机制,而其中最关键的又是data步的自循环,如果不能够理解这一点,那后面的内容就如空中楼阁,是不稳固的。
首先,数据步程序是一行一行的执行,这就意味着变量在使用之前必须创建。这一点很容易理解,几乎所有的语言都是如此。
其次,数据步程序是一个观测一个观测读取。当程序正确的执行到数据步的最后一个语句时,就将该次读取的一条观测写入数据集,然后又重新开始执行数据步,继续读取观测值,这就是数据步的自循环。也就是相当于数据步的最后隐含包括了两个语句,output与return语句。
第一个问题是读取的数据在执行到最后写入数据集之前保存在哪里?input语句执行后,SAS将读取的数据暂时先保存在内存缓冲区,然后执行后面的语句,后面的语句可以对暂存在内存缓冲区中的变量值进行修改,到最后才将整条数据写入数据集,写入数据集的数据就不能在当前data步中再修改。
第二个问题,在data步中间使用return语句会怎么样?自然是按照用户的意思进行执行,当遇到return语句时就重新执行数据步,读取下一条观测值,而跳过return后面的语句。
第三个问题,在data步中间使用output语句呢?那么程序会在执行到output语句那里就把放在内存缓冲区里面的观测值写入数据集,而不是等到整个data步执行完了再写入。
弄清楚这三个问题了应该弄明白data步的自循环是怎么回事了。而且会发现原来data步不一定是一次只可以读取一条观测,完全可以两条或者更多条一次的读取,比如重复input语句,并且在每条语句之后加一条output语句,就可以实现了。
2.数据类型(Data type):
我们在学其他编程语言的时候可能学到很多数据类型,但是SAS将各种各样的数据简化为两种类型,即数值型(numeric)和字符型(character)。那么这里就有问题了,像C语言那样丰富的数据类型而且实际上也存在各种类型的数据,SAS是如何处理的呢?这里就是SAS的特别之处了,两种基本的数据类型外加丰富的数据格式就能识别和显示各种各样的数据了,但是前提是你要告诉SAS怎么去识别和显示数据,按照什么格式去识别和显示数据,这里就涉及到SAS里面一个比较复杂的问题,数据格式,输入数据需要指明输入格式(informat),输出数据需要指明输出格式(format),这个内容请参看后面的有关章节,这里先了解一下。
另外一个问题,从数据类型角度我们把语言分为强类型的和弱类型,强类型的比方说C语言,在使用变量之前得先定义变量,而且必须指定一种数据类型。而SAS则是弱类型的,也就是在用使用变量之前是不需要定义的,变量的类型取决于数据的类型或者预先定义的格式。这个在后面的程序中可以更多的感受到。
3.变量(variable)
变量的命名规范跟其他语言基本相同,要以字母或下划线开始,不要使用系统保留的名称等;需要指明的是SAS的变量名是大小写不敏感的,最多32个字符,不像SPSS一样,SAS并不支持中文变量名,但是可以用变量标签(label)对变量进行说明,变量标签支持中文,最多256个字符。
下面主要讲解SAS比较特殊的内容。
3.1 变量的类型(type)
前面讲了SAS的数据类型只有两种,数值型和字符型,那么相应的变量类型也是两种,数值型变量和字符型变量。那么如何用这两种类型的变量去存储各种类型的数据?
前面一节提到SAS通过丰富的格式数据格式来识别和显示各种形式的数据,那么识别之后怎么存储呢?SAS有一套规则来将所有的数据转换成数值型或者字符型来存储,时间日期,货币数据都不例外。详细内容请参看后面有关章节。????
3.2 变量的类型转换(Type Conversions)
对于变量类型之间(字符型与数值型)的转换,SAS有一套规则如下,
·如果字符变量与数值运算符在一起使用,则SAS将字符变量转换为数值;
·如果字符变量与数值变量进行比较符运算,则SAS将字符变量转换为数值;
·如果数值变量与字符运算符在一起使用,则SAS将数值变量转换为字符;
·如果在一个赋值语句中,左边跟右边的类型不一,则将右边的类型转换成左边的类型;
以上这些转换规则是SAS自动完成的,并且在LOG窗口中打印一个警告信息,指示这个转换发生的地方。以上这些情况在编程的时候最好是不要出现,因为虽然是自动完成,但是转换的结果不一定是我们预期的,比方说字符变量转换成数值时产生的是一个无效的数值,结果就造成了缺失值,当然SAS会在LOG窗口中提示出错信息,同时置自动变量_ERROR_的值为1。
3.3 如何创建变量?(Create Variables)
SAS是弱类型的语言,使用变量前不需要定义,可以在数据步中直接使用变量,当然更多的情形是在用input语句读取数据时。如果是要预先定义变量的格式,则用format语句、informat语句、length语句或attrib语句都可以创建变量。
3.4 变量的属性(attribution)
通常说起变量,就是指变量的名称。其实变量名只是变量的属性之一。
打开一个数据集,然后选定任意一列,点击右键查看属性就会发现第一个选项卡是general,这个对话框里面的内容即为变量的属性,包括变量名、类型、标签、长度及其输入输出格式。
变量名用来标识变量,区分不同的变量;类型是指变量是字符型还是数值型;标签用来补充变量的信息,特别是SAS变量不支持中文命名的情况下可以将中文说明写在变量标签里;长度是变量所有容纳的最多字符的字节数或最大数值的字节数,在没有指定的情况下通常由input语句读取第一个观测值确定下来,当然可以用语句事先指定;输入输出格式用来输入输出数据,让SAS能对内部与外部的数据能实现转换,
3.5 变量列表(variable list)
在一个数据集中,变量按照第一次的出现的顺序(也就是在数据集中的顺序)被SAS系统存储为一个系列,这个系列就是一个完整的变量列表。而实际上我们在操作变量的时候只需要选取其中部分变量,而有了这个完整的变量列表就可以在许多语句中使用缩写的变量列表了。
在SAS中,可以使用4种缩写的变量形式:
(1)数字系列
如果有一系列变量是这样定义的,相同的名字后面加上一个连续的数字,就可以采用数字系列的缩写,如
x1, x2, x3, …, xn可以缩写为
x1-xn
(2)变量名系列
变量名系列就依赖于变量在SAS数据集中出现的顺序,如
x--a
就表示从x变量开始一直到a变量结束这一系列变量,结合自动变量就可以更加灵活的使用变量列表,如
x-numeric-a 表示从x变量开始到a变量结束之间的所有数值型变量,
x-character-a
表示从从x变量开始到a变量结束之间的所有字符型变量,
(3)前缀名系列
如果有一系列变量具有相同的前缀名,比方说SALES_JAN, SALES_FEB,
SALES_MAR… 则可以使用下面的形式表示这一系列变量名,
sales:
打印这些变量,则
proc print;
run;
对这些变量求和,则
sum (of sales:)
(4)特殊的变量列表
包括三个自动变量代表的变量列表
_ALL_
全部变量
_CHARACTER_ 全部字符型变量
_NUMERIC_ 全部数值型变量
3.6 自动变量(automatic variable)
自动变量是在程序中被SAS自动创建的变量,这些变量名有着特殊的用途,下面介绍一下在data步中的两个自动变量,过程步中的自动变量在具体的过程中讲解。
_N_
_N_在data步开始执行前被初始化为1,然后data步自循环一次该变量增加1,也就是_N_代表data步循环执行的次数。这个变量存在于每一个数据集中,但是一般不会显示也不会被打印。
_ERROR_
_ERROR_在data步执行前被初始化为0,当data步执行过程中遇到错误时就会自动被置为1,而且会在LOG窗口中打印出来,这样有利于调试程序的时候定位错误出现的位置以及出现错误时采取相应的处理。
Tips:这里还是说一下SAS的变量命名规则:
·首字符要以字母或者下划线开始;
·名称中只能包含字母、数字和下划线;
·变量名可以是大写,可以是小写,也可以是混合写的,但是SAS会当作是同一个变量名,也就是大小写不敏感;
·不要与系统保留的字段同名,比方_N_;
·变量名长度,SAS9.0是32位,6.12版和8.2版是8位;
说明:其实这些规则同样适用于命名数组、逻辑库、数据集、宏变量、宏名、函数等等,不同的地方是长度限制可能不一样,具体可以查看帮助文件。
4.常量(constant):
常量与变量是一个相对的概念。变量是用来存储数值的,而且是可以重新赋值的,而常量是用来表示固定的值,是不可改变的。常量可以是是一个数字、字符串或者其他特殊记号。常量和变量还有运算符一起是构成表达式的元素。
常量的类型,SAS使用四种类型常数,另外,十六进制常量单独列出来讲。
4.1 字符常数(character)
字符常数是用引号(单引号/双引号)引起来的1-32767个字符组成的字符串,如,
'Tom', "Tom"等
如果是字符串中包含引号,该怎么办?
两种方法
方法一:如果包含单引号,怎么用双引号引起来,相反,则用单引号引起来,如,
"Tom's" 表示Tom's
'Tom"s' 表示Tom''s
方法二:对包含在字符串中的引号可以写成连续的两个引号,如,
'Tom''s' 表示Tom's
"Tom""s"表示Tom''s
4.2 数值常数(numeric)
数值常数就是指在SAS语句中的数字,可以包含数字、小数点、符号和特殊记号E,如,
1, -5, +49, 1.23, 01, 1.2E23, 0.5E-10等等
注意:若一个数值常数大于10E32-1,则必须表示成科学计数法。
4.3 日期、时间和日期时间数值常数(data, time, and
datetime)
为了将日期、时间或日期时间值表示成常数,使用在输入格式和输出格式中被使用的相同的记法,TIME.,
DATA.和DATATIME.。格式值用单/双引号引起来,并跟随一个表示格式的字母D(日期)、T(时间)或DT(日期时间)。如,
'1jan2006'd;
'9:25't;
'9:25:19pm't;
'18jan2002:9:27:05am'dt;
4.4 十六进制常量(hexadecimal)
十六进制字符常量:是用引号引起来的一串偶数个的十六进制字符,并跟随一个X,如,
'534153'x
而且可以在这一串十六进制字符中使用逗号分隔使得易读但不影响十六进制常数的值,只是这里的逗号必须按偶数个来分隔。如上面的常数可以写为,
'53,41,53'x
十六进制数值常量:通常,十六进制数值常数用一个数字开始(一般是0),紧跟着很多十六进制位,并用字母x结尾。这个常数可以包括最多16个有效的十六进制位,如,
0c1x, 9x
5.运算符(operators)
在SAS中,算符包括运算符、括号和函数。其中运算符可以分为两种,前缀运算符和中缀运算符,中缀运算符包括算术、比较、逻辑、特殊运算符。
5.1 前缀运算符(prefix operator)
前缀运算符可以用于变量、常数、函数以及括号括起来的表达式,包括正号(+)、负号(-)及非运算(NOT)。如,
+y
-25
-cos(angle1)
+(x*y)
5.2 中缀运算符(infix operator)
·算术运算符:+, -, *, /, **,
加减乘除在各种语言里面都是一样,只是乘方可能有些差别,SAS是使用**;
·比较运算符:= (EQ), ^=(NE), >(GT), <(LT), >=(GE),
<=(LE),
IN()前面这些运算符分别代表等于、不等于、大于、小于、不小于、不大于,等于列表中一个。其实平常用的话只要知道用符号就行,括号里面的字母是跟符号等价的,了解一下的好处是可以看懂别人的代码,不至于以为是变量名或者英文单词。
在SAS语法中,比较运算符是可以连用的,例如
if (90=<x<=100) then grade='A';
·逻辑运算符:&(AND), |(OR), ^(NOT),
分别代表与或非,括号里面单词跟符号等价。
·其他特殊运算符:<>, ><, ||
<>(max)取最大值,例如:
a=8.2;
b=9.0;
min=(a<>b);
则min变量等于9.0。
><(min)取最小值。
||(连接):用来连接字符串,例如:
a="Hello, ";
b='SAS';
c='System!';
new=a||b||c;
则new变量等于'Hello, SAS System!'
5.3 运算次序,跟其他语言大同小异,更详细准确的说明请参看帮助文档。
思考题1:比较运算符为什么要选用那些字母呢?
6.表达式(expression)
表达式是由一系列算符和运算对象形成的一个指令集,它被执行后产生一个目标值。运算对象包括变量和常数;算符包括运算符、函数和括号。变量和常量是程序处理的两种基本数据对象,算符指定将要进行的操作,表达式则是用算符将变量或常量组合起来生成新的值。
7.语句(statement)
一个SAS语句是由SAS关键字、SAS名字、特殊字符和运算符组成的字符串,并以分号(semicolon)结尾,它要求SAS系统执行一种操作或给SAS系统提供信息。下面举例说明什么是关键字,名字,特殊字符和运算符等,真要解释概念可能到头来我也讲不清楚,你也听不明白。
put x $15.;
data temp;
proc means data=hospital.patiant maxdec=3;
infile rawdata;
do i=1 to dim(eachitem);
key1:total+1;
*这是注释语句;
上面这些语句中,x,
total是变量名字;temp和hospital.patiant是SAS数据集名字,其中hospital是库标记;$15.是格式名字;means是过程名字;data=和maxdec=是means语句中的选项;rawdata是一个文件标记;最后一个语句是注释语句。可以从这些例子中看出,语句都是以分号结尾的,注释语句也是如此。????
语句分类:在SAS中语句分为两大类,data步语句和全程语句。
其中data步语句又分为五类:文件操作语句、运行语句、控制语句、信息语句、窗口语句。
·文件操作语句:用于操作文件,这些文件用于输入数据集;或者用于输出。
·运行语句(动作语句):用于创建、修改或删除变量;或者用来操作记录;或者用来错误信息。
·控制语句:实现流程控制的语句。
·信息语句:给出关于数据集的附加信息,包括数据集中变量的信息。
·窗口语句:用于显示输出或者接受输入。
大部分的语句将在本教程中相应位置讲到,想快速获得其用法请参看附录2——SAS常用语句一览。

加载中…