putt=y=;
_I_=_I_+1;
end;
cards;
123453
024686
;
因一个隐含下标数组可以是其它隐含下标数组的元素,故允许有二维或更高维的隐含下标。
例9.20使用一些数组作为另一些数组的元素。
dataa;
arraytest1t1q1-t1q10;
arraytest2t2q1-t2q10;
arraytest3t3q1-t3q10;
arrayans(k)test1-test3;
inputt1q1-t1q10t2q1-t2q10t3q1-t3q10;
dok=1to3;
doj=1to10;
ifans=.thenans=0;
end;
end;
cards;
例中,有一组数据,包括三组测验题,每组又有十个问题。
每个学生的测验数据包括30个答案。
在DATA步使用ARRAY语句可以把这30个答案中的缺失值改变为0.
例9.21使用DOOVER语句处理上例。
dooverans;
doovertest1;
ifans=.Thenans=0;
end;
end;
由于test1,test2,test3维数相同,在内层doover语句中规定的数组名可以是这三个数组名的任一个。
例9.22规定临时的缺省输入格式。
dataa;
informatdefault=3.1default=$char4.;
inputx1-x5name$;
putx1-x5name;
cards;
11223344100johnny
;
run;
程序提交后LOG窗口输出显示:
1.12.23.34.410John
例中,在INPUT语句列出的变量X1-X5和NAME没有规定输入格式,那么使用这里规定的缺省输入格式,即用格式3.1输入X1-X5,用格式$char4.输入NAME.
例9.23取消已存在的输入格式。
dataa;
setfdata.a000001;
informatdate;
run;
例中,删除变量DATE的输入格式。
这里INFORMAT和SET语句的次序是重要的。
例9.24规定临时的缺省输出格式。
data;
formatw$3.y10.3default=8.2default=$8.;
w='goodmorning.';
x='goodmorning.';
y=12.1;
z=12.1;
putw/x/y/z;
run;
程序提交后LOG窗口输出:
goo
goodmor
12.100
12.10
例9.25使用自定义的格式输出。
procformat;
valuesexfmt1=male2=female;
dataal;
inputname$sex@@;
formatsexsexfmt.;
cards;
jane2bill1cindy2helen2
;
procprint;
run;
例中,
用FORMAT过程定义输出格式SEXFMT。
在DATA步中FORMAT语句把SEXFMT同变量SEX联系起来。
当以后用一些过程输出SEX值时。
MALE和FEMALE替代1和2被输出。
例9.26规定日期时间变量的输出格式。
dataa;
inputname$bdatedate7.;
formatbdateworddate.;
cards;
jimmy15jan84
cindy03mar85
;
procprint;
run;
如果没有FORMAT语句,表示日期变量date的值将用1960年1月1日和日期值之间的天数输出。
例9.27截短数据引起的误差问题。
dataone;
inputa1-4b6.;
lengthdefault=3;
cards;
1.46
1.25
1.14
1.34
1.35
1.36
2.03
;
datatwo;
setone;
ifa=1.3;
run;
例中,数据集TWO中没有观测。
因为,第二个DATA步的子集IF语句中的常数1.3用8个字节表示,而数据集ONE中变量A按LENGTH语句规定只有3个字节,因此A不会等于1.3.
例9.28LENGTH语句必须放在INPUT语句前面才能起作用。
dataa;
lengthname$20;
inputname$1-10;
cards;
(数据行)
;
run;
例中,INPUT语句隐含指定变量NAME的长度为10。
LENGTH语句(放在INPUT语句前面)给出在创建的数据集A中NAME的长度用20替代10。
例9.29字符变量的长由它的第一个观测值决定。
datab;
inputx;
ifx=1theny='no';
elsey='yes';
Cards;
1
5
;
run;
例中,字符变量Y第一次在赋值语句Y=‘NO’中出现时,它的长度被确定为2。
于是,当把‘YES’赋给Y时,仅前两个字符被存储,‘S’丢失了。
为解决该问题,或者使用LENGTH语句规定Y的长度,或者重新排列语句顺序。
例9.30SET语句之后的LENGTH语句对字符变量不起作用。
dataa;
scode=’0001’;
datab;
scode=’600001’;
datac;
setab;
lengthscode$6;/*length语句放在set语句之后不起作用*/
procprint;/*scode的长度为4,所以显示的预测分别为0001和6000*/
run;
上段程序的正确写法:
dataa;
scode=’0001’;
datab;
scode=’600001’;
datac;
lengthscode$6;/*length语句放在set语句之前*/
setab;
procprint;/*显示正确结果*/
run;
例9.31复杂程序中的LENGTH语句。
dataout;
delete;
%macroa(x);
dataa;
scode="&x";
dataout;
setouta;
lengthscode$6;
%menda;
%a(0001);
%a(0002);
%a(600001);
%a(600002);
procprint;
run;
程序中,没有用LENGTH语句变量SCODE的长度,它的长度由第1个观测值决定为4,于是读入第3个观测值时出错,只能读入前4个字符。
正确程序如下:
dataout;
delete;
%macroa(x);
dataa;
scode="&x";
dataout;
lengthscode$6;
setouta;
%menda;
%a(0001);
%a(0002);
%a(600001);
%a(600002);
procprint;
run;
例9.32Label语句的两种写法。
第一种写法:
Label
scode=”交易所用代码|stockcodebyexchange”
hstocd="最新股票代码|stockcode”
shrsdt=“观测日|sharesoutstandingobservationdate”
shrout=“观测到的b股股本|bsharesoutstanding”;
第二种写法:
labelscode=”交易所用代码|stockcodebyexchange”;
labelhstocd="最新股票代码|stockcode”;
labelshrsdt=“观测日|sharesoutstandingobservationdate”;
labelshrout=“观测到的b股股本|bsharesoutstanding”;
例9.33删除变量的标签。
Labelscode=’’hstocd=’’shrsdt=’’shrout=’’;
例9.34对单个变量定义一种属性。
attribscodelength=$6;
例9.35对单个变量定义多种属性。
attribdateinformat=mmddyy.Format=worddate.;
例9.36对多个变量定义相同的多种属性。
attribS1S2S3length=$4label=’SCORE’;
例9.37对多个变量定义不同的多种属性。
attribSlength=$4label=’SCORE’dateinformat=mmddyy.
Format=worddate.label=’TESTDATE’;
例9.38对变量列表定义一种属性。
attribmonth1-month12label=’MONTHLYSALES’;
变量后面几种属性选项的次序是任意的。
例9.39DROP语句的两种等价用法。
dataa;
setfdata.class;
dropsexage;
procprint;
run;
dataa(drop=sexage);
setfdata.class;
procprint;
run;
例中,两段程序的效果相同。
DROP语句告诉SAS系统新建数据集A中将删除SEX和AGE两个变量。
例9.40KEEP语句的两种等价用法。
dataa;
setfdata.a1a0001;
keepdateclpr;
procprintdata=a(obs=10);
run;
dataa(keep=dateclpr);
setfdata.a1a0001;
procprintdata=a(obs=10);
run;
例9.41KEEP语句使用旧变量名时程序运行正常。
dataa;
mergefdata.hqck101(keep=datenumberrename=(number=num101))
fdata.hqck199(keep=datenumberrename=(number=num199));
bydate;
run;
例9.42KEEP语句使用新变量名时程序出错。
dataa;
mergefdata.hqck101(keep=datenum101rename=(number=num101))
fdata.hqck199(keep=datenum199rename=(number=num199));
*Keep后面用的是新名子;
bydate;
run;
dataa;
mergefdata.hqck101(keep=daterename=(number=num101))
fdata.hqck199(keep=daterename=(number=num199));
*没有Keep要用的变量number;
bydate;
run;
例9.43应用举例。
dataa(keep=dateopenlowhighclose);
setfdata.A1a0001;
renameoppr=openlopr=lowhipr=highclpr=close;
procprintdata=a(obs=3);
run;
例9.44没有选项时,规定用INPUT语句或赋值语句创建的所有变量值从DATA步的这次执行到下一次重复时被保留。
于是数据值在一些观测中可能保留了本应为缺失值的其它值。
dataa;
inputid@@;
retain;
ifid=1thentest=’pass’;
ifid=2thentest=’fail’;
cards;
1222351531
;
procprintnoobs;
run;
打印输出结果为:
ID
Test
1
Pass
2
Fail
2
Fail
2
Fail
3
Fail
5
Fail
1
Pass
5
Pass
3
Pass
1
Pass
例中,当ID的值为1或2时,都是对的。
但当ID等于1和2以外的值时,没有一个IF条件是真的,故TEST没有接收新的值。
由于有RETAIN语句,所以,TEST就保持从上一观测中得到的值,这样就产生错误。
若从这段程序删除RETAIN语句,当ID值不等于1或2时TEST的值为空格(缺失值).
dataa;
inputid@@;
ifid=1thentest=’pass’;
ifid=2thentest=’fail’;
cards;
1222351531
;
procprintnoobs;
run;
打印输出结果为:
ID
Test
1
Pass
2
Fail
2
Fail
2
Fail
3
5
1
Pass
5
3
1
Pas
例9.45对于没有用园括号括起来初始值,SAS系统对前面列出的所有元素赋初始值。
retainmonth1-month51year0abc‘XYZ’;
例句中,RETAIN语句设置MONTH1至MONTH5的初值为1,变量YEAR的初值为0,字符变量A,B,C的初值为XYZ.
例9.46对于用圆括号括起来初始值时,SAS系统对括号前的第一个变量赋初值。
retainmonth1-month5
(1);
例句中,RETAIN语句分配初始值1给变量month1,而变量month2至month5初始值被置为缺失值。
例9.47初始值列表的用法。
retainvarl-var4(1234);
retainvarl-var4(1,2,3,4);
如果出现变量个数比初值个数多,剩余的变量用缺失值作为初始值,同时SAS系统发布一个警告信息。