清歌苦调两不厌:夯实基础
查看SAS安装、许可的模块
|
|
如何让SAS自动加载永久逻辑库
- 如果想要让SAS语句建立的永久库在启动后就能看到,可以把包含LIBNAME语句的程序命名为autoexe.sas,并放入和sas.exe同级的目录中,此后每次SAS启动时会自动运行autosas.exe程序。
- 通过工具按钮建立永久库时,可以在建立时勾上Enable at startup,下次启动SAS时就会自动加载这个永久库。
为什么又了数据文件还要视图
视图是依据查询语句动态生成,因此视图本身几乎不占据存储空间。利用视图可以节约硬盘空间。两者在世界内容效果方面是一样的。
日期与时间的本质
- 日期实际存储的是距离1960年1月1日的天数
- 时间是距离凌晨的秒数
打破SAS命名规则
修改系统选项VALIDMEMNAME
和VALIDVARNAME
|
|
运算符
- 不等于 ^= ~=
- 两者取小 ><
- 两者取大 <>
- 连接运算符 ||
- 与 & and
- 或 ! | or
- 非 ^ ~ not
IF-ELSE配合DO-END
希望执行的不仅仅是一个动作,而是多个动作,此时可以在关键词THEN后面用夹板语句DO-END,把多个动作整合在DO-END中。
循环
- DO-END
- DO-WHILE
- DO-UNTIL12345678910111213141516171819202122data random;do i=1 to 10;r=rannor(23);output;end;run;data dowhile;i=0;do while(i<5);i+1;output;end;run;data dountil;i=0;do until(i>=5);i+1;output;end;run;
数组结构
- 数组中的变量必须有相同的数据类型
ARRAY array-name {number-of-elements} <$> <length> <array-elements> <(initial-value-list)>
- 元素个数可以用{*}代替,让SAS自动计数;可以指定具体的数字,如{7};可以指定一定的数字范围,如{1:7}
- 元素名可以是变量名也可以是SAS自定义变量,如_ALL_(变量类型需相同,_NUMERIC_,_CHARACTER_,_TEMPORARY_(临时变量)
- <>中的内容并非必须有。如$和length只有在数组元素为字符型时才用到。
PDV与DATA步自循环
|
|
@与@@
- 当DATALINES数据行里要读入的数据列数=要读入的变量数,也就是说一行就是一条观测时,无尾。
- 当DATALINES数据行里要读入的数据列数>要读入的变量数,而且是整数倍时,也就是说一行=K*数条观测(K为>=1的整数),用@@。
当一个DATA步里有多个INPUT语句时,我们需要单尾@。
123456789101112131415161718192021222324252627* 数据列数=变量数data test1;input id x y z;datalines;1 98 99 972 93 91 92;run;* 数据列数=变量数,多个input语句data test2;input id@;input x@;input y@;input z@;datalines;1 98 99 972 93 91 92;run;* 数据列数=k*变量数data test3;input id x y z @@;datalines;1 98 99 97 2 93 91 92;run;- 无尾Hold不住立即跳
- 一尾(@)Hold住当前INPUT语句不跳,但若刚好是DATA步最后一个INPUT语句,跳。
- 二尾(@@)打死都不跳。
- 最后,无论多少尾,数据行末尾必定自动跳。
|
|
苔点狂吞纳线青:读取数据
读取方式
- LIBNAME语句
- SQL直通设施(SQL pss-through facility)
- ACCESS/DBLOAD过程,已不推荐
- IMPORT/EXPORT过程
- INFILE+INPUT语句
- INPUT+DATALINES语句
- IO函数
LIBNAME访问DBMS数据文件
LIBNAME libref engine-name \<SAS/ACCESS-connection-options> \<SAS/ACCESS-LIBNAME-options>;
libname mydb2 db2 user=yuanyi password="wuyuanyi" datasrc=datadb
- libref: 逻辑库名,其实是存放数据表和视图的DBMS数据库、架构、服务器端别名
- engine-name: 引擎名,不同的DMBS数据文件需要指定不同的引擎名,入oracle、db2等
- SAS/ACCESS 连接选项,常用的如用户名,密码等,不同的DMBS数据文件会有所不同
- SAS/ACCESS 逻辑库选项,控制SAS处理DBMS对象的方式,不同的DBMS数据文件会有所不同
PROC IMPORT语法
PROC IMPORT
DATAFILE = “filename”|DATATABLE = “tablename“(Not used for Microsoft Excel files)
<DBMS = data-source-identifier>
<OUT = libref.SAS data-set-name> \<SAS data-set-option(s)>
<REPLACE>
<file-format-specofoc-statements>;
RUN;
- filename: 欲读入的文件,包括路径、文件名以及扩展名(如:d:\mydata.xls),当然也可以用之前定义的fileref
- data source identifier: 一般情况下与文件扩展名一致,.mdb、.dbf、.dat、.sav等。如果是excel文件,建议用Excel
- <OUT句>: 读入数据后存放的SAS数据库和数据集名称
- <SAS data-set-option(s)>:对保存的数据进行数据集读写,变量筛选,观测筛选等方面的控制
- PW=选项加密数据集
- READ=、WRITE=、ALTER=选项分别加密读、写以及修改权限
- KEEP=、DROP=、RENAME=选项筛选、重命名变量
- OBS=、WHERE=筛选保留的观测
- <REPLACE>: 重复运行时替换掉同名数据集
- <file-format-specific-statements>: 对分隔符分隔的文件(如CSV文件)、EXCEL文件、Access数据文件、dBase数据文件、Paradox数据文件、SPSS以及Stata数据文件做更详细的读取设置
- 对于分隔符分隔的文件
- DATAROW=n 指定数据从第n行开始
- GETNAMES=YES|NO 应对数据文件首行是不是变量名
- GUESSINGROWS=n|MAX 应对仅用默认头20行数据无法判断变量类型和长度的情况
- DELIMITER=‘char’|’nn’x 个性化指定数据文件的分隔符,如DELIMITER=‘#’|‘20’x(十六进制ascii码的空格)
- 对于EXCEL文件
- SHEET=EXCEL文件中特定的sheet
- RANGE=读入某sheet中特定的数据区域
LIBNAME访问PC文件语法
LIBNAME <libref> <engine-name> <‘physical-path and filename.ext’> <SAS/ACCESS-engine-connection-options> <SAS/ACCESS LIBNAME-options>;
- libref: 逻辑库名,其实是存放数据表和视图的DBMS数据库、架构、服务器端别名
- engine-name: 引擎名,不同的DMBS数据文件需要指定不同的引擎名,入oracle、db2等
- ‘physical-path and filename.ext’: PC数据文件地址,文件名以及扩展名,置于引号中
- SAS/ACCESS 连接选项,常用的如用户名,密码等,不同的DMBS数据文件会有所不同
- SAS/ACCESS 逻辑库选项,控制SAS处理DBMS对象的方式,不同的DBMS数据文件会有所不同
⚠️SAS在读取Excel文件时,默认用前8行数据判定列的数据类型和长度。解决的办法是让SAS读入更多的数据行再确定数据类型,然而SAS未为Excel提供这样的选项。可以修改Windows注册表的Excel的TypeGuessRows的值为0,这样SAS会在读入所有行后再确定变量的类型。
|
|
读入CSV文件
|
|
读入TXT特殊字符分隔的文件
|
|
INPUT语句列表读入式
适合数据不齐整
INPUT <pointer-control> variable <$> <:|$|~> <informat.> @|@@;
- pointer-control: 控制变量读入点起始位置。针对行: #, /。针对列: @, +。
- variable: 变量列表
- $: 变量类型为字符型
- :|$|~: 三个互斥点可选用格式修饰符
- : 读入点变量列上不齐整,读到空列、读完字符定义的长度或者数据行结尾时就算一个变量读完
- & 读入点字符变量包含不连续的空格
- ~ 读入其他分隔符分隔数据,字符变量引号,引号里有分隔符
- informat.: 输入格式123456789101112131415161718192021222324data tmp;input name : $13. gender $ age location $; /*:表示遇到空格或第13列,才读完name*/datalines;WYY M 25 ShanghaiWuYuanyi M 25 ShanghaiStatsThinking M 1 Beijing;run;data tmp;input name & $9. gender $ age location $; /*一个空格不会认为变量结束*/datalines;W YY M 25 ShanghaiWu Yuanyi M 25 Shanghai;run;data tmp;infile datalines delimiter=',';input name & $9. gender $ age location $ affiliation ~ $12.;datalines;YY WU,M,30,Shanghai,"SHTU,SSIT"Yuanyi Wu,M,30,Shanghai,"SHTU,SSIT"run;
INPUT语句列读入式
适合数据齐整的情况
INPUT variable<$> start-column<-end-column> <.decimals> @|@@;
- start-column<-end-column>: 变量读入点起止列
- .decimals: 小数位数
|
|
INPUT语句格式读入式
可以对字符变量指定宽度,以及读入非标准形式对数字,如科学计数法、带货币符号、带千分位等。
INPUT <pointer-control> variable informat. @|@@;
INPUT <pointer-control> (variable-list) (informat-list) @|@@;
INPUY <pointer-control> (variable-list) (<n> informat.) @|@@;
- (variable-list) (informat-list): 变量格式列表
- 编号范围列表:形如x1,x2,x3可缩写为x1-xn
- 名称范围列表:x–a定义顺序从x到a的所有变量,x-numeric-a为x到a的所有数值型变量,x-character-ax到a的所有字符型变量
- 名称前缀列表:如x_1,x_2或x1,X2可简写成x:
- 特殊SAS名列表:_numerica_, _character_, _all_
- <n> informat.: 变量格式列表n表示格式重复的次数
|
|
INPUT语句命名读入式
INPUT <pointer-control> variable= <$> @|@@;
INPUT <pointer-control> variable= informat. @|@@;
INPUT variable= <$> start-column<-end-column> <.decimals> @|@@;
|
|
数据导出
PROC EXPORT DATA=<libref.>SAS data set<(SAS data set options)>
OUTFILE=”filename”|OUTTABLE=”tablename”
<DBMS=data-source-identifier\>
<LABEL>
<REPLACE>
<file-format-specific-statements>;
RUN;
- SAS data set: 欲输出的数据集
- filename|tablename: 输出文件的地址名称
- LABEL: 输出文件中输出变量名的标签
|
|
行舟来去泛纵横:变量观测
DATA+SET语句
DATA <data-set-name-1 <data-set-options-1>> <…data-set-name-n <data-set-options-n>> </<DEBUG> <NESTING> <STACK = stack-size>> <NOLIST>;
DATA _NULL_ </<DEBUG> <NESTING> <STACK = stack-size>> <NOLIST>;
- data-set-name: 欲创建的SAS数据集名
- data-set-options: 欲创建的SAS数据集的限制选项
- DEBUG: 调试程序逻辑错误以及部分数据错误
- NESTING: 日志中标记DO-END和SELECT-END语句的起止
- STACK =: 可嵌套LINK语句个数
- NOLIST: 出错时不在日志打印每个变量的值
- _NULL_: 不建任何SAS数据集
获取背后数据
- 利用
OSD TRACE ON
和ODS TRACE OFF
对整个统计过程进行全程追踪和监控:
|
|
- 在LOG文件中,产生的结果一目了然,想要什么数据随意抓取。
ODS OUTPUT
语句抓取Result树形目录下结果:
|
|
IF与WHERE
- WHERE更高效。WHERE语句在读入PDV之前就先行判断,求子集IF语句先读入观测进入PDV,而后再判断。
- WHERE更广泛。WHERE语句可用在DATA步,PROC步,作为数据集选项使用。IF语句只能作为DATA步语句使用。
- IF语句对INPUT语句创建的观测有效,WHERE语句只能筛选数据集里的观测。
- 当有BY语句时,求子集IF语句与WHERE语句结果可能不同,因为SAS创建BY组再WHERE语句之后,求子集IF语句之前。
- 求自己IF语句可以用在条件IF语句中,WHERE语句不行
- 当读入多个数据集时,WHERE语句可以针对每个数据集单独筛选,求子集IF语句不行。
|
|
KEEP、DROP与RENAME
- 选项只作用于被其尾随的数据集,而语句作用域PDV,即语句对不管来自哪个数据集的变量都有效。
- KEPP/DROP,RENAME,WHERE和其他语句的执行有固定的执行顺序。
- 数据集读入和输出阶段的执行顺序:
- KEPP/DROP选项筛选变量
- RENAME选项修改变量名
- WHERE选项筛选观测
- 编程处理阶段:
- WHERE选项筛选观测
- 其他执行语句
- KEPP/DROP选项筛选变量
- RENAME选项修改变量名
- 数据集读入和输出阶段的执行顺序:
编译变量和临时变量
编译变量(NOBS、IN、OBS、END、POINT等)和临时变量的赋值方式是将等号左边赋值给等号右边,其他赋值语句是将等号左边赋值给右边,
|
|
CALL例程
CALL例程也可以生成新变量,这种方法是函数形式的一种变种。
|
|
变量类型转换
new_variable = input(original_variable, informat.);
new_variable = put(original_variable, format.);
- new_variable:欲生成的新变量
- informat.:变量输入格式
- format.:变量输出格式
DATA步实现累加
累加语句:variable+expression;
- variable:累加器变量,必须为数字型变量,累加后的值保存于此变量中
- expression:表达式,表达式的值会被累加到累加器变量variable中
|
|
RETAIN语句:RETAIN <element-list(s) <initial-value(s)|(initial-value-1)|(initial-value-list-1)> <…element-list-n <initial-value-n|(initial-value-n)|(initial-value-list-n)>>>
- element-list:需要保留PDV里的值的参数,可以是变量名、变量列表、数组名
- initial-value:初始值,对应于只有一个参数或者参数列表里的第一个参数
- (initial-value-1):带括号的初始值
- (initial-value-list-1):带括号的初始值列表
|
|
BY语句的作用是在PROC SORT中排序后,在SET、MERGE、UPDATE以及MODIFY语句中,指定分组变量,产生临时变量FIRST.变量和LAST.变量用以标示观测变量是否为分组变量里的第一条和最后一条。
|
|
隔行取数据
SAS DATA步是隔行处理数据,一旦一行处理完,读入下一行数据后,前面行的数据就不在PDV里了。
- LAG:把前面任一行的数据在取出来
- DIF:计算目前行与前面任一行的差
|
|