导入tab文件
目录
编译阶段compliation phase 写入哪些部分?(以下错误的是)
- &与空格作为分隔符的文件时, dbms=dlm; delimiter="&";
tab作为分隔符时,dbms=tab ; delimiter= “09”x;
proc import datafile='C:\Users\Student1\cert\class.txt' dbms=tab
out=class
replace;
delimiter='09'x; run;
proc print data=class; run;
查找变量中的某些字段
proc print data=cert.class;
where name like "%DA%";
run;
- like可以换成contents与?
- index与find
set cert.temp; where index(job,'word processing') > 0; run; proc print data=work.datapool; run;
1).index与之前like的区别是不用体现var job 直接在index(job,“word processing”)
2).找到不不区分大小写的:index(upcase(job),'WORD PROCESSING') index(lowcase(job),'word processing')
find的用法跟index一样 目前没发现区别 都是where find(job,"word processing")>0
编译阶段compliation phase 写入哪些部分?(以下错误的是)
a.the data set descriptor-----> √
b.the first observation ------> X
c.the program data vector-----> √
d.the _N_and_ERROR_-----> √
在编译阶段,将创建程序数据向量。程序数据向量包括两个自动变量_N_和_ERROR_。新SAS数据集的描述符部分在编译阶段结束时创建。描述符部分包括数据集的名称、观察结果和变量的数量,以及变量的名称和属性。直到执行阶段才写入观察结果。
.1可以直接写为1
Sumsec+ 变量后直接跟“+”
data work.stresstest;
set cert.tests;
TotalTime=(timemin*60)+timesec;
SumSec+totaltime;
run;
(注:sumsec+后面 从0开始累加计算totaltime的值)
retain设定初始值
retain SumSec 5400;
sumsec+totaltime;
(注:retain一般与sumsec一起用啊)
length修改变量长度,一定要放在对应变量前的位置
data stress;
set cert.stress;
TotalTime=(timemin*60)+timesec;
retain SumSec 5400;
sumsec+totaltime;
length TestLength $ 6; (字符变量后面加$ 并且针对的是变量的内容)
if totaltime>800 then testlength='Long';
else if 750<=totaltime<=800 then testlength='Normal';
else if totaltime<750 then TestLength='Short';
run;
proc print data= stress;
run;
data work.newloan;
set cert.records;
TotLoan+payment;
if code='1' then Type='Fixed';
else Type='Variable';
length type $ 10;
run;
(新变量的长度由DATA步骤中的第一个引用决定,而不是由数据值决定。
你要设置length的话必须要在第一个变量前,目前的Type长度为5“Fixed”)
"IF ELSE IF ELSE" "IF THEN"
多个条件查询要使用if else 就像多个where要使用where also一样,最后一个else不需要加if:
if totaltime>800 then TestLength='Long';
else if 750<=totaltime<=800 then TestLength='Normal';
else put 'NOTE: Check this Length: ' totaltime=;
run;
(注: else put “想说的” 变量= 就能看到不满足条件的具体值是多少了)
if tolerance='D';
TotalTime=(timemin*60)+timesec;
(注:if后直接加分号时,只显示为D时与totaltime的值 )
if tolerance='D';
then TotalTime=(timemin*60)+timesec;
(两者效果一样)
transpose转置变量--需要回头再来学习
proc transpose data=cert.trials out=transtrials3; /* #1 */
var cholesterol triglyc uric; /* #2 */
id name; /* #3 */
by testdate; /* #4 */
run;
proc print data=transtrials3; /* #5 */
run;
(这个目前不理解 为什么用id 后 跟name 与 testdate没事 其他就报错 日志显示重复)
宏变量应用到title
%let TitleX=PROC MEANS Of Only &Cyl_Count Cylinder Vehicles;
%let Cyl_Count=12;
Title "&TitleX";
proc means data=sashelp.cars;
where Cylinders=&Cyl_Count;
var MSRP;
run;
(注:这个要注意的是 字符型的宏变量要用引号 数值型则不带引号 带了会报错)
nesting嵌套括号内优先级更高
if finlexam>=95
and (research='A' or
(project='A' and present='A'))
then Grade='A+';
(优先计算最内括号内的project='A' and present='A)
set与merge
1. data work.concat;
set cert.therapy2012;
set cert.therapy2013;
run;
2. data work.concat;
set cert.therapy2012 cert.therapy2013;
run;
3. data merged;
merge a b;
by num;
run;
4. proc sort data=cert.demog;
by descending id;
run;
proc sort data=cert.visit;
by descending id;
run;
data work.merged;
merge cert.demog cert.visit;
by descending id;
run;
rename
data work.merged;
merge cert.patdat (rename=(date=BirthDate))
cert.visit (rename=(date=VisitDate));
by id;
run;
in
data work.merged;
merge cert.patdat(in=inpat
rename=(date=BirthDate))
cert.visit(in=invisit
rename=(date=VisitDate));
by id;
if inpat =1 and invisit=1;
run;
proc print data=work.merged;
run;
(这样可以排除缺失值
可以通过以下两种方式指定前面示例中的子集IF语句。第一个IF语句专门检查值1。第二个IF语句检查一个既不缺失也不为0的值(对于IN= variables,它总是为1)。
if inpat=1 and invisit=1;
if inpat and invisit;
关于merge中几个要点:
1. by的顺序必须相同 不一致报错
2.相同变量后不同数值时 比如 id=1 表1 age=23 表2 age=24 表2会覆盖表1
3.不被覆盖就rename 排除缺失值用数据集 后 (in=xx) ; by xxx;if xx = 1 and。。。
4.set a c 如果a中只有id nameb只有id sales
这个公式第二个观测值 为missing 他会按表顺序 a name 1 2 3 4 然后 b sale 1 2 3 4 第二个观测值为name2 pale为missing
不同语句的用法:concatenate(连接) 中 :1.set a;
set c; 显示交集
do的嵌套与until、while
do主要有两个要点 :
*1.嵌套 nesting
每一个do语句都要加end 中间的capital + 2000 为从初始值2k开始
capital+interest为interest累计
data work.earn;
do year=1 to 20;
Capital+2000;
do month=1 to 12;
Interest=capital*(.075/12);
capital+interest;
end;
end;
run;
2.data work.invest;
*(until为从2000起始循环多少次到50000 如果10次最大到不了就用capital+4000尝试)
do year=1 to 10 until (Capital>=50000);
capital+2000;
capital+capital*.10;
end;
run;
3.data work.invest; *while会在开始时循环时求值,如果条件不符合直接循环失败
do while(Capital>=50000);
capital+2000;
capital+capital*.10;
Year+1;
end;
run;
UNTIL表达式在DO循环的底部求值。
因此,DO循环总是至少执行一次。
WHILE表达式在执行DO循环之前求值。因此,如果条件最初为false,则DO循环永远不会执行。
举例:到达 250时 或者使用10加仑时 gallons=1 to 10 ... ; while(Distance<=250) 换成until (Distance>=250)
---while 与 until 相反 while(le)要包含你要的条件 until则需要大于你要的条件 (ge)
formtlib 设置自定义格式
libname formtlib 'c:\sas\formats\lib';
proc format library=formtlib fmtlib;
run;
*fmtlib直接展示将关键字FMTLIB添加到PROC FORMAT语句中,
将显示目录中所有格式的列表,以及它们值的描述
首先建立永久的格式数据集 lib为library缩写
libname formtlib 'C:\Users\Student1\formats\lib';
proc format lib=formtlib; *不加这个lib=xxx 会自动创建临时的work.formtlib
value gender
1 = 'Male';
value agegroup
13 -< 20 = 'Teen'
20 -< 65 = 'Adult'
65 - HIGH = 'Senior';
value $col
'W' = 'Moon White'
'B' = 'Sky Blue'
'Y' = 'Sunburst Yellow'
'G' = 'Rain Cloud Gray';
run;
现在将格式存在了永久数据库中,还要将格式输出才可以替换:这一步实测必须有才行不然报错输出找不到这些变量名
proc format;
value gender
1 = 'Male'
2 = 'Female';
value agegroup
13 -< 20 = 'Teen'
20 -< 65 = 'Adult'
65 - HIGH = 'Senior';
value $col
'W' = 'Moon White'
'B' = 'Sky Blue'
'Y' = 'Sunburst Yellow'
'G' = 'Rain Cloud Gray';
run;
设置完成后format
data work.carsurvey;
set cert.cars;
format Sex gender. Age agegroup. Color $col. Income Dollar8.;
run;
proc print data=work.carsurvey;
run;
使用low/unknown选择不在范围内的变量
proc format lib=formtlib; * 设置格式 low-<13="child" other = "unknown";
value agefmt
low-<13='child'
13-<20='teenager'
20-<65='adult'
65-high='senior citizen'
other='unknown';
run;
使用“||”将变量组合在一起
Assignment=site||"/"||dept;
intnk查找两个日期区间
*查找当月工作满20年的员工:
data work.anniversary;
set cert.mechanics(keep=id lastname firstname hired);
Years=intck('year',hired,today());
if years=20 and month(hired)=month(today());
*当月工作满20年 如果不加month(hired)=month(today()) 会导致 含有其他月份
run;
proc print data=work.anniversary;
title '20-Year Anniversaries';
run;
intnx中的“b”“d”“e”
month后加5个月 b表示该月起始1号 m中间 d 最后
MonthX=intnx('month','01jan2018'd,5,'b'); 21336 (June 1, 2018)
MonthX=intnx('month','01jan2018'd,5,'m'); 21350 (June 15, 2018)
MonthX=intnx('month','01jan2018'd,5,'e'); 21365 (June 30, 2018)
week为从周日计算
left、scan、trim去除变量中的空格值
不区分空格与逗号时
LastName=scan(name,1,' ,');
*就等于LastName=scan(name,1) 空格与逗号是默认的分隔符,所以也可以不列出
*trim 去掉尾随的空格值
"||"连接符 不会移除空格值
left的作用是把这个name里的空格先去掉,
就是Mary前的空格用left去掉,然后再用trim去掉其他空格
(不用left跟不用trim一个效果,全都有空格 可能必须都得用)
data work.nametrim;
length Name $ 20 First Middle Last $ 10;
Name= 'Jones, Mary Ann, Sue';
First = left(scan(Name, 2, ','));
Middle = left(scan(Name, 3, ','));
Last = scan(name, 1, ',');
FullName = trim(First) || trim(Middle) ||Last;
drop Name;
run;
proc print data=work.nametrim;
run;
注意:一般lastname后面不添加空格,不用使用trim
catx用符号将变量连接
data work.newaddress(drop = address city state zip);
set cert.temp;
newaddress=catx(', ',address,city,zip);
run;
proc print data =work.newaddress;
run;
*最终显示为、address,city,zip三个变量的观测值用“,”相连接
upcase、lowcase与Propcase
upcase & lowcase & propcase
*大小写:
Job=upcase(job);
Contact=lowcase(contact);
*首字母大写
Contact=propcase(contact);
compbl去掉多余空格变成1个空格
*多余空格都变成一个空格,
如果一个变量在COMPBL函数返回值之前没有被赋值,
那么该变量将被赋予第一个参数的长度。
data _null_;
string='125 E Main St';
length address $10;
address=compbl(string);
put address;
run;
这里address=compbl(string);之前为
length address $10,所以显示为10个长度 125 E Main(算上单一空格)
未显示完全
compress删除所有空格
data _null_;
a='A B C D';
b=compress(a);
put b=;
run;
*b=ABCD 还有很多附件内容这个 从a到x 的 compress 留着以后再说吧
substr截取变量长度或替换
*1.放在等号右边 截取数据 features=substr(VIN,4,5);
data work.agencyemp(drop=middlename);
set cert.agencyemp;
length MiddleInitial $ 1;
MiddleInitial=substr(middlename,1,1); *这里最终结果为M 首字母且只有一位
run;
proc print data=work.agencyemp;
run;
*2.substr 放在=左边 替换相应的数据
substr(test,4,2)= “92”;
test------------->test
S7381K2 → S7392K2
S7381K7 → S7392K7
总而言之,当SUBSTR函数位于赋值语句的右侧时,该函数提取子字符串;
当SUBSTR函数位于赋值语句的左侧时,该函数将替换字符变量的内容。
将Phone中的前三位为622的观测值换成433
先找到622的位置,这里用exchange来代替,然后drop删掉
data work.temp2(drop=exchange);
set cert.temp;
Exchange=substr(phone,1,3);
IF EXCHANGE ="622" THEN
substr(phone,1,3)='433';
run;
proc print data=work.temp2;
run;
*不用if会把所有前三位替换成433 如果想只替换622需要用if then
关于ceil与floor
e-12 如果参数在一个整数的1E-12范围内,函数返回该整数
ceil内向上取整数到1,floor向下取整数到0
ceil
data _null_;
var1=2.1;
var2=-2.1;
a=ceil(var1);
b=ceil(var2);
put "a=" a;
put "b=" b;
run;
a=3
b=-2
-----------------------------
data _null_;
c=ceil(1+1.e-11);
d=ceil(-1+1e-11);
e=ceil(1+1.e-13)
put "c=" c;
put "d=" d;
put "e=" e;
run;
c=2
d=0
e=1
----------------------------------------
data _null_;
f=ceil(223.456);
g=ceil(763);
h=ceil(-223.456);
put "f=" f;
put "g=" g;
put "h=" h;
run;
f=224
g=763
h=-223
floor
data _null_;
var1=2.1;
var2=-2.1;
a=floor(var1);
b=floor(var2);
put "a=" a;
put "b=" b;
run;
a=2
b=-3
------------------------
data _null_;
c=floor(1+1.e-11);
d=floor(-1+1e-11);
e=floor(1+1.e-13)
put "c=" c;
put "d=" d;
put "e=" e;
run;
c=1
d=-1
e=1
---------------------------
data _null_;
f=floor(223.456);
g=floor(763);
h=floor(-223.456);
put "f=" f;
put "g=" g;
put "h=" h;
run;
f=223
g=763
h=-224