步中有效,也就是数组名只能在当前data步中标识数组,不同的data步中可以使用相同的数组名但不表示同一个数组;默认情况下,数组的标号是从1开始的。
8.1 数组的定义(definition)
ARRAY array-name {number-of-variables}
说明:
·数组名的命名规范与变量命名完全相同,不赘述;但是数组名不能与当前data步中变量同名;
·元素个数有三种形式,分别对应于创建数组的三种方法;元素个数必须用大括号({})、中括号([])或圆括号(())括起来,三者等价;
·变量列表必须由相同类型的变量组成,要么全是数值型,要么全是字符型;数组列表同样可以是缩写形式;
定义数组最简单的方法是直接写明元素的个数,如, array books{3} Reference Usage Introduction; 也可以用上下界来定义元素个数的范围,如
array books{0:2} Reference Usage Introduction;
这样的好处是可以自定义数组第一个元素的标号,上面的例子就是从0开始的,自定义标号某些时候会带来好处,如
array first{10} Year76-Year85; array second{76:85} Year76-Year85; 数组second显然更方便,不容易引起混淆。 定义数组还可以让系统来计算元素的个数,如
array score{ * } score1 score2 score3 score4 score5; 或array score{ * } score1-5;
这种定义的方式更多的用于不知道变量个数的情况下,变量的个数就交给SAS去计算把,如,
array x[ * ] _NUMERIC_;
如果是数组定义一系列字符变量,还可以通过length指定字符变量的长度,如 array ch[ * ] $ 20 name1-3; 8.2 初始化数组(initial-value)
初始化数组时间上是给数组元素即变量赋值, ARRAY array-name {number-of-elements}
如:array test(3) t1 t2 t3 (90 80 70);
array ab(5) (5 4 3);
如果初始值比数组元素少,则初始值依次赋值给变量,多余的变量被处理为缺失值,而且SAS会在LOG窗口中给与WARNING提示。
给数组元素赋值可以采用缩写的形式,如下面5种初始化数组的方法是等价的,
ARRAY x{10} x1-x10 (10*5); ARRAY x{10} x1-x10 (5*(5 5));
ARRAY x{10} x1-x10 (5 5 3*(5 5) 5 5); ARRAY x{10} x1-x10 (2*(5 5) 5 5 2*(5 5)); ARRAY x{10} x1-x10 (2*(5 2*(5 5)));
8.3 引用数组元素(Array Reference)
语法:array-name {subscript}; 不同的引用方式在于数组下标的引用不一样。 ·变量作为下标,主要用于循环语句中
{variable-1< , . . . variable-n>} 如,
array days{7} d1-d7; do i=1 to 7;
if days{i}=99 then days{i}=100;
end;
·*号作为下标{ * }
如:
array days{7} d1-d7; input days { * }; ·表达式作为下标
expression-1< , . . . expression-n> 如:
array arr1{ * } a1-a3; x=1;
input a1 a2 arr1{x+2}; ·直接使用数组名
见do over array-name循环结构
8.4 多维数组(multidimensional array)
定义多维数组跟一维数组没有大多区别,只是不同的维度之间用逗号隔开,同一维度同样可以采用元素个数或上下界的书写方式,但不能用{*}书写方式,如
array x{5,3} score1-score15; array test{3:4,3:7} test1-test10;
多维数组中,数值元素(即变量)先行后列依次进行填充。引用及初始化数组都跟一维数组一致。
8.5 临时数组(_temporary_)
当用户定义一个数组的目的只是进行计算时,经常用临时数组元素列表,使用临时数组元素可以少的占用内存,加快执行速度。
举例,array test{4} _TEMPORARY_ (90 80 70 70); 另外,临时数组还有如下一些特点:
·数组元素没有名字,引用时必须用数组名和下表,如test[1]; ·不能出现在输出的数据集上; ·不能用特殊下标(*)来引用所有元素;
·临时数组元素的值总是自动被保存,而不是像普通数组元素在data步的下一次自循环开始时被置为缺失值。 8.6 与数组有关的函数
DIMn(array-name):计算数组第n维的元素个数,第一维时写为DIM,例如:
do i=1 to dim(days); do i=1 to dim4(days) by 2;
DIMn函数常用于不知道数组元素的情况下,如用{*}创建的数组。 ·LBOUNDn(array-name)&HBOUNDn(array-name):计算数组第n维的下届与上届,第一维时省略n,例如:
array years{72:76} first second third fourth fifth; do i=lbound(years) to hbound(years); if years{i}=99 then years{i}=.; end;
这两个函数常用于用上下界形式创建的数组的情况下。
9.流程结构:顺序、选择、循环
程序语言中的流程结构用于控制各计算操作执行的次序。每一种结构化语言编写的程序都由由顺序、选择、循环三种结构构成,SAS也是如此,不同语言之间只是关键字不一样罢了。顺序结构就是指程序执行是按照代码书写的顺序进行的。下面主要讲选择和循环结构。 9.1 选择结构
条件语句:
IF 条件表达式 THEN 可执行语句 ; ELSE 可执行语句 ; 或者:
IF expression THEN DO;
statements ; . . . END; ELSE DO;
statements ; . . . END;
(1) if sex=?F? then y=100+y;
if upcase(dest)=?LAX? then y=x+z; (2) if sum le 170 then delete; (3) if upcase(dest)=?LAX? then do;
y=x+z; city=?Dallas?; end;
(4) if x>=0 then x=2*x ; ELSE x = -x;
分支语句:
SAS的条件语句不提供多分支结构。而SAS的SELECT语句提供了更为灵活的多分支结构,可以实现比其它语言的IF-ELSEIF-ELSE结构更强的功能。