SAS编程基础.docx
《SAS编程基础.docx》由会员分享,可在线阅读,更多相关《SAS编程基础.docx(39页珍藏版)》请在冰豆网上搜索。
![SAS编程基础.docx](https://file1.bdocx.com/fileroot1/2023-1/31/5e00f03a-104b-4486-ba67-0c2622eef502/5e00f03a-104b-4486-ba67-0c2622eef5021.gif)
SAS编程基础
DATA是一个循环,循环的退出(STOP,丢掉当前PDV中的数据)与短路(STOP,ABORT,RETURN)
数据步中的PDV
数据指针和程序数据矢量(PDV)
语句
指针数
PDV数
INPUTvariables
1
1
SETdata1data2
1
1
MARGEdata1data2
1
1
UPDATEdata1data2
1
1
SETdata1;SETdata2;
2
1
SETdata1;MODIFYdata2;
1
2
MODIFYdata1data2;
1
2
控制数据指针的变量
自动变量
说明
备注
_N_=m
指向对应的第m条观测
_N_=0表示数据集文件信息
POINT=n(variable)
指向第n条观测
END=variable
Variable中保存的是文件结尾标志(逻辑值)
NOBS=variable
Variable保存数据集的所有观测数
编译阶段完成
FIRST=m
从第m条观测开始读入
OBS=n
读入的最后一条观测数
2.3SAS变量
变量命名规则
变量的属性:
变量的类型
字符型:
缺失值为空,但仍占1字节的位置
数值型:
缺失值为“.”,
变量的长度
字符型:
3-8,缺省值8
数值型:
1-32767字节,依输入时的字符长度而定。
输入/输出格式
标签最多256字节,命名规则同数据集相同
变量列表
变量按照它们在PDV中出现的顺序被定义,
表示
说明
X1-xn
x1到xn
X:
字母X打头的变量
x--a
x到a间(包括x和a)的所有变量
x_numeric_a
x到a间(包括x和a)的所有数值型变量
x_character_a
x到a间(包括x和a)的所有字符型变量
_numeric_
所有数值型变量
_character_
所有字符型变量
_all_
所有变量
自动变量
自动变量
说明
_N_
观测序号
_ERROR_
错误信息变量
_IORC_
错误信息变量
_NUMERIC_
所有数值变量
_CHARACTER_
所有字符型变量
_all_
所有变量
FIRST.variable
同一BY变量(组)内第一个观测
LAST.variable
同一BY变量(组)内最后一个观测
第3章数据获取与数据集操作
数据集操作常用语句:
DATA/SET/BY/MERGE/UPDATE/MODIFY/PUT/FILE/INFILE
3.1数据获取
二种方式:
直接方式(在SAS系统中用INPUT语句来创建)
间接方式(直接获取外部数据:
PC格式(如TXT,EXCEL等文件);数据库格式(如DB2,TREADATA等)
文件格式
访问方式
文件格式
访问方式
TXT(PC)
INFILE/IMPORT
TERADATA(数据库)
Libname
Passthrough
odbc
CSV(PC)
INFILE/IMPORT
ORACLE(数据库)
EXCEL(PC)
INFILE/IMPORT
DB2(数据库)
SPSS(PC)
IMPORT
SYBASE(数据库)
MSACCESS(PC)
ACCESS
…
3.1.1LIBNAME方式
1直接访问外部数据库
访问SPSS数据库
libnamespsspss'F:
\Data_Model\Book_data\chapt3';
访问DB2数据库
libnamehsdbdb2user=xxxxpassword="xxxx"datasrc=datadb;
访问Oracle数据库
libnameoraliboracleuser=xxxpw=xxxpath=dbmssrvschema=educ;
访问TERADATA数据库
libnamep_cac_tteradatauser=xxxpassword=xxxdatabase=p_cac_ttdpid="caracal"override_resp_len=yesdbcommit=0;
2通过ODBC访问
Step1(window中完成):
控制面板/管理工具/ODBC数据源/用户DSN/ACCESS选项(例如)/添加/扩展名为MDB,完成/数据源名(自定义),选择ACCESS数据库(扩展名为mdb)/确定完成
Step2(在SAS中完成):
libnameodbodbcuser=***password=***datasrc=test;
3.1.3IMPORT方式
可用实例演示,并保住代码
3.1.3INPUT方式
自由格式,列表方式,格式化方式,命名方式(形式复杂,但实际中使用较少)
3.2SET语句
1一般描述
格式:
SET<数据集<数据集选项>><选项>
语法
子项
说明
数据集
一个或多个
最多50个数据集
数据集选项
KEEP=变量(组)
DROP=变量(组)
RENAME=(旧变量名=新变量名)
WHERE=表达式
IN=变量
FIRSTOBS=常数
OBS=常数
选项
NOBS=变量
POINT=变量
END=变量
KEY=索引名
创建新_IORC_,显示最近I/O操作序号,若KEY=值没找到,则返回_ERROR_=1
KEY=UNIQUE
规定从数据集索引的开关开始搜索
2例子:
keep
datakeep;
setsashelp.class(keep=namesex);
run;
datad1(keep=name)d2(keep=namesex);/*这是定义处使用*/
setsashelp.class(keep=namesex);/*这是调用处使用*/
run;
rename
datarename;
setsashelp.class(keep=namesexrename=(name=name_newsex=sex_new));
run;
where
datawhere;
setsashelp.class(keep=sexwhere=(sex='M'));
run;
In的使用
dataone;
inputxy$@@;
cards;
1a2b3c
;
datatwo;
inputxz$@@;
cards;
4d5e
;
datain1;
setone(in=ina)two(in=inb);
in_one=ina;
in_two=inb;
run;
firstobsobs
dataobs;
setsashelp.class(firstobs=3obs=5);
run;
nobs
datanobs1(keep=total);
setsashelp.classnobs=total_obs;
total=total_obs;
output;
stop;/*停止DATA步,相当于退出DATA步的自循环*/
run;
注:
程序在编译时就将数据集class头文件里面的观测数已读入并赋给变量total_obs。
datanobs2;
if0thensetsashelp.classnobs=total_obs;/*此语并不执行,但编译时已经赋值*/
total=total_obs;
output;
stop;
run;
point=
datapoint1;
n=3;
setsashelp.classpoint=n;/*注意这种调用方式,只能跟变量,不能跟数值*/
output;
stop;/*POINT的执行可能达不到文件尾,一定要有退出机制*/
run;
挑选3,15,4,19号观测
datapoint2;
don=3,15,4,19;
setsashelp.classpoint=n;
output;
end;
stop;
run;
快取数据集最后一条观测
datanobs_point;
setsashelp.classnobs=lastpoint=last;
output;
stop;
run;
注下面这段程序的效率不如上面的程序
Datazhu;
Setsashelp.classend=obs_last;
Ifobs_last=1;/*数据集要从头读到尾*/
Run;
End=
dataend;
setsashelp.classend=last_obs;
flag=last_obs;
run;
两个数据集的合并(要注意差别)
dataconcatenat;
setsashelp.classsashelp.class(obs=10);/*一个指针,一个PDV,故先读完第一个数据集,然后是第二个数据集,共29条观测*/
run;
procprint;run;
dataconcatenat;
setsashelp.class;/*注:
读入了第5条观测*/
setsashelp.air(obs=4);/*两个SET语句,每个SET语句有各自的指针,但总的只有一个PDV,因此数据集class和数据集air的指针同时运行,结果放到同一个PDV中,故结果只有4条观测*/
run;
procprint;run;
libnamechapt3'f:
\data_model\book_data\chapt3';
datapercent;
if_n_=1then
setchapt3.summary(keep=cargosum);/*这个命令只执行了一次,故其数据指针一直保持不变,因而cargosum值保持不变。
从这里也可看出,SET语句里面的指针移动与DATA步的循环有关*/
setchapt3.empcount;
pctemps=numemps/cargosum;
run;
3.3BY语句
经过排序后,SAS系统的两个自动变量FIRST.variable和LAST.variable很有用
databy_data;
inputprov$cty$mthincome@@;
cards;
JSc11100JSc12110
JSc13101JSc21200
JSc22210JSc23201
SHc11500SHc12510
SHc13501SHc21400
SHc22410SHc234201
;
run;
procsort
data=by_data;
byprovctymth;
run;
datafst_lst;
setby_data;
byprovctymth;
fst_p=first.prov;
lst_p=last.prov;
fst_c=first.cty;
lst_c=last.cty;
fst_m=first.mth;
lst_m=last.mth;
run;
3.4MERGE语句
实现表的横向合并,可合并:
一对一;多对一;或一对多
若是多对多合并,需要用SQL过程实现
使用的选项中IN=变量使用最多
一一合并
1)MERGE语句在没有BY语句的情况下,对MERGE后面的数据集实行一对一横向合并,显然,在不同数据集变量名相同的情况下,后面数据集的变量值会覆盖前面的数据集。
2)合并结果观测数取MERGE后面所有数据集中具有最大观测数的数据集所对应的观测数
匹配合并:
要合并的两个数据集均需事先按相同的关键词按相同的排序方式排序,
从下面的例子中可以看出其机制:
dataa;
inputid$xy;
datalines;
01a23
02b34
02b46
02b57
01a78
03c88
run;
datab;
inputid$xz;
datalines;
03c9998
01a7788
01a8888
02b3333
02b4455
run;
/*MERGE*/
dataab;
mergeab;
run;
procprint;run;
注:
一个指针一个PDV,没有匹配,一个一个地横向拼接。
观测的个数是两个数据集中最大的观测数。
procsortdata=a;
byid;
run;
procsortdata=b;
byid;
run;
dataab1;
mergeab;
byid;
run;
procprint;run;
注:
匹配合并时,从结果中可以看出这种合并机制:
一一合并如03c;01a为多对多合并,且个数相同;02b仍为多对多,但个数不一样多,从结果看第一个数据集中第3个02b观测值,仍为第二个数据集的最后一个,但并不覆盖第一个数据的变量x的值;
dataab12;
mergeba;
byid;
run;
procprint;run;
/*SET*/
dataab2;
setab;
byid;
run;
procprint;run;
注:
按照id值,先第一个数据集,再第二数据集。
再到第二个id值
3.6MODIFY
注:
modify语句开辟两个PDV,一个为主数据集,另一个为更新数据集,但只有一个数据指针。
主数据集一直处于打开状态。
3.6.1访问方式
匹配访问
Datamaster_data;
Modifymaster_datatransaction_data;
…;
Byvariable;
Run;
注:
若主数据集的BY变量有重复值,则只有第一个出现的观测被更新;若更新数据集的BY变量有重复值,则会反复对主数据集对应的观测进行更新,但只有最后一次的更新有效。
若更新数据集中有主数据集没有观测,则自动变量_iorc_会赋值为1,_ERROR_的取值为1.
dataAa;
inputid$xy;
datalines;
01a23
02b34
02b46
02b57
01a78
03c88
run;
dataBb;
inputid$xz;
datalines;
03c9998
01a7788
01a8888
02b3333
02b4455
run;
DATAaa;
modifyaabb;
byid;/*不需要事先排序*/
run;
procprint;run;
注意:
对于有重复的BY组数据的更新结果(符合上面的规则)
利用上面的规则,可以做如下的工作:
master_trans里面为汇总信息,day_trans里面为每天的成交信息,将每天的成交工作进行汇总,即更新汇总数据集master_trans。
Datamaster_trans;/*汇总信息*/
Inputuser_idtrans_amt@@;
cards;
101100010215001032000
;
Run;
Dataday_trans;/*信息*/
Inputuser_idday_amt@@;
cards;
10250102601033011080
;
Run;
可用如下程序完成:
datamaster_trans;
modifymaster_transday_trans;
byuser_id;
trans_amt=trans_amt+day_amt;/*利用更新数据集BY组值不唯一的特点*/
if_iorc_=0thenreplace;
elsedo;trans_amt=day_amt;_error_=0;output;end;
run;
结果:
亦可用如下的SQL过程完成:
procsql;
createtabletempas
select
user_id
sum(day_amt)asday_amt
fromday_trans
groupby1;
quit;
procsortdata=master_trans;byuser_id;run;
procsortdata=temp;byuser_id;run;
datamaster_trans;
mergemaster_transtemp;
byuser_id;
iftrans_amteq.thentrans_amt=COALESCE(trans_amt,day_amt);
elsetrans_amt=sum(trans_amt,day_amt);
run;
观测序号访问:
Datamaster_data;
SETtransaction_data
Modifymaster_datapoint=variable;
…;
Run;
注:
point=variable中variable为更新数据集中的一个变量,该变量的值必须是主数据集需要更新的观测序号。
若在主数据集中没找到相应的观测,则自动变量_iorc_取值为1(出现错误)
dataa1(index=(x));
inputxy@@;
cards;
1011110220330
;
run;
datab3;
inputpnty;
cards;
220033004400
;
run;
dataa1;
setb3(rename=(y=y1));
modifya1point=pnt;
y=y1;
run;
3.6.2输出观测问题的方法
3.7PUT语句
将信息输出到:
SAS的日志窗口
FILE规定的外部文件
3.7.1语法说明
语法格式
简单方式
PUT<_ODS_><@|@@>;
列方式
PUTvariable开始列<终止列><小数位><@|@@>;
列表方式
PUT<指针控制>variable<@|@@>;
PUT<指针控制>‘字符串’<@|@@>;/*n*--表示字符串可重复n次*/
PUT<指针控制>variable<:
|~>格式<@|@@>;
格式化方式
PUT<指针控制>变量格式<@|@@>;
PUT<指针控制>(变量列表)(格式列)<@|@@>;
命名方式
PUT<指针控制>variable=格式<@|@@>;
PUTvariable=开始列<-终止列><小数位><@|@@>;
指针控制
指针控制
相对位置
绝对位置
列指针控制
+n
@n
+(expression)
@(express)
+numeric-variable
@numeric-variable
行指针控制
/
#n
_PAGE_
#numeric-variable
_BLANKPAGE_
OVERPRINT
行固定说明符
@
@@
3.7.2例子
dataa;
inputx$yz@@;
cards;
a1020b3040c5060
;
run;
data_null_;
seta;
putx$@;
puty@;
putz;
run;
data_null_;
seta;
put@10x$@;
put@15y@;
put@20z;
run;
data_null_;
seta;
putx$10-14@;
puty15-19@;
putz20-24;
run;
data_null_;
seta;
putx$10-14@;
puty15-20.3@;
putz25-30.2;
run;
data_null_;
seta;
putx$:
@;/*:
号表示去掉输出值前后的空格*/
puty:
4.3@;
putz:
7.4@;
put3*'hereischar';
run;
data_null_;
seta;
putx$5-10@;
put@15(yz)(4.3"--"2.);/*注意格式与变量间的对应关系*/
run;
data_null_;
seta;
putx$5-10@;
put@15y4.3@;
put"--"@;
putz2.;
run;
data_null_;
seta;
putx=@;
put@15y=4.3@;
put@25z=2.;
run;
多种格式的混合使用:
datamix;
inputx$yzmnpq;
cards;
x102030405060
y708090100110120
;
data_null_;
setmix;
put@2x$@;
puty5-10.2@;
put@15z:
5.3@;
put(mnp)(best10."---"4.2"---"4.2)@;
put@60q=;
run;
data_null_;
setmix;
put@2x$@;
put+3y5-10.2@;
put+5z:
5.3@;
put+5(mnp)(best10."---"4.2"---"4.2)@;
put+10q=;
run;
一个综合例子
libnamech3'f:
\data_model\book_data\chapt3';
odslistingclose;
odsoutputparameterestimates=et;
procregdata=ch3.fitnessoutest=est;
modeloxygen=ageweightruntimerunpulserestpulsemaxpulse;
quit;
odsoutputclose;
odslisting;
filenamefb"f:
\data_model\book_data\chapt3\score";
data_null_;
setet(keep=variableestimate)end=last;
filefbnotitles;
if_n_=1thenput@1"scr=0";
est=abs(estimate);
ifestimate<0thenput@