通过示例学SAS(6)--循环语句
1.假设有包含学生信息的文件,变量有名字,性别,期中成绩,测验成绩等级及期末成绩。数据内容如下
File c:"books"learning"grades.txt
21 M 80 B- 82
. F 90 A 93
35 M 87 B+ 85
48 F . . 76
59 F 95 A+ 97
15 M 88 . 93
67 F 97 A 91
. M 62 F 67
35 F 77 C- 77
49 M 59 C 81
读入数据时,你想对这些学生分组。年龄小于39的学生将并入年轻组,且最终成绩等级的计算方式为,期中的40%加上期末的60%;年龄大于39的学生将并入年老组,其最终成绩等级的计算方式为两次成绩的平均成绩。使用逻辑判断的形式为
data grades;
length Gender $ 1
Quiz $ 2
AgeGrp $ 13;
infile 'c:"books"learning"grades.txt' missover;
input Age Gender Midterm Quiz FinalExam;
if missing(Age) then delete;
if Age le 39 then Agegrp = 'Younger group';
if Age le 39 then Grade = .4*Midterm + .6*FinalExam;
if Age gt 39 then Agegrp = 'Older group';
if Age gt 39 then Grade = (Midterm + FinalExam)/2;
run;
注意到前两个if和后两个if对同一个条件进行了两次重复判断。使用DO和END可以取消这种重复。上述代码可以修改为
data grades;
length Gender $ 1
Quiz $ 2
AgeGrp $ 13;
infile 'c:"books"learning"grades.txt' missover;
input Age Gender Midterm Quiz FinalExam;
if missing(Age) then delete;
if Age le 39 then do;
Agegrp = 'Younger group';
Grade = .4*Midterm + .6*FinalExam;
end;
else if Age gt 39 then do;
Agegrp = 'Older group';
Grade = (Midterm + FinalExam)/2;
end;
run;
2.Do 循环
看下列代码
data compound;
Interest = .0375;
Total = 100;
Year + 1;
Total + Interest*Total;
output;
Year + 1;
Total + Interest*Total;
output;
Year + 1;
Total + Interest*Total;
output;
format Total dollar10.2;
run;
title "Listing of COMPOUND";
proc print data=compound noobs;
run;
上述代码的目的很简单,无非是从100元开始,以0.0375的利息计算3年下来的钱的总数。output把观测值写入到数据集中。每过一年,利息就要重复计算一次,更好的方式是利用 Do loop循环,如下
data compound;
Interest = .0375;
Total = 100;
do Year = 1 to 3;
Total + Interest*Total;
output;
end;
format Total dollar10.2;
run;
Do循环的格式如下
do index-variable=start to stop by increment
增量的缺省值为1.
这里再看一个例子,作一个函数的图像。
data equation;
do X = -10 to 10 by .01;
Y = 2*x**3 – 5*X**2 + 15*X -8;
output;
end;
run;
symbol value=none interpol=sm width=2;
title "Plot of Y versus X";
proc gplot data=equation;
plot Y * X;
run;
3.其它形式的Do loop循环
index-variable不仅可以是数字型变量,还可以是字符型变量。如do month='Jan','Feb','Mar';使用字符型变量作为index values的例子
data easyway;
do Group = 'Placebo','Active';
do Subj = 1 to 5;
input Score @;
output;
end;
end;
datalines;
250 222 230 210 199
166 183 123 129 234
;
Score后的@符号表示‘稳住‘此行的意思,没有这个@,读取数据时将转向下一行数据。
行保持标志符@
@ :cards语句中的数据一行为一条观测记录,用多条input语句读入。
@@:cards语句中的数据一行为多条观测记录 ,用一条input语句读入。
4.Do while 和 do until循环
当达到某一条件时,停止循环。如
data double;
Interest = .0375;
Total = 100;
do until (Total ge 200);
Year + 1;
Total = Total + Interest*Total;
output;
end;
format Total dollar10.2;
run;
注意,do until后的条件至少会执行一次。
do while形式的循环为
data double;
Interest = .0375;
Total = 100;
do while (Total le 200);
Year + 1;
Total = Total + Interest*Total;
output;
end;
format Total dollar10.2;
run;
结合Do until和Do loop的例子
data double;
Interest = .0375;
Total = 100;
do Year = 1 to 100 until (Total gt 200);
Total = Total + Interest*Total;
output;
end;
format Total dollar10.2;
run;
5.Leave和continue
Leave表示从循环中退出,而continue表示跳过此轮循环,继续下一轮循环。例如
data leave_it;
Interest = .0375;
Total = 100;
do Year = 1 to 100;
Total = Total + Interest*Total;
output;
if Total ge 200 then leave;
end;
format Total dollar10.2;
run;
当总数大于或等于200时,则退出循环。
data continue_on;
Interest = .0375;
Total = 100;
do Year = 1 to 100 until (Total ge 200);
Total = Total + Interest*Total;
if Total le 150 then continue;
output;
end;
format Total dollar10.2;
run;
只要Total小于或等于150,执行语句会跳到loop底部,而忽略output。