标题：SAS语言
SAS语言简介
SAS系统强大的数据管理能力、计算能力、分析能力依赖于作为其基础的SAS语言。SAS语言是一个专用的数据管理与分析语言，它的数据管理功能类似于数据库语言（如FoxPro），但又添加了一般高级程序设计语言的许多成分（如分支、循环、数组），以及专用于数据管理、统计计算的函数。SAS系统的数据管理、报表、图形、统计分析等功能都可以用SAS语言程序来调用，只要指定要完成的任务就可以由SAS系统按照预先设计好的程序去进行，所以SAS 语言和FoxPro等一样是一种第四代语言。这里简单介绍SAS语言的基本成分与规则。
SAS语言构成
一SAS语句SAS语言程序由数据步和过程步组成。数据步用来生成数据集、计算、整理数据，过程步用来对数据进行分析、报告。SAS语言的基本单位是语句，每个SAS语句一般由一个关键字（如DATA，PROC，INPUT，CARDS，BY）开头，包含SAS名字、特殊字符、运算符等，以分号结束。SAS关键字是用于SAS语句开头的特殊单词，SAS语句除了赋值、累加、注释、空语句以外都以关键字开头。SAS名字在SAS程序中标识各种SAS成分，如变量、数据集、数据库，等等。SAS 名字由1到8个字母、数字、下划线组成，第一个字符必须是字母或下划线。SAS关键字和SAS 名字都不分大小写。二SAS表达式SAS数据步程序中的计算用表达式完成。表达式把常量、变量、函数调用用运算符、括号连接起来得到一个计算结果。     
常    量
SAS常量主要有数值型、字符型两种，并且还提供了用于表达日期、时间的数据类型。
数值型：数值型常数可以用整数、定点实数、科学计数法实数表示。如：
12，－7.5，2.5E－10
字符型：字符型常数为两边用单撇号或两边用双撇号包围的若干字符。如：
'Beijing'，"Li Ming"，"李明"
日期、时间：
日期型常数是在表示日期的字符串后加一个字母d大小写均可），中间没有空格。时间型常数是在表示时间的字符串后加一个字母t。日期时间型常数在表示日期时间的字符串后加字母dt。
日期型：'13JUL1998'd 
时间型：'14:20't 
日期时间型：'13JUL1998:14:20:32'dt
因为SAS是一种数据处理语言，而实际数据中经常会遇到缺失值，比如没有观测到数值，被访问人不肯答，等等。SAS中用一个单独的小数点来表示缺失值常量。
变    量
SAS变量的基本类型有两种：数值型和字符型。日期、时间等变量存为数值型（实际记录为距1960/01/01的天数）。SAS的数值型变量可以存储任意整数、定点实数、浮点实数，一般不关心其区别。数值型变量在数据集中的存贮一般使用8个字节。SAS的字符型变量缺省的长度是8个字符，但是如果在INPUT 语句中输入字符型变量时指定了长度则不受此限制。可以用LENGTH语句直接指定变量长度。
LENGTH 语句一般应出现在变量定义之前，格式为：
LENGTH 变量名 $ 长度;例如：
LENGTH name $ 20;
运算符
SAS运算符包括算术、比较、逻辑及其它的运算符。
算术运算符
算术运算符： + － * / **，运算优先级按通常的优先规则。
比较运算符
比较运算符用于比较常量、变量的值大小、相等，包括 
=  ^=  >  <  >=  <=
EQ  NE  GT  LT  GE  LE                   IN
其中EQ等名字和=等特殊字符是同一运算符的等价写法。比较运算符得到“真”或“假” 的结果，主要用于需要条件的分支、循环等语句中。
运算符IN是一个SAS特有的比较运算符，用来检查某个变量的取值是否在一个给定列表中，例如：
prov in ('Beijing', 'Tianjin', 'Shanghai', Chongqing')
可以判断变量prov的取值是否为四个直辖市之一。 
逻辑运算符
逻辑运算符用来连接比较得到的结果以构成复杂的条件，有三种逻辑运算符： &(AND) |(OR) ^(NOT) 。其中AND是&（与）的等价写法，OR是|（或）的等价写法，NOT是^（非）的等价写法。
例如：
(salary >= 1000) AND (salary < 2000) 
表示工资收入在1000－2000之间（不含2000）
(age <= 3) OR (sex = '女') 
表示三岁以下（含三岁）的婴儿及妇女
NOT ((salary >= 1000) AND (salary < 2000)) 
表示工资收入不在1000－2000之间
复杂的逻辑表达式最好用括号表示其运算优先级,以免误记优先规则并可利于阅读程序。
其它的运算符
其它的运算符：
||（两个连续的|号），两个字符串连接
<>  取两个运算值中较大一个的（比如3<>5结果为5）
><  取两个运算值中较小一个的 （比如3><5结果为3）
注意：<>符在有些语言中用作“不等于”比较算符，而SAS 中用法则较特殊。三SAS程序规则SAS程序由语句构成。每个语句以分号结尾。在SAS程序中，一个语句可以写到多行（不需任何续行标志），也可以在一行连续写几个语句。SAS语言中只要允许用一个空格的地方就可以加入任意多个空白（空格、制表符、回车），允许用空格的地方是名字周围、运算符周围。另外，SAS关键字和名字大小写不分，但字符型数据值要区分大小写，比如"Beijing" 和"BEIJING"被认为是不同的数据值。 
在SAS程序中可以加入注释，注释的内容用/*和*/在两端界定。这种注释可以出现在任何允许加入空格的位置，可以占多行。SAS中一般只把注释单独占一行或若干行，不把注释与程序代码放在同一行。注释的另一个作用是把某些代码暂时屏蔽使其不能运行。
SAS程序包括数据步和过程步两种结构，每一个步是一段相对完整的可以单独运行的程序。数据步用来生成、整理数据和自编程计算，过程步调用SAS已编好的处理过程对数据进行处理。自己用SAS编程序进行计算主要在数据步中进行。
SAS数据步以DATA语句开头，以RUN语句结尾。DATA步中可以使用INPUT、CARDS、INFILE 、SET、MERGE等语句指定数据来源输入数据，也可以用赋值、分支、循环等编程结构直接生成数据或对输入的数据进行修改。
SAS用作一般高级语言
SAS是一种专用的数据处理、统计计算语言，但是它也包含一般的高级语言编程能力并扩充了许多数学、统计等方面的函数。
SAS语言的编程计算能力主要由SAS数据步提供。DATA语句以关键字DATA 开头，后面给出一个数据集名，例如：
data out1;
则在本数据步要生成的数据集，其名字为out1。我们也可以省略数据集名，这时SAS自动生成一个临时数据集名。也可以使用特殊名字_NULL_ ，表示本数据步不生成数据集。一赋值语句在SAS中用赋值语句计算一个值并存放到变量中。
格式为 
变量名 = 表达式;
例如： 
avg = (math + chinese)/2;
isfem = (sex='女');
y=sin(x)**2;
newv = .;
其中第一个赋值语句用一个公式计算平均分数。第二个生成一个取值为0或1的变量，性别为女时为1，否则为0。第三个使用了正弦函数和乘方运算。第四个给变量赋了缺失值。二输出语句SAS数据步的输出一般是数据集，用赋值语句计算的结果会自动写入数据集。SAS也提供了一个PUT语句用于立即打印输出结果。
PUT语句的语法：
PUT  输出项表
输出项表中只能是变量或字符串，项间用空格隔开。如：
data;
x=0.5;
y=sin(x);
put  'Sine function value of '  x  'is '  y;
run;
结果将在运行记录窗口显示一行 
Sine function value of 0.5 is 0.4794255386
PUT说明
⒈在PUT语句中，若在变量名后加“=”，则指定输出项可以显示带有变量名的输出结果。
比如把上程序中的PUT语句改为
put  x=  y=;
则结果在LOG窗口显示为 
X=0.5 Y=0.4794255386
⒉指定变量输出项的具体列位置及小数位数
绝对位置格式：
变量  起始列-结束列.小数位数
比如，
put x 10-20 .6 y 30-40 .6;
指定把X数值显示在第10－20列，保留6位小数，把
Y数值显示在第30－40列，保留6位小数。
在指定的列位置内，数值型数据靠右对齐，字符型
数据靠左对齐。变量为整数值或者字符型则不指定
小数位数。
相对位置格式：
变量  宽度.小数位数(用于数值型)
变量  $宽度.(用于字符型)
如：put x 20.8 y 20.8; 使X占用第1－20列，8位小数，右对齐；Y占用第21－40列，8位小数，右对齐。
而put name $10.;使name占用10列。
输出占位不满指定宽度时，数值型数据向右对齐，字符型数据向左对齐。
⒊如果希望PUT语句的输出不产生换行，使下一个PUT的结果可以显示在同一行，只要在PUT 语句结尾处加一个@符。
PUT语句的输出结果缺省情况下被送到运行记录窗口。若在PUT语句之前用FILE语句可以改变PUT语句的输出目的地。如，在PUT语句之前用file print;可以把PUT语句的输出转向到输出窗口。在FILE语句中指定一个包含文件名的字符串可以把PUT语句的输出转向到此文件中。比如file 'tmp.out';输出文件把后续的PUT语句输出转向到当前工作目录下的文件“tmp.out”中，生成tmp.out 。注意当前工作目录在SAS状态栏的右方显示，双击可以更改。文件名也可以指定全路径，比如“C:\SAS\TMP.OUT”。三分支结构⒈if...then...else 结构
⒉SELECT结构
1. if...then...else 结构
格式为：
IF  条件  THEN  语句；
ELSE  语句；
例：    data temp1
input x @@;
if x>0 then put x '是正数';
else put x '是负数';
cards;
1 2 -3 4 -5
;
run;
有时我们在条件成立时需要进行的操作无法用一个语句完成，这时可以使用SAS提供的复合语句功能。例：
data;
input x@@; /*不分行符@@的使用：每读入一天记录后,数据指针保持原位不换行,
继续读下一条记录*/
if x>0 then do;
y=2*x;
put 'f(' x ')=' y;
end;
else put 'Data Error!';
cards;
1 2 -3 4 -5
;
run;
如果当条件不成立时，不进行什么操作，可以不使用ELSE及其后面的语句。
2.SELECT结构
格式一：
SELECT (选择表达式);
WHEN(值列表)  语句;
WHEN(值列表)  语句;
……
OTHERWISE  语句;
END;
功能及流程：
执行SELECT结构时，先计算出选择表达式和值列表中的所有值，然后把选择表达式值由前向后与值列表中的值相比，发现相等值则执行对应的语句，然后退出SELECT结构（不再查看后面的值列表）。如果选择表达式的值不等于任何值列表中的值则执行OTHERWISE对应的语句，这种情况下没有OTHERWISE语句会出错。
例:
DATA ;
INPUT month $ @@;
put month @;
SELECT(month);
WHEN('Feb', 'Mar', 'Apr')  put  '春天';
WHEN('May', 'Jun', 'Jul')  put  '夏天';
OTHERWISE  put  '秋天或冬天';
END;
CARDS;
Mar Jun oct
;
run;
格式二：
SELECT;
WHEN(条件)  语句;
WHEN(条件)  语句;
……
OTHERWISE  语句;
END;
这种SELECT语句没有选择表达式，而是在每
一个WHEN语句指定一个条件（逻辑表达式），
执行第一个满足条件的WHEN后的语句。如果所
有条件都不满足则执行OTHERWISE后的语句。
例：
data;
input age @@;
put age @;
SELECT;
WHEN(age<=12)  put  '少年';
WHEN(age<35)  put  '青年';
OTHERWISE  put  '中老年';
END;
cards;
10 30 50
;
run;四循环结构⒈计数DO循环
⒉当型循环
⒊直到型循环
⒈计数DO循环
计数DO循环的格式： 
DO  计数变量 = 起始值  TO  结束值  BY  步长;
循环体语句……
END;
这种结构与BASIC中计数循环很类似，功能也相当，只是在SAS中是以关键字DO开头(不是FOR),另外步长用BY引导(不是STEP)，而结构以END结束(而不是NEXT)。
其功能与流程：
程序先把计数变量赋值为起始值，如果此值小于等于结束值则执行循环体语句，然后把计数变量加上步长，再判断它是否小于等于结束值，如果是则继续执行循环体，直到计数变量的值大于结束值为止。上述结构中“BY 步长”可以省略，这时步长为1。如果步长取负值，则继续循环的条件是计数变量大于等于结束值。
计数DO循环举例
data;
sum=0;
DO  i = 1  TO  10  ;
sum +i;
/*此处sum+i等价于sum=sum+i*/
END;
PUT sum=;
run;
在循环体中可以用LEAVE语句跳出循环(功能与C语言的break语句相当),如：
data;
n=13;
flag=1;
DO  i = 2  TO  n/2  ;
if  mod(n,i)=0 then do;
flag=0;
leave;
end;
END;
if flag=1 then
put n "是素数";
else
put n "不是素数";
run;
⒉当型循环
当型循环的格式：
DO  WHILE(循环继续条件);
循环体语句……
END;
程序先判断循环继续条件是否成立，成立时执行循环体语句，再判断循环继续条件，如此重复，直到循环继续条件不再成立。
data;
x=243;
y=63;
z=mod(x,y);
DO  WHILE  (z ^= 0);
x=y;
y=z;
z= mod(x,y);
END;
put y;
run;
⒊直到型循环
直到型循环的格式： 
DO UNTIL (循环退出条件);
循环体语句……
END;
程序先判断循环退出条件是否成立，成立则结束循环，否则继续。例：
data;
n=0;
do until (n>=5);
n+1;
put n=;
end;
run;
SAS常用函数
⒈算术函数（Arithmetic Functions） 
⒉数学函数（Mathematical Functions）
⒊截断函数（Truncation Functions） 
⒋三角和曲线函数（Trigonometric and Hyperbolic Functions）
⒌字符函数(Character Functions) 
⒍日期和时间函数(Date and Time Functions)
⒎概率与密度函数(Probability and Density Functions)
⒏分位数函数（Quantile Functions）
⒐随机数函数（Random Number Functions）
⒑样本统计函数（Sample Statistics Funtions）
⒈算术函数（Arithmetic Functions）
ABS(x) ：求x的绝对值。 例如ABS(-56.3)=56.3 。
MAX(x1,x2,…,xn) ：求所有自变量中的最大一个。 例如MAX(52,15,67,89)=89 。
MIN(x1,x2,…,xn) ：求所有自变量中的最小一个。例如MIN(52,15,67,89)=15 。
MOD(x,y) ：求x除以y的余数。 例如MOD(24,3)=0 。
SIGN(x) ：计算x的符号，结果为1、-1、0。例如SIGN（-5）=-1，SIGN（20）=1，SIGN（0）=0。
SQRT(x) ：求x的平方根。 例如SQRT(225)=15 。
⒉数学函数（Mathematical Functions）
ERF(X)：误差函数            。
EXP(X):指数函数   。
GAMMA(X):计算              的值。
LOG(X):计算x的自然对数。
LOG10(X)：计算x的以10为底的对数。
LGAMMA(X):计算函数的自然对数。
⒊截断函数（Truncation Functions）
CEIL(X)：计算x的最小整数，当x为整数时就是x本身，否则为x右侧最近的整数。
例如CEIL(-134.45)=-134,CEIL(34.45)=35,CEIL(78)=78。
FLOOR(X)：计算小于或等于x的最大整数，例如FLOOR(-134.45)=-135,FLOOR(34.45)=34。
INT(X)：求x舍掉小数部分后的整数部分。例如INT(-134.45)=-134,INT(34.45)=34。
ROUND(x,unit)：计算x按照unit指定的精度四舍五入后的结果，例如ROUND(134.4567,0.01)结果为134.46，ROUND(3678.2398,10)结果为3680。
⒋三角和曲线函数（Trigonometric and Hyperbolic Functions） 
ARCOS(y)：计算反余弦函数。
ARSIN(y)：计算反正弦函数。
ATAN(y)：计算反正切函数。
COS(X)：计算x的余弦函数。
SIN(X)：计算x的正弦函数
⒌字符函数(Character Functions) 
COMPBL(S)：将字符串S中的多余空格去掉。
COMPRESS(S,S1)：将字符串S中包含的所有字符串S1去掉。
INDEX(S,S1)：查找字符串S1在S中的位置。如果S中不包含S1则返回0。
LOWCASE(S)：把字符串S中所有大写字母转换为小写字母。
UPCASE(S)：把字符串S中所有小写字母转换为大写字母。
RANK(S)：求字符串S的ASCII码值。
REPEAT(S,N)：将字符串S重复N次。
SUBSTR(S,N,LONG)：字符串S中的第N个字符开始抽取long个字符长的子串。
TRANWRD(S,S1,S2)：将字符串S中的所有字符串S1替换成字符串S2。
⒍日期和时间函数(Date and Time Functions)
常用日期和时间函数有：
DATEIF(sdate,edate,basis)：计算两个日期之间相距的天数，basis指定日期格式。
DATE：计算当前SAS系统的日期。
DAY(date)：有SAS日期值date得到是几日。
DHMS(date,hour,minute,second)：有日期、小时、分钟、秒得到SAS日期和时间值。
MDY(month,day,year)：生成月日年的SAS日期值。
MONTH(date)：有SAS日期值date得到月。
QTR(date)：有SAS日期值date得到季度值。
WEEKDAY(day)：有SAS日期值date得到星期几。
YEAR(DATE)：有SAS日期值date得到年。
其它日期和时间函数参见SAS系统的帮助信息。
⒎概率与密度函数(Probability and Density Functions) 
作为一个统计计算语言，SAS提供了多种概率分布函数。分布密度、概率、累积分布函数等可以通过集中统一的格式调用，格式为：
CDF(‘dist’,quantile,parm-1,…,parm-k)：计算累计分布函数。Dist为分布名称，quntile为分为数，随后是相关参数。
PDF|PMF(‘dist’，quantile,parm-1,…,parm-k)：计算概率密度函数。Dist为分布名称，quntile为分为数，随后是相关参数。
LOGPDF|LOGPMF(‘dist’，quantile,parm-1,…,parm-k)：计算概率密度函数的对数值。Dist为分布名称，quntile为分为数，随后是相关参数。
LOGSDF(‘dist’，quantile,parm-1,…,parm-k)：计算生存函数的对数值。Dist为分布名称，quntile为分为数，随后是相关参数。
PROBCHI(x,df<,nc>)：计算卡方分布的概率值。可选参数nc为非中心参数。
PROBF(x,ndf,ddf<,nc>)：计算F分布的概率值。可选参数nc为非中心参数。
PROBGAM(x,a)：计算伽马分布的概率值。
PROBNORM(x)：计算标准正态分布的概率值。
⒏分位数函数（Quantile Functions）
分位数函数是概率分布函数的反函数。其自变量在0-1之间取值。分位数函数计算的是分布的左侧分位数。
BETAINV(p，a，b)：计算参数为(a, b)的   分布的p分位数。
CINV(p, df<，nc>)：计算自由度为df的卡方分布p分位数。可选参数nc为非中心参数。
FINV(p, ndf, ddf<，nc>）：计算F (ndf , ddf）分布的p分位数。可选参数nc为非中心参数。
GAMINV（p, a)：计算参数为a的伽马分布的p分位数。
PROBIT(p)：计算标准正态分布的p分位数。
TINV(p, df>，nc<）：计算自由度为df的t分布的p分位数。可选参数nc为非中心参数。
⒐随机数函数（Random Number Functions）
SAS提供了常见分布的伪随机数生成函数。
NORMAL(seed）：产生服从正态分布的随机数。seed为0，或5位、6位、7位的奇数。
RANNOR (seed）：产生服从正态分布的随机数。seed为任意数值常数。
RANBIN(seed，n, p)：产生参数为（n, p）的二项分布随机数，seed为任意数值。
均匀分布随机数。系统提供两个均匀分布随机数函数：
UNIFORM(seed）：产生服从均匀分布的随机数。参数seed必须是常数，为0,或5位、6位、7位的奇数。
RANUNI (seed）：产生服从均匀分布的随机数。参数seed为小于231-1的任意常数。在同一个数据步中对同一个随机数函数的多次调用将得到不同的结果，但不同数据步中从同一种子出发将得到相同的随机数序列。随机数种子如果取0或者负数，则种子采用系统日期时间。
RANEXP(seed）：产生服从指数分布的随机数。seed为任意数值，产生参数为1的指数分布的随机数。
RANPOI(seed，lambda)：产生参数为lambda>0的泊松分布随机数，seed为任意数值。
RANTBL(seed，P1，…，Pn）生成取1，2，…，n的概率分别为P1，…，Pn的离散分布随机数。
⒑样本统计函数（Sample Statistics Funtions）
样本统计函数把输人的自变量作为一组样本，计算样本统计量。其调用格式为“函数名（自变量1，自变量2，…，自变量n）”或者“函数名（OF变量名列表）”。比如SUM是求和函数，如果要求x1、x2, x3的和，则可以用SUM(xl，x2，x3），也可以用SUM(of x1-x3）。
各样本统计函数为：
CSS：离差平方和
CV：变异系数
KURTOSIS：峰度
MEAN：均值
MAX：最大值
MIN：最小值
N：非缺失数据的个数
NMISS：缺失数值的个数
RANGE：极差=MAX - MIN
SKEWNESS：偏度
STD DEV：标准差
STDERR：均值估计的标准误，用STD/SQRT（N）计算
SUM：求和
USS：平方和
VAR：方差