资源描述
Title text should go hereEven if on two lines(but not three),First level,Second level,Third level,第,4,章 访问外部数据文件,本章内容,通过,IMPORT,过程导入外部数据文件;,通过,LIBNAME,语句和库引擎连接外部数据文件;,通过,SAS/ACCESS,软件访问外部数据文件;,通过,ODBC,或远程软件平台,访问外部数据文件;,创建,SAS,数据集方法总结。,注意:本章的一些例子需要较为复杂的软硬件环境,可能无法在单个,PC,机上实现操作。,访问两类外部文件,SAS,系统访问的外部文件可以分为两类:,PC,格式的数据文件;,流行数据库(,DBMS),文件。,访问外部数据文件方法,除了前面两章介绍的读入外部数据文件的方法外,,SAS,系统访问外部文件,特别是流行数据库文件的方法还有以下几种。,通过,IMPORT,过程;,通过,LIBNAME,语句和库引擎;,通过,ACCESS,过程;,通过,ODBC,或远程软件平台。,句法与选项说明,PROC IMPORT,DATAFILE=“|TABLE=tablename OUT=SAS-data-set,;,选项说明:,应用举例,例,4.1,导入,EXELL,数据表。,proc import out=tb31,datafile=D:ResDattable.xls,dbms=excel2000 replace;,range=3#1$;/*,导入表,3.1*/,getnames=yes;,run,;,例,4.2,从文本文件的第二行导入数据。,proc import,out=b_share_1,datafile=D:ResDatb_shares_1.txt,dbms=dlm replace;,getnames=no;,datarow=2;,run,;,通过,LIBNAME,语句和库引擎,通过,LIBNAME,语句和库引擎连接的外部文件有两类:,其它,SAS,版本或分析软件的数据集;,流行数据库(,DBMS)。,语句格式:,LIBNAME,libref,SAS/ACCESS-engine-name,;,SAS8.2,系统支持的库引擎,读入流行数据库(,DBMS),读入流行数据库时需要知道这些数据库的简单操作。同样可以通过菜单建立新逻辑库和利用,LIBNAME,来实现。,例,4.7,用,LIBNAME,建立与,ORACLE DBMS,的连接。,libname,oralib oracle,user=ZSW password=ZSW321,path=ora7db dbindex=y;,例4.8,取消逻辑库指定。,libname,oradb,clear,;,例4.9,与,DB2,的连接。,libname,db2lib db2,authid=ZSW ssid=ZSW321;,通过,ACCESS,过程,通过,ACCESS,过程可以实现对外部数据文件的透明访问和读写。,SAS/ACCESS,可以访问的主要外部数据文件:,ACCESS,过程访问外部数据须分两步完成:,创建访问描述器(,Access Descriptor);,创建基于外部数据文件的数据视窗(,View)。,创建访问描述器,语句格式:,PROC ACCESS,DBMS=DBF|DIF|WKn|XLS|;,CREATE libref.member-name.ACCESS;,required database-description statements;optional editing statements;,RUN,;,创建访问描述器的,SAS,程序对于不同的外部文件有不同的形式。下面给出几种外部文件访问描述器的创建方法。,由,EXELL,表创建访问描述器的一般格式:,PROC ACCESS,DBMS=XLS;,CREATE,逻辑库名,.,访问描述器名,.ACCESS;,PATH=XLS,文件的地址和全名,;,;,;,;,;,;/*,规定运行时在,LOG,窗口显示列的信息*,/,RUN,;,由,ORACLE,数据库创建访问描述器的一般格式:,PROC ACCESS,DBMS=Oracle;,CREATE,逻辑库名,.,访问描述器名,.ACCESS;,USER=Oracle,用户,ID;,ORAPW=Oracle,服务器上的用户密码,;,TABLE=Oracle,表名,;,PATH=Oracle,驱动器、结点和表的别名或库名,;,;,;,;,RUN,;,创建数据视窗,通常基于一个访问描述器可以创建多个数据视窗。,SAS,数据视窗(,View),和,SAS,数据集(,Data),都是数据文件,均可以作为数据对象被引用。虽然类型不同,但在同一逻辑库中名称不能重复。,创建基于访问描述器数据视窗的语句格式,PROC ACCESS,DBMS=DBF|DIF|WKn|XLS|ACCDESC=libref.access-descriptor;,CREATE libref.member-name.VIEW;,SELECT column-list;optional editing statements;,RUN,;,创建基于访问描述器的数据视窗的一般格式,PROC ACCESS,DBMS=,数据库类型,ACCDESC=,访问描述器名;,CREATE,逻辑库.视窗名.,VIEW;,SELECT ALL|DBMS,表的列名;,RUN,;,当然,对于不同的,DBMS,还有许多不同的控制语句。,同时创建访问描述器和数据视窗的语句格式,PROC ACCESS,DBMS=DBF|DIF|WKn|XLS|;,CREATE libref.member-name.ACCESS;required database-description statements;optional editing statements;,CREATE libref.member-name.VIEW;,SELECT column-list;optional editing statements;,RUN,;,例4.1,2,创建,DBF,文件的数据视窗。,proc,access,dbms,=dbf accdesc=work.s000002;,create,work.s000002.view;,select,all,;,list,view,;,run,;,例中,基于访问描述器,RESDAT.s000002.ACCESS,创建,DBF,文件,stk000002.DBF,的数据视窗,WORK.s000002.VIEW.,ACCESS,过程将数据视窗转换为数据集格式:,PROC ACCESS VIEWDESC=,数据视窗名,OUT=,数据集名;,例,4.16 ACCESS,过程将数据视窗转换为数据集。,PROC ACCESS,VIEWDESC=s000001 OUT=stk000001;,Run,;,通过,ODBC,ODBC(Open Database Connectivity),技术是由微软提供的一个应用程序(,API),接口标准。用于支持,ODBC,软件之间的数据访问。,支持,ODBC,的外部数据文件系统:,创建,ODBC,数据源,通过,ODBC,访问外部数据文件的前提是创建,ODBC,数据源。,不同的外部数据文件系统创建,ODBC,数据源的方式也不一样。,第,5,章 数据步读入原始数据,清华大学经管学院 朱世武,Resdat,样本数据:,SAS,论坛:,原始数据分类,原始数据一般分为字符和数值两种类型,数值数据又分为标准数值数据和非标准数值数据。,标准数据,是由字符或者数值组成的可以被列表、列、格式化、命名输入方式读入的数据如,ARKANSAS,1166.42,。,非标准数据,只能在输入格式的帮助下读入的数据。如非标准的数值数据,可能包含逗号,空格等符号。日期和时间数值。十六进制和二进制数值。,标准数值数据,只包含数字,小数点或负号。,非标准数值数据,则包含其它的特殊字符,如千分号,美元符号等。,字符数据,字符数据是由一系列字符组成的数据。,下面任一种情况下,,INPUT,语句认定读入变量的值是字符值。,INPUT,语句中变量名后跟一个美元符号,$,;,使用字符输入格式;,要读入数据的变量已经被定义为字符值。,原始数据呈现形式,原始数据的呈现形式一般分为呈现在,SAS,编辑窗口的数据行,和储存在外部文件中的原始数据,例,5.1,编辑窗口下,数据行形式的原始数据。,data,weight;,input PatientID$Week1 Week8 Week16;,loss=Week1-Week16;,datalines;,2477 195 177 163,2431 220 213 198,2456 173 166 155,2412 135 125 116,;,例,5.2,储存在外部文件中的原始数据,,TXT,文本格式。,-1-2,2477 195 177 163,2431 220 213 198,2456 173 166 155,2412 135 125 116,使用,INPUT,语句读入原始数据,INPUT,语句的用途有两方面:,读入外部数据文件中的数据;,读入,CARDS,语句后面的数据。,INPUT,语句的五种输入方式,简单方式:,INPUT,;,列方式:,INPUT,variable start-column ;,格式化方式:,INPUT,variable informat.;,INPUT,(variable-list)(informat-list);,INPUT,(variable-list)(informat.);,列表方式:,INPUT,variable ;,INPUT,variable ;,命名方式:,INPUT,variable=;,INPUT,variable=start-column ;,INPUT,variable=informat.;,选项说明,specification(s),变量及其格式的详细说明,variable-list,列出要读入数据值的变量,执行下一个,INPUT,语句时指针移到下一记录行,,要求一条记录必须对应一个数据行,执行下一个,INPUT,语句时指针保持在当前记录行,,不要求一条记录对应一个数据行,$,定义字符型变量,start-column,规定变量值在记录行中的起始列,end-column,规定变量值在记录行中的终止列,decimalplaces,小数点位置,pointer-control,移动输入指针到指定的行或列上,informat,列出变量的输入格式;,informat-list,-,列出变量列表对应的输入格式列表,decimals,规定小数部分的位数,列方式输入,语句格式,INPUT,variable start-column ;,设定变量名称,,为可选项,如果选择,$,则表示这是一个字符变量。而,start-column,表示该变量在记录行中的起始列(终止列)。,例,5.3,使用列方式输入数据。,data,scores;,in truncover;,input name$1-10 sex$11 age 12-15 ;,datalines;,Justine F 12,Bob M 13,;,-+-1-+-2-+-3-+-,例中,规定记录行的第,1,到,10,列为变量,NAME,的输入值,,11,列为变量,SEX,的输入值,,12,到,15,列为变量,AGE,的输入值。,NAME,和,SEX,为字符型变量。,列方式输入使用条件,原始数据输入值的位置在每个记录行相同的列中,;,原始数据输入值是标准的数值格式或一般字符格式,。,列方式输入的特点,原始数据输入值可以按任意顺序读取;,字符型原始数据中间可以有空格;,可以重复读取原始数据记录行的某一部分。,读入的数据值不需要用空格或者其它分隔符隔开。,列表方式输入,简单列表方式输入,INPUT,variable ;,调整列表方式输入,INPUT,variable ;,列表方式输入使用条件,输入数据值之间,至少有一个,空格隔开;,用小数点表示表示缺失值;,字符型值的默认长度为,8,个字节,也可以用,LENGTH,ATTRIB,INFORMAT,语句规定长度;,数据必须是字符数据或标准的数值数据。,列表方式输入格式修饰符,:,当原始数据是以空格为分隔符时,要想对变量值长度不一致的变量规定统一长度就必须用到该格式修饰符。,规定变量值是从非空格列中读取,直到第一次遇到以下三种情况之一,该变量值的读取过程才结束:,下一个空格列;,达到变量预先设定的长度(如果没有预先设定变量长度就是,SAS,默认字符长度,8,个字节);,数据行结束。,例,5.5,空格为分隔符时,对变量值长度不一致的变量规定统一长度。,data,;,input Univ:$12.Plc$Zip;,cards;,MIT Boston 100023,TsinghuaUniv Beijing 100084,;,例中,第一个观测变量,Univ,的值为,MIT(,只读,3,个字符,因遇到空格而结束,),第二个观测值为,TsinghuaUniv(,得到先前定义的变量长度,12),。如果只对变量,Univ,规定长度,而不加格式修饰符,(:),,在读入第一条记录时就会出错,如果不对变量,Univ,规定长度,读入第二条记录时就会只读入,Tsinghua,,而不是预先要读入的,TsinghuaUniv,,这是因为,SAS,默认的字符变量的存储长度就是,8,个字节。,Univ,Plc,Zip,MIT,Boston,100023,TsinghuaUniv,Beijing,100084,加格式修饰符,(:),不加格式修饰符,(:),Univ,Plc,Zip,MIT,Boston,1,00023,.,&,字符型输入值可能包含一个或几个空格。因为空格是列表读入方式默认的分隔符,所以,如果要读入的数据值本身包括空格时就必须用此格式符。,例,5.6,空格为分隔符时,字符型输入值嵌有空格。,data,;,input name,cards;,Jiang Zhu 20,Annie Zheng 31,I.Altman 60,;,run,;,例中,第一个观测,name,中,Jiang Zhu(,包含一个空格,),,第二个观测为,Annie Zheng,(包含一个空格,),。分隔符为两个空格。,注意:因,&,有以上特性,数据之间应该用两个以上的空格隔开。,规定读入字符值时保留引号。此选项只在,INFILE,语句中与选项,DSD,一起使用时才有效。,注意:,DSD,选项在第六章会有详细介绍。这里先说明它的,4,个功能:,将默认分隔符改为逗号;,对于连续的两个分隔符,中间按缺失值处理;,将字符变量值的引号去掉;,对引号里的分隔符按字符来对待。,所以,INFILE,语句中的,DSD,选项自动把数据记录的分隔符设置为逗号,并且读入数据之前,把字符数据中的引号去掉,若加上,就会保留数据中的引号。,可以通过下面的这个例子来理解,DSD,和,的作用。,例,5.7 DSD,和,的作用,读入字符值时保留引号。,只在,INFILE,语句中与选项,DSD,一起使用时才有效。,data,topics2;,in dsd;,input speakers:$15.title$40.location,datalines;,Song,Credit Derivatives,Room 329,Zhu,Credit Risk Management,Room 406,;,proc,print,;,run,;,由上例可以看出,,“,”,包含“,:”,选项的功能,。例中,虽然,title,变量的长度是,40,,而观测值得长度都不到,40,,仍然可以得到正确结果。所以“,”,包含“,:”,的功能。,把,speakers,后面的“,:”,改成了“,”,也可以。例如:,data,topics2;,in dsd;,input speakers$15.title$40.location,datalines;,Song,Credit Derivatives,Room 329,Zhu,Credit Risk Management,Room 406,;,proc print;,run;,输出窗口信息,:,Obs speakers title location,1 Song Credit Derivatives Room 329,2 Zhu Credit Risk Management Room 406,但是,若把,title,后成的“,”,改成“,:”,,引号就因为,dsd,选项的存在被去掉。如下,:,data,topics2;,in dsd;,input speakers:$15.title:$40.location,datalines;,Song,Credit Derivatives,Room 329,Zhu,Credit Risk Management,Room 406,;,proc,print,;,run,;,输出窗口信息,Obs speakers title location,1 Song Credit Derivatives Room 329,2 Zhu Credit Risk Management Room 406,格式化方式输入,格式化输入方式是,INPUT,语句,读取非标准数据,的唯一方法。即在变量名后面规定输入格式。这种输入方式不仅给出了该输入数据所对应的类型,而且给出了输入数据所在列的长度。,语句格式:,INPUT,variable informat.;,INPUT,(variable-list)(informat-list);,INPUT,(variable-list)(informat.);,其中:,n*,规定在输入列表中后面的输入格式重复,n,次。,例,5.8,格式化方式输入。,data,;,in;,Input(X1-X5)(3*7.2,2*5.2);,.,例中,前,3,个变量,X1-X3,的格式为,7.2,,而后,2,个变量,X4-X5,的格式为,5.2,例,5.9,读入非标准数据,$1,000.22,。,data,one;,input x comma9.2;,datalines;,$1,000.22,;,run;,例中,读入的数据为,1000.22,,这里要注意长度,该数据符号加上数字一共是九列。,命名方式输入,如果数据行中含有变量的名字,后面跟着等号和变量的值,读取数据时应该使用命名输入方式。,语句格式,INPUT,variable=;,INPUT,variable=start-column ;,INPUT,variable=informat.;,其中:,variable=,规定用于,INPUT,语句读入的变量名。,例,5.11,使用命名输入格式。,data,a;,input date yymmdd10.fullshr stkcd=$lstknm=$;,cards;,2001-01-18 1486553100 stkcd=600001 lstknm=,邯郸钢铁,;,run,;,后面变量的不采用命名输入格式,读入数据时出错。,data,a;,input date yymmdd10.stkcd=$lstknm=$fullshr;,cards;,2001-01-18 stkcd=600001 lstknm=,邯郸钢铁,1486553100,;,run,;,Log,窗口显示出错信息:,NOTE:LOST CARD.,RULE:-+-1-+-2-+-3-+-4-+-5-+-6-+-7-+-8-,date=14993 stkcd=600001 lstknm=,邯郸钢铁,fullshr=._ERROR_=1 _N_=1NOTE:INPUT,语句到达一行的末尾,,SAS,已转到新的一行。,NOTE:,数据集,WORK.A,有,0,个观测和,4,个变量。,第,20,章,SQL,从单个表中检索数据,清华大学经管学院 朱世武,Resdat,样本数据:,SAS,论坛:,SELECT,语句综述,SELECT,语句是,PROC SQL,的主要工具。使用,SELECT,语句可以识别、检索和操作表中的数据,使用,SELECT,子句可以设定查询条件。,SELECT,语句格式,SELECT,object-item,FROM from-list,;,SELECT,子句,语句格式,SELECT,object-item,FROM from-list,选择所有列,语句格式:,COLUMN-NAME,=*(asterisk),select *from from-list,SELECT,子句中,“*”号表示选择表中的所有列。,例:,proc sql,outobs=3;,select*,from ResDat.dret;,选择特定列,语句格式:,Select column-name from from-list,例,20.1,选择特定列。,proc sql,outobs=3;,title,股票代码,;,select stkcd from resdat.lstkinfo;,proc sql outobs=3;,title,股票代码和名称,;,select stkcd,lstknm from resdat.lstkinfo;,quit;,用,DISTINCT,语句剔除查询结果中重复观测,语句格式:,=distinct,例,20.2,删除重复观测。,proc sql,;,select distinct stkcd,from ResDat.yrret;,quit;,创建说明列,语句格式:,SELECT TEXT,,,COLUMN-NAME,例,20.4,创建说明列。,proc,sql,outobs=,3,;,select Stock Code for,lstknm,is,stkcd,from ResDat.lstkinfo;,quit,;,输出窗口结果,:,最新股票名称,|,Latest Stock,股票代码,|Sto,Name ck Code,-,Stock Code for S,深发展,A is 000001,Stock Code for,万科,A is 000002,Stock Code for *ST,国农,is 000004,计算新列值,语句格式:,Calculating Values=Calculating Expression of columns,例,20.5,计算股票每日成交金额。,proc sql,outobs=3;,title Trading Sum;,select stkcd,lstknm,clpr*trdvol format=12.2,from ResDat.qttndist;,quit;,Trading Sum,最新股票名称,|,股票代码,|Sto Latest Stock,ck Code Name,-,000001 S,深发展,A 3946648.52,000001 S,深发展,A 1420743.60,000001 S,深发展,A 1120732.50,为列分配别名,语句格式:,SELECT calculation-form ,别名必须符合,SAS,名称要求,别名只在当前的查询中有效。,例,20.6,为列分配别名。,proc sql,outobs=3;,title Trading Sum;,select stkcd,lstknm,clpr*trdvol as trdsum format=12.2,from ResDat.qttndist;,quit;,Trading Sum,最新股票名称,|,股票代码,|Sto Latest Stock,ck Code Name trdsum,-,000001 S,深发展,A 3946648.52,000001 S,深发展,A 1420743.60,000001 S,深发展,A 1120732.50,CALCULATED,语句,语句格式:,Calculated Column-name,使用别名引用一个计算过的列值时,必须使用,Calculated,关键词,并将,Calculated,放在列名称之前,以此告知,PROC SQL,这个列是经计算得到的。,proc sql,outobs=3;,select stkcd,lstknm,date,clpr*mcfacpr as adjpr format 8.2,(calculated adjpr*trdvol)as trdsum format 12.2 from resdat.qttndist;,quit;,最新股票名称,|,股票代码,|Sto Latest Stock,ck Code Name,日期,|Date adjpr trdsum,-,000001 S,深发展,A 1991-01-02 66.94 3946648.52,000001 S,深发展,A 1991-01-03 66.89 1420743.60,000001 S,深发展,A 1991-01-04 66.75 1120732.50,CASE,表达式,语句格式:,CASE,WHEN when-condition THEN result-expression,END,例,20.7,简单形式的,Case,表达式。,proc sql,outobs=3;,select stkcd,lstknm,lstdt,case,when exchflg=1 then,上交所,when exchflg=2 then,深交所,else,所有交易所,end as exchflg,from resdat.lstkinfo,order by lstdt;,quit;,例中,将股票信息表,lstkinfo,交易所标识(,exchflg,)的编码值进行转换,同时得到新的交易所标识列及相关数值。,最新股票名称,|,股票代码,|Sto Latest Stock,股票上市日,|L,ck Code Name ist Date exchflg,-,000005 ST,星源,1990-12-10,深交所,600652,爱使股份,1990-12-19,上交所,600602,广电电子,1990-12-19,上交所,使用,ORDER BY,语句排序,语句格式,ORDER BY order-by-item;,选项说明:,order-by-item,可以是如下:,integer,等同于一个列在,SELECT,子句中的位置,column-name,列的名称或者别名,sql-expression,见附录中的,sql-expression,ASC,升序排列数据,默认方式,DESC,降序排列数据,例,20.9,对股票上市时间列进行排序。,proc,sql,outobs=,3,;,select lstknm,lstdt from resdat.lstkinfo,order by lstdt;,quit,;,最新股票名称,|,Latest Stock,股票上市日,|L,Name ist Date,-,ST,星源,1990-12-10,爱使股份,1990-12-19,广电电子,1990-12-19,可以通过指定列在,SELECT,子句中的整数位置对该列排列。,例,20.11,按第,4,列排序。,proc sql outobs=3;,select stkcd,lstknm,date,clpr*mcfacpr as adjpr format 8.2,from resdat.qttndist,order by 4 desc;,quit;,最新股票名称,|,股票代码,|Sto Latest Stock,ck Code Name,日期,|Date adjpr,-,600652,爱使股份,2001-05-15 105881.8,600652,爱使股份,2001-05-16 103950.1,600652,爱使股份,2001-05-14 103020.1,用,WHERE,语句选择观测,语句格式,WHERE sql-expression,选项说明:,sql-expression,(见,sql-expression,定义),.,例,20.13,用,WHERE,语句选择,1991,年以前上市的股票。,proc sql,outobs=3;,select lstknm,lstdt from resdat.lstkinfo where lstdt,选项说明:,integer,等同于一个列在,SELECT,子句中的位置,Column-name,列的名称或别名,Sql-expression,见附录,sql-expression,例,20.22,分组进行汇总。,proc,sql,outobs=,3,;,title 2005,年股票月收益平均值,;,select stkcd,avg(monret)from resdat.monret,where,1jan2005d,=date=,31dec2005d,group by stkcd;,quit,;,2005,年股票月收益平均值,股票代码,|Stock Code,-,000001 -0.0017,000002 0.025023,000004 -0.03469,用,HAVING,子句选择分组数据,语句格式,例,20.25,算出,A,股市场股票,2005,年的交易天数。,proc,sql,;,select stkcd,count(*)as trday from resdat.dret,where,1jan2005d,=date=,31dec2005d,group by stkcd,having substr(stkcd,1,1,)in(0,6)or substr(stkcd,1,2,)=99;,quit,;,股票代码,|Sto,ck Code trday,-,000002 212,000007 241,000011 230,000016 239,600601 241,600604 232,600651 239,600653 240,
展开阅读全文