小白学SAS
2024-11-07 10:09:40 2 举报
AI智能生成
小白学SAS
作者其他创作
大纲/内容
1.初识SAS
起名:英文、数字和下划线
data 数据集名
input 变量1 变量2 ...;
cards;<br>数据<br>;
data first;<br>input gender age;<br>cards;<br>1 30<br>0 24<br>;
-first为永久数据集在sasuser里-<br>data sasuser.first;<br>input gender age;<br>cards;<br>1 30<br>0 24<br>;<br>
-在SAS逻辑库里建立一个名为“fgs”的文件夹,<br>并将它与电脑上的“g:\excel”文件夹关联起来-<br>libname fgs "g:\excel";<br>
-把first数据集添加到fgs文件夹中-<br>data fgs.first;<br>input gender sge;<br>cards;<br>1 30<br>0 24<br>;<br>
-在G盘EXCEL文件夹中生成一个名为FIRST的SAS数据集-<br>data "g:\excel\first";<br>input gender age;<br>cards;<br>1 30<br>0 24<br>;<br>
-对于自己建立的逻辑库,<br>在调用前需要用libname语句把逻辑库与文件夹建立关联-<br>libname fgs "g:\excel";<br>proc print data=fgs.first;<br>run;<br>
-如果用data"g:\excel\first";语句建立永久数据集的调用程序-<br>proc print data="g:\excel\first";<br>run;<br>
注释格式为:/*注释*/
2.SAS数据集建立的高级议题
SAS变量的输入格式
SAS变量:字符型和数值型<br>input 变量1 输入格式1 变量2 输入格式2 ...;<br><br>数值型的输入格式:w.d<br>(w表示数值的总位数或宽度,包括小数点;<br>d表示数值的小数部分的位数,即使没有小数,点号也要加上)<br>
data fh;<br>input x 4.2; /*变量后4.2表示变量x的宽度共4位,其中小数有2位*/<br>cards;<br>12<br>2.1<br>15.6<br>23.46<br>;<br>proc print; /*这句话的作用是让读入的数据显示在输出窗口*/<br>run;
字符型的输入格式:$w.<br>(其中$符号是必须加的,w表示字节数,<br>1各种问占2个字节,SAS默认对字符只读取8位)<br>
data fh;<br>input pro $12.;<br>cards;<br>山东省青岛市<br>;<br>proc print;<br>run;
如果不加12.,只加一个$符合,那么只显示“山东省青”<br>只要加上宽度值,后面必须跟着“.”,但是如果只写$符号而没有宽度值,就不用加“.”
日期型变量的输入格式
如果年月日之间没有任何分隔符,此时SAS要求输入的月和日都是2位
两个特殊输入字符:和&
<span style="font-size: inherit;">冒号:的作用是告诉SAS,如果要读取下一个变量,需要满足下面任一条件:要么遇到空格,要么变量的宽度读完。<br>(一旦对变量指定了宽度,SAS就不再以默认的空格作为区分的标志了,而是按指定的宽度来识别变量。)</span><br>
data fh;<br>input city:$18. zone$; /*在city后加了一个冒号*/<br>cards;<br>山东省蓬莱市 0536<br>山东省青岛市市南区 0532<br>;<br>proc print;<br>run;
data fh;<br>input day1: yymmdd10. day2: yymmdd10.; /*在day1后加了一个冒号*/<br>cards;<br>130125 20130528<br>;<br>proc print;<br>run;
1.一旦对变量指定了宽度,SAS就按指定的宽度来读取变量。<br>2.如果指定了宽度,SAS就忽略空格的作用,而是把包括空格在内的所有字符都作为变量的值。<br>3.不过要记住,日期型变量的宽度最大不能超过32。<br>4.如果有超过2个以上的变量指定了宽度,最好都用冒号结合一个的宽度值得方式来输入。
&符号的作用:变量值包含空格的情况下使用<br>(当变量本身就有空格是时,变量之间就需要2个或2个以上的空格隔开,<br>这样SAS就会把这2个或2个以上的空格作为变量分隔符)<br>
data fh;<br>input name&:$50. city&:$50.;<br>cards;<br>Peter Parker 山东省 蓬莱市<br>Ross Geller 山东省 青岛市 市南区<br>;<br>proc print;<br>run;
SAS变量的输出格式
指定输入格式会改变变量的值,而指定输出格式不会改变变量的值,只会改变它们的样子。<br>input<br>format 变量1 格式1 变量2 格式2 ...;<br>cards<br><br>数值型变量常用的输出格式:3种<br>w.d<br>commaw.d(将数值的整数部分自右向左每三位用逗号隔开)<br>percentw.d(将数值显示位百分比的形式,%占3个字节)<br>
data wt;<br>input num cost prop;<br>format num 5.2 cost comma12.1 prop percent8.2;<br>cards;<br>50 10205600 0.1236<br>45 9580000 0.0361<br>;<br>proc print;<br>run;<br>
字符型的输出格式:与输入格式一样也是$w.
data fs;<br>input x$ y$2.;<br>format x$2.;<br>x1=x+1;<br>y1=y+1;<br>cards;<br>1100 1100<br>;<br>proc print;<br>run;
日期型变量的输出格式
data dat;<br>input date1:yymmdd10. date2:yymmdd10. date3:yymmdd10.;<br>format date1 yymmdd10. date2 yymmdds8. date3 yymmddp8.;<br>cards;<br>13.06.16 130616 20130616<br>;<br>proc print;<br>run;
自定义输入和输出格式
用informat和format自定义格式
proc format;<br>invalue <$>格式名 变量值或范围1=输入格式1...; /*如果定义的输入格式是字符,需要在格式名前加$*/<br>value <$>格式名 变量值或范围1=输出格式1...;/*如果变量值或范围是字符,需要在格式名前加上$*/<br>picture 模板名<数值范围>;
proc format;<br>invalue fage low-<40=30 40-<50=40 50-<60=50 60-hiigh=60;<br>data age;<br>input id age fage.; /*在变量age后假上自定义的输入格式fage,别忘了加点号*/<br>cards;<br>1 36<br>2 43<br>3 51<br>4 60<br>5 59<br>;<br>proc print;<br>run;
proc format;<br>invalue fage low-<40=30 40-<50=40 50-<60=50 60-hige=60;<br>data age;<br>input id age fage.; /*在变量age后加上自定义的输入格式fage,别忘了加点号*/<br>cards;<br>1 36<br>2 43<br>3 51<br>4 60<br>5 59<br>;<br>proc print;<br>run;
proc formate要写在data语句前
proc format;<br>invalue $grade 1="Freshman" 2="Sophmore" 3="Junior" 4="Senior";<br>value fscore low-<60="不及格" 60-<80="及格" 80-high="优秀";<br>data grade;<br>input id grade:$grade20.score;<br>format score fscore.;<br>cards;<br>1 1 60<br>2 4 59<br>3 3 80<br>4 2 79<br>;<br>proc print;<br>run;
grade 本身值1~4都只有1位宽度,但是指定的输入格式,<br>真正读取的是Freshman、Sophomore等,所以需要grade:$grade20.<br><br>value需要用format语句将变量score和输出格式fscore关联起来。<br><br>proc format是个过程,format是个语句,<br>只是把变量与某种输出格式关联起来,让变量按照这种格式输出。<br>
picture 不是定义值,而是定义一种显示的样式。
proc format;<br>picture pft low-high="0,000,000"(prefix="¥");<br>picture pro low-high="09.99%";<br>run;<br>data profit;<br>input profit prop;<br>format profit pft. prop pro.;<br>cards;<br>298630 16.72<br>365800 21.30<br>;<br>proc print;<br>run;
pft为指定样式名,low-high表示所有值,(所有值都加一个前缀)<br>0和非0数字有区别:用0表示的话会自动去数字前面的0.<br>最好每个程序结束都要加一个run来结束。
产生新变量
利用表达式或函数直接产生新变量
data a1;<br>input wt ht;<br>bmi=wt/(ht/100)**2;<br>rbmi=sqrt(bmi);<br>obesity=(bmi>=28);<br>city="北京";<br>date="02apr2013"d;<br>format date yymmdd10.;<br>cards;<br>60 170<br>55 166<br>73 161<br>;<br>proc print;<br>run;
注意:data与date 中英文大小写<br>sqrt是平方根计算的意思。<br>日期常量都要写成“年月日”d这种格式。
利用if-then语句产生新变量
-基本格式-<br>if 表达式 then 新变量= ;<br>eles 新变量= ;<br>
data lx;<br>input id lx$;<br>lx1=lx in ("有效","显效","痊愈");<br>if lx in ("有效","显效","痊愈")then lx2="有效";else lx2="无效";<br>cards;<br>1 显效<br>2 有效<br>3 无效<br>4 痊愈<br>;<br>proc print;<br>run;
lx1是用的比较运算符<br>lx2是用的if语句产生的变量
利用retain语句和累加语句产生新变量
-retain语句基本格式-<br>retain 变量 <初始值>;<br>例如:retain a 21;(指定a的初始值为21)<br> retain year 2001 total 0;(指定year的初始值为2001,total的初始值为0)<br>-累加语句基本格式-<br>变量+表达式<br>year+1,(默认year=0,year+1产生的结果就是year=1)<br>total+amount;(amount变量必须在前面已经指定了,此时相当于total=total+amount)
-错误示例-<br>data fh;<br>count=0;<br>count=count+1;<br>input time ;<br>cards;<br>23<br>29<br>49<br>;<br>proc print;<br>run;<br>
-retain语句-<br>data fh;<br>retain count 0;<br>count=count+1;<br>input time ;<br>cards;<br>23<br>29<br>49<br>;<br>proc print;<br>run;<br>
-累加语句-<br>data fh;<br>count+1;<br>input time ;<br>cards;<br>23<br>29<br>49<br>;<br>proc print;<br>run;<br>
data fsh;<br>input amount;<br>retain year 2000;<br>year+1;<br>total+amount;<br>cards;<br>100<br>200<br>300<br>;proc print;<br>run;
利用do循环语句产生新变量
data fh;<br>input count time;<br>cards;<br>1 23<br>2 29<br>3 49<br>4 64<br>5 87<br>;<br>proc print;<br>run;
data fh;<br>do count=1 to 5;<br>input time;<br>output;<br>end;<br>cards;<br>23<br>29<br>49<br>64<br>87<br>;<br>proc print;<br>run;
注意:<br>1.忘记写output;语句,这导致SAS只能读取最后一个数,<br> 因为前面的数你没有通知SAS显示;<br>2.忘记写end;语句,此时SAS找不到循环结束的标志,给不出结果。<br>
指定新变量的类型和长度
-SAS主要用length语句来指定新变量的长度与类型-<br>length 变量 <$> 长度1 变量2 <$> 长度2 ...;
-错误示例-<br>data lx;<br>input id lx$;<br>if lx="无效" then lx2="无效";<br>else lx2="有效+显效+痊愈";<br>cards;<br>1 显效<br>2 有效<br>3 无效<br>4 痊愈<br>;<br>proc print;<br>run;<br>
SAS有个规则:字符变量的长度是由第一个遇到的值的长度决定的,<br>而且字符变量一旦产生,它的长度就无法改变。<br>
data lx;<br>input id lx$;<br>length lx2 $16.;<br>if lx="无效" then lx2="无效";<br>else lx2="有效+显效+痊愈";<br>cards;<br>1 显效<br>2 有效<br>3 无效<br>4 痊愈<br>;<br>proc print;<br>run;
length语句一定要写在if语句之前,否则就是不起作用的。
data eva;<br>length bouns$5. eva$8.;<br>input id g bouns$;<br>if g<70 then eva="合格";else eva="不合格";<br>cards;<br>1 67 100000<br>2 80 110000<br>3 89 110000<br>;<br>proc print;<br>run;
@符号在输入方式中的应用
@@
-错误示例-<br>data fsh;<br>input id age;<br>cards;<br>1 23 2 29 3 49 4 36<br>;<br>proc print;<br>run;<br>
data fsh;<br>input id age@@;<br>cards;<br>1 23 2 29 3 49 4 36<br>;<br>proc print;<br>run;
@@是强制SAS往右读取数据
@
data score;<br>input gender$ id score;<br>cards;<br>M 1 86<br>M 2 90<br>M 3 83<br>M 4 79<br>F 1 85<br>F 2 93<br>F 3 90<br>;<br>proc print;<br>run;
data score;<br>input gender$ n@;<br>do id=1 to n;<br>input score@@.;<br>output;<br>end;<br>cards;<br>M 4 86 90 83 79<br>F 3 85 93 90<br>;<br>proc print;<br>run;
SAS函数应用技巧
data age;<br>input id birth:yymmdd10. death:yymmdd10.;<br>age=(death-birth)/365;<br>if age<60 then age1=50;<br>else if age<70 then age1=60;<br>else age1=70;<br>format birth death yymmdd10.;<br>cards;<br>1 1954-12-06 2014-02-03<br>2 1938-02-18 2014-01-07<br>3 1947-07-10 2014-01-11<br>4 1943-08-21 2014-03-03<br>;<br>proc print;<br>run;
与数值计算有关的函数
round(4.8,2),意思是将4.8舍入到最接近能被2整除的数值(如0、2、4、6等)
data aa;<br>input age@@;<br>gage=round(age-5,10);<br>cards;<br>29 31 39 40 55 60 64<br>;<br>proc print;<br>run;
data aa;<br>input id@@;<br>if mod(id,2)=1 then group="A";else group="B";<br>cards;<br>1 2 3 4 5 6 7 8 9 10<br>;<br>proc print;<br>run;
与字符有关的函数
-计算变量的长度-<br>length(变量):计算变量长度,对缺失值返回1<br>lengthn(变量):计算变量长度,对缺失值返回0<br>-提取变量中的字符-<br>substrn格式:substrn(变量,起始位置<,提取长度>):指定一个变量,<br> 对该变量从起始位置开始,提取指定长度的字符,<br> 起始位置是从第几个字符开始提取,提取长度是提取多少个字符,<br> 这是可选项,如果不写,默认提取到最后一个字符<br>
data iden;<br>input iden:$18.;<br>if length(iden)=18 then gen=substrn(iden,17,1);<br>else gen=substrn(iden,15,1);<br>if mod(gen,2)=1 then gender="男";<br>else gender="女";<br>cards;<br>36053319720613591x<br>360533801215792<br>360533198208254533<br>360533851009226<br>;<br>proc print;<br>run;<br>
<br>
-查找变量中的字符-<br>find(变量,查找内容<,"i"><,起始位置>)<br>findc(变量,查找内容<,"i"><,起始位置>)<br><,"i">是忽略查找字符的大小写 <,起始位置>从第几个字符开始查找,如果不写,默认从第1个字符开始。<br>根据指定的起始位置,查找相应的内容。如果找到,就返回找到的位置;如果找不到,就返回到0<br>对于多个字符的查找,find必须是所有字符都完全匹配才算找到,而findc只要找到字符中的任意一个就算找到。<br>
data book;<br>input book:&$100.;<br>sas=find(book,"sas","i");<br>if sas>0 then class="SAS书";<br>else class="其他";<br>cards;<br>Survival Analysis Using SAS<br>Matlab程序设计<br>SPSS数据分析<br>SAS应用分析<br>The Little SAS Book<br>;<br>proc print;<br>run;
anyalpha(变量<,起始位置>);查找变量中任意的字母,并返回第一个字母的位置<br>anydigit(变量<,起始位置>);查找变量中任意的数字,并返回第一个数字的位置<br>anyalnum(变量<,起始位置>);查找变量中任意的字母或数字,并返回第一个字母或数字的位置
data computer;<br>input type$@@;<br>alpha=anyalpha(type); /*返回第1次出现字母的位置*/<br>digit=anydigit(type); /*返回第1次出现数字的位置*/<br>xh=substrn(type,alpha,digit-alpha); /*提取type中的字母*/<br>bh=substrn(type,digit,length(type)-digit+1); /*提取type中的数字*/<br>cards;<br>TP340 KS320 B3510 C560 H430<br>;<br>proc print;<br>run;<br>
-替换变量中的字符-<br>tranwrd(变量,查找值,替换值):从变量中找到“查找值”,并用“替换值”替换掉<br>
data lx;<br>input id lx$;<br>lx1=tranwrd(lx,"显效","有效");/*将lx变量中的“显效”替换为“有效”*/<br>lx1=tranwrd(lx1,"痊愈","有效");/*将lx1变量中的“痊愈”替换为“有效”*/<br>cards;<br>1 显效<br>2 有效<br>3 无效<br>4 痊愈<br>;<br>proc print;<br>run;
tranwrd有个缺点,一次只能替换一个字符串,<br>也就是说,他不能同时把显效和痊愈都替换为有效,只能一次替换一个。<br>所以第一个lx1将显效替换成了有效,但痊愈并没有被替换掉,<br>所以在此基础上对lx1中的痊愈再次替换,仍然复制为lx1.<br>
-去除变量中的字符-<br>compress(变量<,欲去除的字符><,"修饰符">):从变量中去掉"欲去除的字符"<br>指定不同的修饰符,常用的有:<br>a,去掉变量中的所有字母<br>d,去掉变量中的所有数字<br>s,去掉变量中的所有空格<br>i,忽略大小写<br>k,保留“欲去除的字符”,去掉其他字符<br>
data computer;<br>input type$@@;<br>xh=compress(type,,"d"); /*去除type中的所有数字*/<br>bh=compress(type,,"a"); /*去除type中的所有字母*/<br>cards;<br>TP340 KS320 B3510 C560 H430<br>;<br>proc print;<br>run;
compress中变量的第1个逗号后是“欲去除字符”和“修饰符”都是可选项,<br>SAS认为compress中变量的第1个逗号后市“欲去除字符”,第2个逗号后是“修饰符”。<br>即使你不指定“欲去除字符”,也需要用逗号留出它的位置,此时默认是去除空格。<br>
data phone;<br>input phone:&$20.;<br>phone1=compress(phone,"(-) "); /*去除phone中的4个字符“(-) ”*/<br>phone2=compress(phone,,"kd"); /*保留phone中的所有数字*/<br>cards;<br>(010)67658925<br>010-67685621<br>010 67685621<br>;<br>proc print;<br>run;
-变量的合并-<br>cats(变量1,变量2,...):将几个变量合并为一个变量,删除前后空格<br>catx("分隔符",变量1,变量2,...):将几个变量合并为一个变量,中间用分隔符隔开<br>分隔符“/”“-““~”"||"<br>
data code;<br>input prov$ city$ county$;<br>code1=cats(prov,city,county);<br>code2=catx("-",prov,city,county);<br>code3=prov||city||county;<br>cards;<br>37 05 02<br>37 03 21<br>37 06 13<br>37 06 85<br>;<br>proc print;<br>run;
-清点变量中某字符的个数-<br>count(变量,欲清点的字符<,"i">):从变量中找到"欲清点的字符",返回字符个数,<br>如果没有找到,返回0.<,"i">指定修饰符i,作用是忽略大小写。<br>
data cloth;<br>input pj&:$1000.;<br>beauty=count(pj,"漂亮");<br>cards;<br>裙子很漂亮,穿起来有仙女的感觉<br>裙子很喜欢,很漂亮,不知道面料牢固不牢固<br>裙子很漂亮<br>裙子很飘逸<br>面料柔软舒适,很飘逸<br>很漂亮,超喜欢这颜色<br>质量一般,没想象中的好<br>很大方,不足之处是,透气性不是非常好<br>;<br>proc print;<br>run;<br>
data ques;<br>input id (y1-y10)($); /*输入变量y1-y10,均为字符型,统一加上$符号*/<br>y=cats(of y1-y10); /*将y1-y10合并为一个变量y*/<br>cy=count(y,"y","i"); /*统计变量y中的"y"的个数,忽略大小写*/<br>cn=count(y,"n","i"); /*统计变量y中的"n"的个数,忽略大小写*/<br>cards;<br>1 y y n Y n y n Y n n<br>2 y n y Y n y y Y n y<br>3 n y N y y y n Y y n<br>4 n n Y y y y N Y n y<br>;<br>proc print;<br>run;
-查找变量中的缺失值-<br>missing(变量):判断变量是否为缺失值,是则返回1,不是则返回0.<br>SAS是用"."表示缺失值,所以就用if语句查找"."。<br>missing对数值型变量和字符型变量都是通用的。
data baseline;<br>input id gender$ age;<br>mgender=missing(gender); /*判断gender是否有缺失*/<br>mage=missing(age); /*判断age是否有缺失*/<br>cards;<br>1 f 60<br>2 m 59<br>3 f .<br>4 . 48<br>;<br>proc print;<br>run;
与日期和时间有关的函数
-日期的合并与差值-<br>mdy(月,日,年):将年月日合并为一个日期格式的变量或值<br>yrdif(开始日期,结束日期,"计算依据"):计算两个日期之间以年为单位的差值<br>datdif(开始日期,结束日期,"计算依据"):计算两个日期之间以天为单位的差值<br>指定计算差值的依据,通常指定"actual",也就是按当年的实际天数计算,也可以指定其他依据,比如“ACT/365”,<br>表示不管当年多少天,全部都按365天来算。<br><br>
data date;<br>input year1$ month1$ day1$ year2$ month2$ day2$;<br>date1=mdy(month1,day1,year1);<br>date2=mdy(month2,day2,year2);<br>format date1 date2 yymmdd10.;<br>ydif=yrdif(date1,date2,"actual");<br>ddif=datdif(date1,date2,"actual");<br>cards;<br>2013 05 21 2014 03 11<br>2013 03 10 2014 01 22<br>2013 06 05 2014 05 06<br>2013 07 08 2014 04 13<br>;<br>proc print;<br>run;
-日期的提取-
带时间的日期变量输入格式:<br>一是datetimew.格式(w.指定长度),主要用于ddmmyyhh:mm:ss格式的数据,如26JUN09:12:00:00;<br>二是ymddttmw.格式(w.指定长度),主要用于<yy>yy-mm-dd/hh:mm:ss格式的数据<br>(日期和时间之间的分隔符除了“/”外,还可以是“-”“.”":" ),如2009/6/26:13:00:00<br><br>带时间的日期变量输出格式:<br>datetimew.(w.指定长度),显示为ddmmyy hh:mm:ss的格式,如26JUN09:13:00:00<br>如果只有时间而没有日期,输入和输出格式可以写成timew.(w.指定长度)的格式。<br>
data dt;<br>input dt:ymddttm30.; /*指定dt为ymddttmw.格式*/<br>date=datepart(dt); /*提取dt的日期部分*/<br>time=timepart(dt); /*提取dt的时间部分*/<br>month=month(date); /*提取date的月*/<br>hour=hour(time); /*提取time的小时*/<br>formate dt datetime30.; /*指定dt的输出格式为datetime30.*/<br>format date yymmdd10.; /*指定date的输出格式为yymmdd10.*/<br>format time time12.; /*指定time的输出格式为time12.*/<br>cards;<br>2009/6/26:11:20:00<br>2009/5/5:19:30:00<br>2009/9/12:13:20:00<br>;<br>proc print;<br>run;
与变量类型转换有关的函数<br>*当使用自定义格式时,如果用input函数,proc format就要用invalue语句;<br>*如果用put函数,proc format就要用value语句。put函数输出的值一定是字符型。<br>*靠左是字符型,靠右是数字型<br>
input函数:主要用于把字符型转为数值型<br>格式:input(变量,输入格式):字符型转换为数值型,或将字符型转换为其他格式的字符型
data date;<br>input year1$ month1$ day1$ year2$ month2$ day2$;<br>date1=catx("/",year1,month1,day1); <br>date2=catx("/",year2,month2,day2);<br>d1=input(date1,yymmdd10.); /*将date1按yymmdd10.的格式转换为日期型*/<br>d2=input(date2,yymmdd10.); /*将date2按yymmdd10.的格式转换为日期型*/<br>format d1 d2 yymmdd8.;<br>dif=d2-d1;<br>cards;<br>2013 05 21 2014 03 11<br>2013 03 10 2014 01 22<br>2013 06 05 2014 05 06<br>2013 07 08 2014 04 13<br>;<br>proc print;<br>run;
子主题
data date;<br>input year1$ month1$ day1$ year2$ month2$ day2$;<br>date1=cats(year1,month1,day1); <br>date2=cats(year2,month2,day2); <br>d1=input(date1,yymmdd10.); /*将date1按yymmdd10.的格式转为日期型 */<br>d2=input(date2,yymmdd10.); /*将date2按yymmdd10.的格式转为日期型 */<br>d3=input(date1,8.); /*将date1按8.的格式转为数值型 */<br>d4=input(date2,8.); /*将date2按8.的格式转为数值型 */<br>format d1 d2 yymmdd10.; <br>dif1=d2-d1;<br>dif2=d4-d3;<br>cards;<br>2013 05 21 2014 03 11<br>;<br>proc print;<br>run;
put函数:主要用于把数值型转为字符型<br>格式:put(变量,输出格式):数值型转换为字符型,或将字符型转换为其他格式的字符型
proc format;<br>invalue fage low-<40=30 40-<50=40 50-<60=50 60-high=60;<br>data age;<br>input id age fage.; <br>cards;<br>1 36<br>2 43<br>3 51<br>4 60<br>5 59<br>;<br>proc print ;<br>run;
<br>proc format;<br>value fage low-<40=30 40-<50=40 50-<60=50 60-high=60;<br>data age;<br>input id age; <br>ageg=put(age,fage.); <br>cards;<br>1 36<br>2 43<br>3 51<br>4 60<br>5 59<br>;<br>proc print ;<br>run;
*靠左是字符型,靠右是数字型;<br>*当使用自定义格式时,如果用input函数,proc format就要用invalue语句;如果用put函数,proc format就要用value语句。<br>*put函数输出的值一定是字符型的,不管它看起来是数字还是其他样子。<br>*用input和put函数转换已有变量的时候一定要赋值给另外一个变量,而不是原有变量。
与概率和分布有关的函数
cdf("分布",分位数,参数):返回指定分布的累计概率分布与分位数对应的概率
dif和lag函数
3.SAS数据清洗和加工
数据合并
利用set语句进行纵向合并
data 数据集;<br>set 数据集1 数据集2 ...;<br>run;
*如果后面只有一个数据集,此时相当于复制的作用。
set 数据集1(in=临时变量1) 数据集2(in=临时变量2)...;<br>
data ab1;<br>set saauser.a1 sasuser.b1;<br>proc print;<br>run;
set 数据集1(rename=(原名1=新名1 ...)) 数据集2(rename=(原名1=新名1 ...)) ...;<br>
data ab1;<br>set sasuser.a1 sasuser.b1(rename=(ht=height wt=weight));<br>proc print;<br>run;
用proc contents看变量的属性
proc contents data=sasuser.a2;<br>run;
将字符型的time转为数值型<br>data saauser.b2;<br>set sasuser.b2;<br>time1=input(time,yymmdd10.);<br>format time1 yymmdd10.;<br>drop time;<br>rename time1=time;<br>run;
data语句作用是创建新的空白数据集<br>drop语句是删除
a2和b2合并后区分
data ab2;<br>set sasuser.a2(in=a) sasuser.b2(in=b);<br>a2=a;<br>b2=b;<br>proc print;<br>run;
in=a的意思是产生临时变量a<br>通过In=选项就可以吧合并数据集中的子数据集做个标识,但是临时变量可以调用,但不会在结果中显示。<br>只要用到数据集选项“in=临时变量”,就加一句“新变量=临时变量”
利用mergr语句进行横向合并
data 数据集;<br>merge 数据集1 数据集2 ...;<br>by 变量1 变量2 ...;<br>run;
data ab;<br>merge ab1 ab2;<br>by id;<br>drop a2 b2;<br>proc print;<br>run;
再利用by语句进行横向合并时,如果两个数据集实现一定要分别对他们都排序才能合并。<br>drop a2 b2;意思是删除a2 b2这两个变量。<br><br>
两个数据的交集
data ab;<br>merge ab1(in=d1) ab2(in=d2);<br>by id;<br>proc print;<br>run;
if d1=1 and d2=1;的意思是跟在set或merge语句后面时,他所起到的作用就是根据指定的表达式保留符合条件的观测。
数据对比
proc compare <base=数据集 compare=数据集><nosummary><transpose>;<br>by变量1 变量2 ...;<br>id变量1 变量2 ...;<br>run;
proc compare base=ab compare=cd nosummary;<br>by id;<br>run;<br>nosusmmary 的作用是不显示一些概括性的结果。
proc compare base=ab compare=cd nodummary transpose;<br>by id;<br>id id;<br>run;<br>按记录来显示核对。
data sasuser.xb;<br>set ab;<br>if id=4 then time="16Jun2012"d;<br>proc pront;<br>run;
数据清洗-查找和删除重复项
数据清洗-查找和删除重复项<br>
proc sort <data=数据集> <out=数据集><niuniquekey><nodupkey>;<br>by<descending>变量1<descending>变量2 ...;<br>run;<br>*proc sort 语句调用排序过程,选项data是指定对哪个数据集进行排序,选项out是数据集排序后输出位置,否则将覆盖原数据集。<br>*nouniquekey是输出重复值,nodupkey是删除重复值,输出唯一值。<br>*by语句是指定排序的变量,可以指定多个,选项descending表示按降序排序,如果不加,默认为按升序排序。<br>
proc sort data=ab1;<br>by id;<br>proc sort data=ab2;<br>by id;<br>run;<br>data ab;<br>merge ab1 ab2;<br>by id;<br>proc print;<br>run;<br>
proc sort data=sasuser.xb nouniquekey out=rep;<br>by nanme gender;<br>proc print data=rap;<br>run;<br>输出重复值
proc sort data=sasuser.xb nodupkey out=norep;<br>by name gender;<br>proc print data=norep;<br>run;<br>输出唯一值
扩展内容;first.变量和last.变量
data patients;<br>input id gender age time yymmdd10. sbp;<br>format time yymmdd10.;<br>cards;<br>1 1 51 2010/01/12 150<br>1 1 51 2010/02/12 147<br>1 1 51 2010/03/14 142<br>2 2 59 2010/01/09 163<br>2 2 59 2010/02/10 162<br>2 2 59 2010/03/17 160<br>2 2 59 2010/04/16 151<br>;<br>proc sort; <br>by id time; /*按id和time升序排序 */<br>run;<br>data patients;<br>set patients;<br>by id;<br>if first.id then firstsbp=sbp; /*对每个人的第一个观测,将sbp值赋给firstsbp */<br>retain firstsbp; /*利用retain语句让firstsbp保留上个观测值 */<br>difsbp=sbp-firstsbp; /*计算每次测量值与首次测量值的差值 */<br>proc print;<br>run;<br>
一是用proc sort 过程按id和time排序,这样SAS后台产生了first.id和last.id两个自动变量;<br>二是用set语句复制数据集时,也要加上by语句,否则SAS依然不认first.id和last.id.<br>
当if语句跟在set后面时,其作用时保留符合条件的观测。
first.id不是指第一个id值,而是id为某个值时,它所对应的多个观测中的第一个观测;同样,last.id不是指最后一个id值,而是id为某个值时,它所对应的多个观测中的最后一个观测。
数据清洗-查找缺失值
补充内容-数组
array 数组名[下标]<$><数组元素><(元素初始值)>;<br>array是定义数组的标志,看到array,你就要知道后面跟着的是数组。<br>数组名是给数组起个名字,名字的规则与SAS数据集名一样。<br>下表指定数组中包括的元素个数,这里的元素一般就是变量。<br>数组元素主要是列出数组中包含的1个或多个变量,这些变量可以是数据集中的已有变量,也可以是新的变量。如果新建的变量是字符型,需要在前面加上¥符号。<br>元素初始值指定新变量的值,如果不指定元素初始值,默认新变量的值为缺失值。<br>array s[5] a b c d e; 表示可以用s[1],s[2],s[3] s[4] s[5]分别代表a,b,c,d,e这五个变量。当你对s[1]操作时,就相当于对a进行操作,但s[1]~s[5]的命名更有规律,因而更容易执行一些批量命令。
数组定义的注意事项:<br>数组名不能与数据集中已有的变量重名,也不要与已有函数同名。<br>一个数组中的变量类型必须相同,不能既有数值型,又有字符型。<br>数组中下标的写法既可以用【】,也可以用{}或(),根据个人习惯。<br>数组中下表也可以是个范围,如arrat x[11:15] y11 y12 y13 y14 y15;。<br>数组中“下标”可以不写,而用*代替。如array 下【*】a b c;,SAS会自动根据变量个数来判断下标值为3.<br>数组中的“数组元素”可以不写,如array y[3];等同于array y[3] y1 y2 y3;.<br>元素初始值一定要用()括起来,各个值之间可以用逗号或空格隔开。
data missing;<br>set sasuser.xb;<br>array cha[1] name;<br>if missing(cha[1]) then output;<br>array num[10] gender age height weight time y1-y5;<br>do i=1 to 10;<br>if missing(num[i]) then output;<br>end;<br>proc print;<br>run;
data missing;<br>set sasuser.xb;<br>array cha[1] name;<br>if missing(cha[1]) then output;<br>array num[10] gender age height weight time y1-y5;<br>do i=1 to 10;<br>if missing(num[i]) then output;<br>end;<br><b>drop i;</b><br>proc print;<br>run;<br>
proc sort data=missing out=missing2 nodupkey;<br>by id;<br>proc print;<br>run;<br>剔除重复观测
补充内容-自动变量
_n_表示观测或记录的序号,如第一个观察_n_=1,第六个观测_n_=6。<br>_numeric_表示数据集中的所有数值型变量。<br>_character_表示数据集中的多有字符型变量。<br>_all_表示数据集中的所有变量。
data missing;<br>set sasuser.xb;<br>array cha[1] _character_ ;<br>if missing(cha[1]) then output;<br>array num[11] _numeric_ ;<br>do i=1 to 11;<br>if missing(num[i]) then output;<br>end;<br>proc print;<br>run;<br>
超值大礼包:查找缺失值的万能程序<br>
dim()函数是专门针对数组的函数,它的作用是返回指定数组所含的元素个数。<br>如指定数组array x[*]a b c;则dim(x)返回值为3.<br>
data missing;<br>set sasuser.xb;<br>array cha[*] _character_ ;<br>do i=1 to dim(cha);<br>if missing(cha[i]) then output;<br>end;<br>array num[*] _numeric_ ;<br>do i=1 to dim(num);<br>if missing(num[i]) then output;<br>end;<br>proc print;<br>run;<br>
数据清洗-查找异常值
data 新数据集;<br>set 已有数据集;<br>if|where 条件语句;<br>proc print;<br>run;
补充内容:if和where的区别<br>(1)在利用set语句有条件地复制数据集时,set后紧跟着条件句,此时用if和where都可以。<br>(2)if:使用SAS的自动变量时,只能用if,不能用where。<br> 如果指定的条件变量时新产生的变量,只能用if,不能用where。<br>(3)where:当使用某些特殊运算符时,只能用where语句,不能用if。<br> 特殊字符:between...and,contains"指定字符",like“指定字符”,is null或is missing<br> 当我们调用某一proc 过程时,如果要选择部分观测执行该过程,只能用where语句,不能用if语句。<br> 当作数据集选项使用时,只能用where.
between ...and:指定介于数值变量两个值之间的观测。<br>contains "指定字符":指定字符型变量中包含指定字符的观测。<br>like"指定字符":指定字符变量中与指定字符相似的观测,模糊部分可用%或_代替,其中%代表多个符号,_代表1个字符。<br>is null或is missing:指定包括缺失值的观测。
超值礼包-查找异常值的万能程序
%let data=sasuser.xb; /*此处改为自己的数据集*/<br>%let id=id; /*此处改为数据集中表示id号的变量*/<br>%macro outline(var=,low=,high=);<br>data outline;<br>set &data.(keep=&id. &var.);<br>length variable $20. reason $20.;<br>variable="&var.";<br>value=&var.;<br>if &var.<&low. and not missing(&var.) then do;<br>reason="过低";<br>output;<br>end;<br>else if &var.>&high. and not missing(&var.) then do;<br>reason="过高";<br>output;<br>end;<br>drop &var.;<br>proc append base=outliner1 data=outline;<br>run;<br>%mend outline;<br>%outline(var=height,low=150,high=200);<br>%outline(var=weight,low=40,high=100);<br>%outline(var=y1,low=1,high=5);<br>%outline(var=y2,low=1,high=5);<br>%outline(var=y3,low=1,high=5);<br>%outline(var=y4,low=1,high=5);<br>%outline(var=y5,low=1,high=5);<br>proc print data=outliner1;<br>run;<br>
缺失值的填补
缺失数据的填补
proc mi<out=数据集><round=><minimum=><maximum=>;<br>mcmc;<br>var 变量1 变量2 ...;<br>run;
proc mi语句调用填补缺失值,Out=是把填补后的数据保存到自定义的数据集中;<br>round=填补缺失值的小数位数;<br>minimum和maximum是指定填补值的最大值和最小值。
data xb9;<br>set xb_revised;<br>if id=9 then delete; /*利用if和delete删除id=9的观测*/<br>run;<br>proc mi data=xb9 out=nomissing round=1 1 1 minimum=150 1 1 maximum=200 5 5;<br>mcmc;<br>var height y2 y4;<br>run;<br>proc print data=nomissing;<br>run;<br>
缺失数据的更新
data 新数据集;<br>update 旧数据集 新数据集;<br>by 索隐变量;<br>run;
data xb_revised;<br>set sasuser.xb;<br>if id=6 then y3=1;<br>if id=7 then y5=5;<br>if id=9 then weight=56;<br>if id=10 then height=162;<br>proc print;<br>run;<br>
data newdata;<br>input id weight height y3 y5;<br>cards;<br>6 . . 1 .<br>7 . . . 5<br>9 56 . . .<br>10 . 162 . .<br>;<br>data xb_revised;<br>update sasuser.xb newdata;<br>by id;<br>proc print;
proc univariate data=nomissing noprint;<br>class id; <br>var height y2 y4;<br>output out=nm mean=height y2 y4;<br>run;<br>data newxb;<br>update xb9 nm;<br>by id;<br>height=round(height,1);<br>y2=round(y2,1);<br>y4=round(y4,1);<br>proc print data=newxb;<br>run;<br>
数据集选项
data aa;<br>input id x@@;<br>cards;<br>1 10 2 20 3 30<br>;<br>data bb;<br>set aa;<br>rename x=x1;<br>y=x+5;<br>run;<br><br>
<br>data aa;<br>input id x@@;<br>cards;<br>1 10 2 20 3 30<br>;<br>data bb(rename=(x=x1));<br>set aa;<br>y=x+5;<br>run;<br>
<br>data aa;<br>input id x@@;<br>cards;<br>1 10 2 20 3 30<br>;<br>data bb;<br>set aa(rename=(x=x1));<br>y=x+5;<br>run;<br>产生的与前两者不同
通常作为选项时,是与set语句同时起作用的;而作为语句时,是在set语句执行之后才起作用的。
产生数据子集
产生特定记录的子集
1.选择具有相同特征的人群子集
data 新数据集;<br>set 已有数据集;<br>if|where 条件语句;<br>run;
选择连续记录的数据子集
proc print data=数据集(firstobs= obs=);<br>run;
产生变量子集
0 条评论
下一页