SAS中文论坛

标题: 请教一个简单的问题,这种循环如何实现。 [打印本页]

作者: shiyiming    时间: 2004-4-13 11:27
标题: 请教一个简单的问题,这种循环如何实现。
有一个表,假设内容为
id,  age,month,region
121, 18 , 1, A
122, 17 , 1, B
125, 15 , 2, A
150, 30 , 5 , B
.....

想统计这样几个值:对所有ID中有‘21’的记录
1、各region每月的记录数(也就相当于region A ,month(1)=1);
2、以5为一个段,各年龄段每month的记录数(比如说15-19年龄段,month(1)=3);
3、各年龄段、各region每month的记录数(如:15-19,A ,month(1)=1)。结果送入一新表中。

从理论上讲,这个程序不难,但我是新接触SAS,对语法不熟悉。不知道如何实现循环。请哪位大侠指点一下,最好明确一下语法的使用。过了这关,我一定努力学习SAS,回报社会。

我的想法:先求出(3)的结果,利用它再求1和2
我的伪代码:求(3)结果:
for i= 1 to 12
for k=0 to 15 /*age group*/
  select count(1) as number ,i as month , k as age_group, 'A' as region
    where month=i , int(age/5)=k, region='a',index(id,'21') ne 0;
end for // for k
end for // for i
.....same code to other regions like B C D...

也想用proc freq实现,但不知道这么多条件怎么实现。
作者: shiyiming    时间: 2004-4-13 12:50
随便demo一个,要求id中char型的,否则要改一改。

proc format;
value age  1-5='1-5'     6-10='6-10'
          11-15='11-15' 16-20='16-20'
          21-25='21-25' 26-30='26-30';
;
data tem;
input id $ age month region $;
age1=put(age,age.);
cards;
121 18 1 A
121 17 1 B
121 16 2 A
121 17 2 A
150 30 5 B
;run;

proc sql;
create table result1 as
  select age1 as age,region,month,count(1) as number from tem
  where index(id,'21')>0 group by age1,region,month;
quit;
proc print;run;
作者: shiyiming    时间: 2004-4-13 13:05
标题: proc freq 过程实现。
/**********************************************************/
proc format;
   value age
   1 - 5='1'
   6 -10='2'
   10-15='3'
   16-20='4'
   21-25='5'
   26-30='6'
   31-35='7'
;

data tem;
input id $  age month region $;
age_1=put(age,age.);
cards;
121  18   1   A
122  17   1   B
125  15   2   A
150  30   5   B
121  14   5   A
121  9    4   B
121  19   1   B
121  17   1   A
;
run;

/********************************************************/
proc freq data=tem noprint;
table age_1*region*month/norow nocol nopercent out=tem1;
where index(id,'21') ne 0;
run;
作者: shiyiming    时间: 2004-4-13 19:11
假设数据源是这样的:

data source;
input id age month region $;
cards;
121 18 1 A
121 17 1 B
121 16 2 A
121 17 2 A
150 30 5 B
;
run;

造个format从1到100,每5个一段:
data format;
length start end label $10;
fmtname = "age_grp";
type = "N";
do i = 1 to 100 by 5;
        start = trim(left(i));
        end = trim(left(i + 4));
        label = trim(start)||"-"||trim(end);
        output;
end;
start = "other";
end = start;
label = start;
output;
drop i;
run;

proc format cntlin=format;
run;

用Proc Summary把 region*month*age month*age region 三个层次的汇总一次生成:
proc summary data=source(where=(index(trim(left(id)),'21')>0)) chartype;
class region month age;
types region*month*age month*age region;
output out=summary;
format age age_grp.;
run;

打印结果:
proc print data=summary(keep=region age month _freq_ _type_ where=(_type_="111"));
run;

proc print data=summary(keep=age month _freq_ _type_ where=(_type_="011"));
run;

proc print data=summary(keep=region _freq_ _type_ where=(_type_="100"));
run;

或者用“小猪”网友的算法:
proc freq data=source(where=(index(trim(left(id)),'21')>0))  noprint;
table age*region*month/norow nocol nopercent out=tem1;
table age*month/norow nocol nopercent out=tem2;
table region*month/norow nocol nopercent out=tem3;
format age age_grp.;
run;

提示:
用trim(left(id))不管id是否字符型都可以使用index(trim(left(id)),'21')>0

用format age age_grp.在过程步里动态转换format,不需要专门生成这个列

一般来说,Proc summary在功能上和效率上比Proc Sql汇总及Proc Freq要好一些。
作者: shiyiming    时间: 2004-4-13 21:06
收到!请继续指教!




欢迎光临 SAS中文论坛 (http://mysas.net/forum/) Powered by Discuz! X3.2