SAS第五课
- 格式:doc
- 大小:126.00 KB
- 文档页数:12
第五课 SAS编程-第三部分一.SAS data step 的运行机制data a;put x= y= z=;input x y;z = x + y;put x= y= z=;cards;10 20100 200;run;上例说明 SAS data step 如果有数据输入,比如用 input,set, merge, update, modify 等语句输入数据,则此 data step 隐含了一个循环,即 data step 执行到最后一个语句后,会返回到 data step 内的第一个可执行语句开始继续执行,直到读入数据结束标志才停止执行 data step,并把读入的各个观测值写入在 data 语句中给定的数据集。
如果没有数据输入而只是直接计算,则 data step 不需要此隐含循环。
二.Infile 语句/* 读入外部数据 */data cars;infile"D:\93cars.txt" firstobs=2; /* 第一行是变量名,数据从第二行开始 */ input manu $ model $ type $ price; /*只读这几个变量*/run;proc print; run;/* 读入由不同的分隔符定义的数据 */data num;infile datalines dsd; /* dsd 表示数据的分隔符为逗号 */input x y z;datalines;,2,34,5,67,8,9;proc print; run;/* 如果字符型变量里含有分隔符,则将变量的值由引号引起来 */data scores;infile datalines dsd;input Name : $9. Score Team : $25. Div $;datalines;Joseph,76,"Red Racers, Washington",AAAMitchel,82,"Blue Bunnies, Richmond",AAASue Ellen,74,"Green Gazelles, Atlanta",AA;proc print; run;data weather;infile datalines missover; /* missover 防止SAS到下一行去读数据 */ input temp1-temp5;datalines;97.9 98.1 98.398.6 99.2 99.1 98.5 97.596.2 97.3 98.3 97.6 96.5;data nums;infile datalines delimiter='ab'; /* 字符 a,b 都是分隔符 */input X Y Z;datalines;1aa2ab34b5bab67a8b9;run;三.自定义输出格式和输入格式输入格式(informat)决定原始数据以什么样的方式读入和存储。
输出格式(format)决定数据以什么样的方式被表现出来。
这是所谓的the informat converts and the format prints.使用输入格式✧将数值型变量转化为字符型变量✧将数值型变量转化为另外的数值型变量✧将字符型变量转化为数值型变量✧将字符型变量转化为另外的字符型变量使用输出格式✧打印数值型变量为字符型变量✧打印字符型变量为另外值✧打印格式化的数值型变量/*输入格式(informat)*//* 由输入格式将字符型变量转化为数值型变量 */proc format; /*字符型转成了数值型*/invalue grade 'A'=4/* invalue 表示定义一个输入格式 */'B'=3'C'=2'D'=1'F'=0;run;data grades;input name $ (course1-course3) (: grade.);gpa = mean(of course1-course3);cards;BILL A B AJIM A B BRICK B C DROBERT D . F;/* 由输入格式检查数值型变量的取值是否合理 */`proc format;invalue check 1-4=_same_ /* 1 - 4 为正常值,保留原值 */99=.other=_error_;run;data evaluation;input name $ eval: check.;cards;BILL 4JIM 2RICK 3ROBERT 99Mary 5Peter 0;proc print; run;/*输出格式(format)*/data staff;input name $ 1-16 id 18-21 salary 24-28 site $ 31-33 hiredate: date7.; format hiredate date7.;cards;Capalleti, Jimmy 2355 34072 BR1 30JAN79Chen, Len 5889 33771 BR1 18JUN76Davis, Brad 3878 31509 BR2 20MAR84Leung, Brenda 4409 55256 BR2 18SEP74Martinez, Maria 3985 78980 US2 10JAN93Orfali, Philip 0740 80648 US2 16FEB83Patel, Mary 2398 56643 BR3 02FEB90Smith, Robert 5162 64561 US4 15APR86Sorrell, Joseph 4421 62403 US1 19JUN93Zook, Carla 7385 37010 BR3 18DEC91;run;/* 对字符型变量 site 定义一个输出格式 */proc format; /*字符型变为字符型*/value $city 'BR1'='Birmingham UK''BR2'='Plymouth UK''BR3'='York UK''US1'='Denver USA''US2'='Miami USA'other='INCORRECT CODE';run;proc print data=staff; format site $city.; run;/* 对数值型变量在打印时加入说明格式 */PROC FORMAT; /*数字型转为字符型*/VALUE fseason 1="winter"2="spring"3="summer"4="autumn";RUN;DATA SALES;INPUT YEAR SEASON OFFICE $ SALES;DATALINES;1991 1 NEWYORK 12341991 1 SEATTLE 5771991 1 CHICAGO 2881991 2 NEWYORK 12341991 2 SEATTLE 5771991 2 CHICAGO 2881991 3 NEWYORK 12341991 3 SEATTLE 5771991 3 CHICAGO 2881991 4 NEWYORK 12341991 4 SEATTLE 5771991 4 CHICAGO 288;Run;PROC PRINT; format season fseason.; Run; /*将格式 fseason.暂时加到season*/ DATA SALES;SET SALES;FORMAT SEASON fseason.; /* 将格式 fseason. 永久地加到 season 上*/ Run;PROC PRINT; Run;/* 对时间变量利用已知格式产生一个新的格式 */libname library "D:/sas"; /* 定义一个叫 library 的 library 来存放formats *//* 下面的library = library选项使得 SAS 可以去 library 中搜索 formats */proc format library = library;value benefit low-'31DEC1979'd = [worddate20.]'01JAN1980'd-high = ' ** Not Eligible **';run;data salary;input name $ 1-16 id 18-21 salary:comma7. site $ 31-33 date: date7.; cards;Capalleti, Jimmy 2355 $34,072 BR1 30JAN79Chen, Len 5889 $33,771 BR1 18JUN76Davis, Brad 3878 $31,509 BR2 20MAR84Leung, Brenda 4409 $55,256 BR2 18SEP74Martinez, Maria 3985 $78,980 US2 10JAN93Orfali, Philip 0740 $80,648 US2 16FEB83Patel, Mary 2398 $56,643 BR3 02FEB90Smith, Robert 5162 $64,561 US4 15APR86Sorrell, Joseph 4421 $62,403 US1 19JUN93Zook, Carla 7385 $37,010 BR3 18DEC91;run;proc print label noobs ;label date="Hire Date";format date benefit.;run;/* picture 格式*/libname my “D:/SAS”; "; /* 定义一个叫 my 的 library 来存放formats */options nodate pageno=1 linesize=80 pagesize=40 FMTSEARCH=(my); /* multi 和 prefix options */proc format library=my;picture uscurren low-high='000,000'(mult=1.61prefix='$'); run;proc print data=staff noobs label;label salary='Salary in U.S. Dollars';format salary uscurren.;title'STAFF with a Format for the Variable Salary';run;/* fill 和 prefix options */data pay;input name $ monthlysalary;cards;Liu 1259.45Lars 1289.33Kim 1439.02Wendy 1675.21Alex 1623.73;run;proc format library=my;picture salary low-high='00,000,000'(fill='*'prefix='$'); run;proc print data=pay noobs;format mothlysalary salary.;title'Printing Salaries for a Check';run;三.Arraydata changed(drop=count);input Reference Usage Introduction;array book{3} Reference Usage Introduction;do count=1to3;if book{count}=.then book{count}=0;end;totcnt = sum(of book{*});datalines;45 63 113. 75 15062 . 98;run;proc print data=changed;title“Number of Books Sold”;footnote;run;data changed(drop=count);input Reference Usage Introduction;array book{3} Reference Usage Introduction;do count=1to3;if book{count}=.then book{count}=0;end;datalines;45 63 113. 75 15062 . 98;proc print data=changed; title'Number of Books Sold'; run;/* 将所有字符型变量变为大写: names 是原始数据,capitals 是大写数据 */data text;array names{*} $ n1-n10;array capitals{*} $ c1-c10;input names{*}; /*是读取name的数据*/do i=1to10;capitals{i} = upcase(names{i});end;datalines;smithers michaels gonzalez hurth frank bleigh rounder joseph peters sam ;proc print; title'Names Changed from Lowercase to Uppercase'; run;/* 给一个 array 赋初值 */data score1(drop=i);array test{3} t1-t3 (908070); /*将 test 的三个变量的初值赋为90,80和70 */ array score{3} s1-s3;input id score{*}; /*读取id 和score 中的s1-s3*/do i=1to3;if score{i} >= test{i} then do;NewScore=score{i};output;end;end;datalines;1234 99 60 825678 80 85 75;proc print noobs data=score1; title'Data Set SCORE1'; run;/* 定义一个暂时 array,它的变量不会在最后的数据中出现 */data score2(drop=i);array test{3} _temporary_ (908070);array score{3} s1-s3;input id score{*}; /* 包括 score 所有的变量 */do i=1to3;if score{i}>=test{i} then do;NewScore=score{i};output;end;end;datalines;1234 99 60 825678 80 85 75;proc print noobs data=score2; title'Data Set SCORE2'; run;/* 对所有数值型变量做相同运算,每个都乘以倍数 3 */data sales;infile datalines;input Value1 Value2 Value3 Value4;datalines;11 56 58 6122 51 57 6122 49 53 58;data convert(drop=i);set sales;array test{*} _numeric_;do i=1to dim(test);test{i} = (test{i}*3);end;run;proc print data=convert; title'Data Set CONVERT'; run;五.常用函数/* Missing:如果变量有缺失值,则返回真 */data blood;input id 1 gender $ 3 wbc 6-7 rbc 10-12 chol 15-16;cards;1 M 68 232 61 99 203 F 63 214 M 205 455 M 696 F 125 307 M 72 220 48;Run;data blood1;set blood;if missing(Gender) then Missgender + 1;if missing(WBC) then misswbc + 1;if missing(RBC) then missrbc + 1;if chol lt 200 and not missing(chol) then level="low";else if chol ge 200then level="High";run;proc print; run;/* Lag: 返回前一个观测值 */data look_back;input time temperature;prev_temp = lag(Temperature); /* lag 给出变量的前一个观测值 */ two_back = lag2(Temperature); /* lag2 给出变量的前两个观测值 */ datalines;1 602 623 654 70;proc print; run;data diff;input time temperature;diff_temp = temperature - lag(temperature); /* 计算今天和昨天的温度差 */ datalines;1 602 623 654 70;Run;proc print; run;/* 更直接的是 dif 函数 */data diff;input time temperature;diff_temp = dif(temperature);datalines;1 602 623 654 70;Run;proc print; run;/* compress: 删除空格或指定的字符 *//* 设一个电话号码的数据如下 */data phone;input phone $ 1 - 20;datalines;(908)232-4856210.343.4757(516) 343 - 92939342342345;Run;proc print; run;/* 想去掉括号,点号和 - 号 */data phone;length phonenumber $ 10;set phone;PhoneNumber = compress(Phone, " ()-.");Drop phone;Run;proc print; run;compress 的参数的意义如下:✧ d 删除数字✧ a 删除大小写字母✧i 忽略大小写✧k 保留字符串✧s 删除空格,制表符等✧p 删除标点符号data a;string = 'ABC12345 a&%$456 bc,,,,,, ';x1 = compress(string,,'a') ; /* 删除所有字符串 */x2 = compress(string,,'kd'); /* 删除除数字外的其他字符 */x3 = compress(string,,'pd'); /* 删除标点符号和数字 */x4 = compress(String,'abc','i'); /* 删除abc,不论大写或小写 */run;proc print; run;/* translate:替换字符串 */data trans;input Answer : $5.;Answer = translate(Answer,'ABCDE','12345');datalines;14325AB12351492;proc print; run;/* Put 和 input 函数 */data bank;input id 1gender $ 5bdate $ 9-17 educ 25salary $ 29-38salbegin $ 41-50jobtime 53-54 preexp 57-59 minority 61;datalines;1 m 1952/2/3 3 $57,000.00 $27,000.00 98 144 02 m 1958/5/23 1 $40,200.00 $18,750.00 98 36 03 f 1929/7/26 1 $21,450.00 $12,000.00 98 381 0;run;data bank;set bank(rename=(bdate=bdateold salary = salaryold salbegin = salbeginold));bdate = input(bdateold,yymmdd10.);salary = input(salaryold,comma10.);salbegin = input(salbeginold,comma10.);drop bdateold salaryold salbeginold;run;proc print; run;/* 与时间有关的函数 */data datetime;startdate = "01jan2002"d;enddate = "01jan2003"d;dayactual = datdif(startdate,enddate, "act/act");days360 = datdif(startdate,enddate, "30/360");yractual = yrdif(startdate,enddate, "act/act");yr360 = yrdif(startdate,enddate, "30/360");x = date();y = today();year = year(today());season = qtr(today());month = month(today());day = day(today());run;proc print; run;。