SAS笔记.docx
《SAS笔记.docx》由会员分享,可在线阅读,更多相关《SAS笔记.docx(50页珍藏版)》请在冰豆网上搜索。
SAS笔记
一、VAR语句
VAR语句在很多过程中用来指定分析变量。
在VAR后面给出变量列表:
VAR变量名1变量名2…变量名n;
变量名列表可以使用省略的形式,如X1-X3,MATH--CHINESE等。
VAR用法例如:
varmathchinese;
WHERE 语句
WHERE 语句的格式很简单,只要后面跟用于数据筛选的逻辑表达式即可:
WHERE logical-expression(s);
下面的例子基于test1数据表生成test2数据表,但是只选择满足sex='F'并且age>20的数据行:
data test2; set test1; where sex='F' AND age>20; run;
表面看来,WHERE 语句和数据步骤中的 SASIF语句的功能相近,都是筛选数据和。
实际上 WHERE 语句和 IF语句的运作机制是不同的。
WHERE 语句相当于对数据集执行了一个SQLSelect的操作。
也就是说,在进入到操作前数据已经被整体筛选过了,而 IF 语句是在数据步骤的每个循环中单独执行的,WHERE 语句显然效率要提高很多。
如果数据表是索引过的,那么 WHERE 语句能够更加显著地提高效率。
WHERE 语句也有其限制。
因为它是对现存的数据表的整体性操作,故而只能对该数据表中已有的变量进行筛选操作,不能对数据处理后生成的变量操作,也不能对 INPUT 语句定义的变量操作。
WHERE 语句不但能用于数据步骤中还能用于过程语句中。
操作符
除了一般的SAS操作符(见 SAS语法),WHERE 语句还支持一些特有的操作符。
between...and。
比如:
where x between 10 and 20;
其实相当于:
where 10<=x<=20;
contains。
字符串包含。
可以用问号代替。
比如:
where firstnamecontains 'john'; where firstname ?
'john';
isnull 或 ismissing。
测试是否空值。
比如:
where ageis null; where ageis missing;
like。
用于字符串匹配。
百分号 %代表多个任意字符,下划线_代表一个任意字符。
比如以下的方式都匹配“john”:
where firstname like 'j_h_';
where firstname like 'j%';
sameand。
用于合并上一个 WHERE 语句。
比如:
where age>10;
where same and sex='F';
以上两句相当于一句:
where age>10 and sex='F';
min 和 max。
两数中的较小或较大者。
比如:
wherex=(aminb);
print语句
PRINT过程是最常用的SAS过程之一。
我们在生成了一个数据集之后,如果不是太大,一般都用一个
procprint;run;
过程步来列出数据集的内容,这样可以检查变量与值之间对应是否正确,数据输入是否正确。
为了列出一个指定的数据集,在PROC语句中使用DATA=选项指定要列表的输入数据集名,比如:
procprintdata=sasuser.gpa;run;
在过程内使用VAR语句可以指定要列出的变量并指定顺序。
比如,
procprintdata=c9501;
varnamechinesesex;(这里的顺序决定输出的结果顺序)
run;
列出变量NAME、CHINESE、SEX的值。
注意这已不是生成时的变量顺序。
变量MATH未列出。
结果如下
TheSASSystem3
OBSNAMECHINESESEX
1李明98男
2张红艺106女
3王思明90男
4张聪109男
5刘颍110女
注意PRINT的输出第一列总是标为OBS,值为观测序号。
我们有时不想输出这一列,可以在PROCPRINT语句中加入NOOBS选项,如:
procprintdata=c9501noobs;
run;
结果中就没有了OBS这一列。
在过程中使用WHERE语句可以从输入数据集中选一个子集来处理,在PRINT过程中使用WHERE可以指定只列出满足条件的观测。
比如,
procprintdata=c9501;
wherenamein('李明','张聪');
run;
结果为
OBSNAMESEXMATHCHINESEAVG
1李明男929886.8333
4张聪男9810994.4167
只列出了李明和张聪两个人的观测。
注意其观测序号分别为1和4,这是生成C9501数据集时确定的。
SAS的运算符
算术运算符
表示意思
比较运算符
表示意思
逻辑运算符
表示意思
**
*
/
+
-
乘方
乘法
除法
加法
减法
=或EQ
^=或NE
>或GT
>=或GE
<或LT
<=或LE
等于
不等于
大于
大于等于
小于
小于等于
AND
OR
NOT
逻辑与
逻辑或
逻辑非
contents函数
在编程环境下查看数据对象的描述部分可用以下过程:
proc contents data=sasuser.air position; run;(position是位置的意思)
engine的本义
据美国传统字典:
Amachinethatconvertsenergyintomechanicalforceormotion。
所以其要义在Convert转换.在SAS里,应该是对外部数据格式如EXCEL、ACCESS、ORACLE,SAS自己的数据版本如V6、V8等进行格式转换,以便SAS读取,写入。
我觉得是引擎的意思吧,SAS9.2里默认的就是V9,如果连接其他引擎如oracle,db2,access等数据库引擎,就要加上这个引擎名告诉SAS连接该库引擎
“libnameoratabsoracleuser=USERNAMEorapw=PASSWORDpath="@INSTANCE"schema=TRIALNAME;”
上面这个中的oracle 甲骨文 就是一种engineengine就是一种系统或文件方式之类的
我讲不清,比如SPSS,Excel都能是engine.
引擎的作用就是告诉sas,目标文件的格式是什么,应该怎么进行数据操作.
libname语句
指定sas逻辑库:
libnamelibref'sas-data-library'其中libref是逻辑库名,sas-data-library是逻辑库对应的物理地址,engine:
引擎名称。
libnameresdat'D:
\resdat';--创建逻辑库resdat,对应的
libname语句:
其中的物理地址要存在,就可以了,建立新的逻辑数据库
libname basesas 'G:
\sas';
data basesas.aa;
set sasuser.sample;
run;
Libname、、数据集data区别
25.指定逻辑库名的语句的一般形式为:
libname逻辑库名‘库的实际地址’;
26在程序编辑器窗口提交语句:
libname逻辑库名list;可以在log窗口显示该逻辑库的连接;
27.多个物理位置指定同一个逻辑库名的一般形式为:
libname逻辑库名(物理位置1物理位置2…);
28.指定逻辑文件名语句的一般形式为:
逻辑文件名‘文件位置’;
就是就文件的一份存储位置或者说文件名指定一个代号,或者称号,和libname不同点就是
Libname就是指定和文件名的一个对应关系,
数据集就是逻辑库的一个数据集合,
可以这么说:
libname和data是sas里面的,不是的
SAS分列的各种方法
假设变量a是几种产品的组合,产品名之间以+号连接,如下
变量a
a+b
ab+c+d
a+dec+bdfs+j
k
现在的问题是想分列,每个产品自成一列,变成如下形式
变量a1 变量a2 变量a3 变量a4
a b
ab c d
a dec bdfs j
k
1、一般做法如下:
datatest;
inputa$20.;
datalines;
a+b
ab+c+d
a+dec+bdfs+j
k
;
run;
dataout;
settest;
arrayarr$a1-a4;
doi=1to4;
arr(i)=scan(a,i,'+');
end;
dropi;
run;
2、考虑到实际情况中目标变量的数目可能未知的情况,改进如下:
datatest;
inputa$20.;
cards;
a+b
ab+c+d
a+dec+bdfs+j
k
;
run;
procsqlnoprint;
selectmax(count(a,'+'))+1into:
num
fromtest;
%macrogroup(n);
dataout;
settest;
%doi=1%to&n;
new&i=scan(a,&i,'+');
%end;
run;
%mend;
%group(&num);
dataout(drop=i);
settest;
arraynew(&num)$;
doi=1to#
new(i)=scan(a,i,'+');
end;
run;
3、巧用装置法:
datatest;
inputa$20.;
cards;
a+b
ab+c+d
a+dec+bdfs+j
k
;
datatemp;
settest;
docol_id=1tocount(a,'+')+1;
row_id=_n_;
val=scan(a,col_id);
output;
end;
run;
proctransposedata=tempout=out(drop=_name_)prefix=val_;
idcol_id;
byrow_id;
varval;
run;
以下是个人对PDV的粗浅总结,希望各位高手补充指正。
什么是PDV
个人认为可以把PDV想象成一排用于存放变量值的盒子。
每个盒子代表一个变量。
提交一个DATA步后,SAS会对这个DATA步进行编译,然后执行。
首先,PDV是在DATA步的编译阶段生成的。
(编译会进行语法检查并创建一排整齐摆放的”盒子”);
然后,在DATA步的执行阶段,根据不同语句对PDV中变量的值进行清空或更改。
(将盒子清空或换上新的物品);
最后,在RUN;语句或者OUTPUT;语句将PDV中变量的当前值输出到目标数据集中。
KEEP,DROP语句或KEEP=,DROP=数据集选项会影响输出到目标数据集中变量的个数。
(如果没有KEEP/DROP,将新建变量和数据集变量对应的盒子搬出到目标数据集;如果只有KEEP,则只搬KEEP指定的盒子;如果只有DROP,则不搬DROP指定的盒子;如果KEEP/DROP同时存在,则只搬KEEP-DROP后剩下的盒子)
PDV中变量的个数及顺序
DATA步中所涉及到的所有的变量,包括新创建的、从其他数据集读取的(SET)、以及自动生成的变量。
自动生成的变量包括:
_ERROR_,_N_;或是FIRST.VAR,_IORC_等由某个语句或选项所自动产生的变量。
默认情况下,自动生成的变量不会输出到目标数据集中。
PDV中变量按照先来后到的原则,是根据其在DATA步中第一次出现的位置决定整个PDV中的变量顺序。
同样,这是在DATA步的编译阶段确定的。
(在SET语句中,数据集选项IN=所指定的变量会在数据集变量之前)PUT_ALL_;语句会将PDV中所有的变量按照其在PDV中的顺序输出到log中。
例如下面这个例子:
datatest;
aaa=1;
setsashelp.class(keep=namesexin=in1);
byname;
bbb="bbb";
setsashelp.class(keep=ageweightheightin=in2);
put_all_;
run;
在PDV中共有13个变量,包括两个新创建的(aaa,bbb),5个数据集中的,6个自动生成的(in1,first.name,last.name,in2,_error_,_n_)。
顺序为:
aaa,in1,name,sex,first.name,last.name,bbb,in2,age,weight,height,_error_,_n_。
关于PDV中变量值的RETAIN
一般情况下,DATA步的执行是一个循环的过程,也就是SAS运行到DATA步最后一句后会默认回到DATA语句继续执行。
在回到DATA语句再次执行这个DATA步的代码的时候,就会涉及到是否对PDV中变量已有的值清空,这就是RETAIN要做的。
(这里用“一般情况下”,是因为有些情况下,SAS不会回到DATA语句,而是在RUN;语句就结束了。
如:
***Nodatareadfromoutside;
dataa;
put_all_;
x=1;
run;
***Nodatareadfromthefirstiteration(_N_=1);
datab;
x=2;
put_all_;
ifx=1thensetsashelp.class;
run;
)
回到PDV:
a.在DATA步刚开始执行的时候:
自动生成变量会被附上初始值:
_N_=1,_ERROR_=0,FIRST.VAR=1,LAST.VAR=1,等等;
如果RETAIN语句对某变量设置了的初始值,则对应的变量被设为指定的值;
SUM语句(如a+1;)的变量会被初始化为0;
其他的变量,包括新建变量和SET的数据集对应的变量都会被设为空值。
b.当SAS执行过程中再次回到DATA语句时:
自动生成变量的值会被retain;
如变量来自RETAIN语句、SUM语句、或数据集中,则变量值会被retain;
其他的变量会被置空。
例如,可以根据下面DATA步所产生的log来判断变量的retain情况:
procsortdata=sashelp.classout=class;
byage;
run;
datatest;
put"===============================";
put"Atbegnning:
"_all_;
aaa=_N_;
setclass(keep=nameagein=in1);
byage;
bbb+age;
retainccc0;ccc=age+ccc;
retainddd;ddd=sum(ddd,age);
put"Atending:
"_all_;
run;
合并
DATAa;
inputtype$City$;
cards;
A上海
A广州
B北京
C重庆
C天津
C南昌
;
RUN;
PROCsortdata=a;
bytype;
RUN;
DATAb;
lengthCity_combine$256;
retainCity_combine;
seta;
bytype;
iffirst.type+last.type=2thendo;
City_combine=City;
output;
end;
elseiffirst.typethenCity_combine=City;
elsedo;
City_combine=compress(City_combine)!
!
","!
!
compress(City);
iflast.typethenoutput;
end;
RUN;
PROCsortdata=sasuser.test;
byVAR1;
RUN;
DATAsasuser.test1;
lengthres_code$256;
retainres_code;
setsasuser.test;
byVAR1;
iffirst.VAR1+last.VAR1=2thendo;
res_code=VAR2;
output;
end;
elseiffirst.VAR1thenres_code=VAR2;
elsedo;
res_code=compress(res_code)!
!
","!
!
compress(VAR2);
iflast.VAR1thenoutput;
end;
RUN;
Length语句
SAS变量的基本类型有两种:
数值型和字符型。
日期、时间等变量存为数值型。
SAS的数值型变量可以存储任意整数、定点实数、浮点实数,一般不关心其区别。
数值型变量在数据集中的存贮一般使用8个字节。
SAS的字符型变量缺省的长度是8个字符,但是如果在INPUT语句中输入字符型变量时指定了长度则不受此限制。
可以用LENGTH语句直接指定变量长度,LENGTH语句一般应出现在变量定义之前,格式为:
LENGTH变量名$长度;
例如
LENGTHname$20;
$和@@
"$",表示字符型变量
"@@":
一行有多个观测值时,使用@@,sas将在读完一个观测后保持在该行继续读取下面的观测值,直到所有观测读完或者到input后面的变量完为止。
祥见相关书籍:
如thelittlesasbook等等
datalinescards一样的
数值类型
SAS常量主要有数值型、字符型两种,并且还提供了用于表达(不是存储)日期、时间的数据类型。
例如
∙数值型:
12,-7.5,2.5E-10
∙字符型:
'Beijing',"LiMing","李明"
∙日期型:
'13JUL1998'd
∙时间型:
'14:
20't
∙日期时间型:
'13JUL1998:
14:
20:
32'dt
赋值的时候可以写成这个样子赋值,
DATAx;x='14:
20't;run;
但是存储的时候还是数值类型
日期格式的时候你声明了是D或者T了
sas自动日期转化为数字到存储地方,在展现的时候,用format语句就可以了,不过格式不带T的
数值型常数可以用整数、定点实数、科学计数法实数表示。
字符型常数为两边用单撇号或两边用双撇号包围的若干字符。
日期型常数是在表示日期的字符串后加一个字母d(大小写均可),中间没有空格。
时间型常数是在表示时间的字符串后加一个字母t。
日期时间型常数在表示日期时间的字符串后加字母dt。
因为SAS是一种数据处理语言,而实际数据中经常会遇到缺失值,比如没有观测到数值,被访问人不肯回答,等等。
SAS中用一个单独的小数点来表示缺失值常量。
SAS变量的基本类型有两种:
数值型和字符型。
日期、时间等变量存为数值型。
SAS的数值型变量可以存储任意整数、定点实数、浮点实数,一般不关心其区别。
数值型变量在数据集中的存贮一般使用8个字节。
SAS的字符型变量缺省的长度是8个字符,但是如果在INPUT语句中输入字符型变量时指定了长度则不受此限制。
可以用LENGTH语句直接指定变量长度,LENGTH语句一般应出现在变量定义之前,格式为:
LENGTH变量名$长度;
例如
LENGTHname$20;
标准的数字型:
如不带货币符号,千分位号等
标准的字符型:
如字符中间不嵌空格等
存储的都是标准的格式
日期格式
sas输入日期格式是16JAN2014,日月年+d;(赋值的时候输入,且只能输入这种格式,可能是d的写法的特别规定,但是在input、informat中可以09-01-12这种写法,这是格式为ddmmyy,format中不存在这种问题)
因为输入的时候不用jan的话,sas区分不了年月日
输出的格式可以是这样(date9.)这是显示16JAN2014,
也可以yymmdd9.,ddmmyy8.
datetime.(月份也是英文缩写)、time.(表面意思)
Day.输出日期中“天”:
16month.为输出为月:
1
SAS输入格式就是告诉sas这是日期格式的,不是数字,存储的时候要转化,比如:
'13JUL1998'd和下面的日期函数,而货币等格式中输入和输出的格式一样写的,赋值语句中日期也想写成一样啊,但是我们写的时候将datetime简写了而已
没有输入格式的话,sas会把我们的数据当成字符或者数字,直接放在sas存储里面,输出的时候就算转换格式的话,也会转化成其他的日期格式,下面的日期函数也差不多
SAS系统提供的几种常用输入输出格式:
w.d标准的数字型格式
$w.标准的字符型格式
commaw.d数字中加入逗号
dollarw.d数字中加入逗号,数字前加入$
datew.日期格式
bestw.SAS选择最佳表示法
而‘01jan13’d不过是格式的补充而已,在赋值语句使用(暂未发现其他的使用方法)
无论informat还是format语句,数据格式还是一样的
日期函数
(不管输入输出的,有参数就出现,一般用在赋值输入格式中)
TODAY()当前系统的日期值(年月日)
TIME()当前系统的时间值(时分秒)
DATE()当前系统的日期值(年月日)
DAY(自变量)自变量的月内日期值(1-31)day(‘02dec66’d)=2
--day里面的变量存储的是数字,直接转化为日期格式,求天值
WEEKDAY(自变量)自变量的周内参数(1-7)weekday(‘02dec66’d)=6
MONTH(自变量)自变量的月份值(1-12)month(‘02dec66’d)=12
QTR(自变量)自变量的季度值(1-4)qtr(‘02dec66’d)=4
YEAR(自变量)自变量的年份值year(‘02dec66’d)=1966
WEEKDAY(自变量)的值为1,表示的周日,周一为2,依此类推。
value
VALUE语句定义一种值输出格式,可把某变量的值按所定义的格式输出。
可把数值变成字符或把字符转变成另一字符。
每一VALUE语句可定义一种格式,在一个FORMAT过程中,你可以使用多个VALUE语句定义多个格式。
在fo