关于pinseng“请教一个SAS _n_的问题”中set语句的运用规则总结
发布:meishanjia1900 | 分类:SAS软件培训
关于本站
人大经济论坛-经管之家:分享大学、考研、论文、会计、留学、数据、经济学、金融学、管理学、统计学、博弈论、统计年鉴、行业分析包括等相关资源。
经管之家是国内活跃的在线教育咨询平台!
获取电子版《CDA一级教材》
完整电子版已上线CDA网校,累计已有10万+在读~ 教材严格按考试大纲编写,适合CDA考生备考,也适合业务及数据分析岗位的从业者提升自我。
TOP热门关键词
pinseng发了名为《请教一个SAS_n_的问题》的帖子。他想问以下程序中if_n_=1的意义是什么:datatemp;inputxy@;datalines;123456.9677.1863;run;dataq3;if_n_=1thendountil(last);settempnobs=obsend=last;sum_x+x;sum ...
免费学术公开课,扫码加入![]() |
他想问以下程序中if _n_=1的意义是什么:
data temp;
input x y@;
datalines;
1 2
3 4
5 6
. 9
6 7
7 .
1 8
6 3
;
run;
data q3;
if _n_=1 then do until (last);
set temp nobs=obs end=last;
sum_x+x;
sum_y+y;
end;
set temp;
if x=. then x=sum_x/obs;
if y=. then y=sum_y/obs;
run;
源自:https://bbs.pinggu.org/thread-1246757-1-1.html
---------------------------------------------------------------------------------------
问题本身已经解决了,这里只是想总结一下我在参与回复的过程中所探索出的一些东西——“set语句的法则”,它是我尝试过很多小程序后的一个结论。
仔细想想还是有些复杂的:
***************************************************
set语句的法则——当DATA b;数据步中出现多个set a;语句时,遵循如下法则:
(1)计算机对程序中每一处的set a;语句分别设置各自对a集的读取进程,每个set a;语句第一次执行时均从a集的第一条记录开始读入,之后,分别按各自被执行的次数一条一条读取a的记录,注意,DATA步的大循环不会打断这种读取进程的推进,每个特定位置的set语句,仍可在新循环里沿着自己上一次DATA步循环时的a集读取进程继续往下读。
(2)同一DATA b;循环中,每次只针对该循环对应的特定b记录,多次写入set a;语句读出的a记录数据。且对于b的该特定记录行从a处读入的变量,写入的新数据会覆盖旧数据。
(3)DATA步的上一次循环中执行的最后一处set a;为b集读入的a集变量值也将在该次循环开始时被再次写入到这个b集的新的记录行里,形成与上一行b记录重复的格局。即,set a;创建的变量在b集中被当作保留变量。但是要注意,新记录也一如既往的没有禁止覆盖!如果新循环中执行了set,则默认值将被覆盖。若新的DATA循环中没有set语句被执行,且保留变量没被其他语句修改,那么b的新记录行保留默认值。
(4)只要DATA新循环中没有任何set语句被执行,那在完成该DATA循环后,程序自动终止。
(5)无论程序中哪一处的set a;语句在先行读到a的最后一条记录的进度基础上不知“适可而止”,仍被DATA b;程序再次执行,导致“超出极限读取”的,该data b;循环将不产生(理解为抹消也可以)对应的整条b集记录,且data b;数据步终止。
***************************************************
解释:
-------------------------------------------------------------
例1:
- data a;
- input v1;
- cards;
- 1
- 2
- 3
- 4
- 5
- ;
- data b;
- do until (last);
- set a end=last;
- v2+2;
- end;
- set a;
- run;
- proc print data=b;
- run;
Obs v1 v2
1 1 10
data b;程序段中出现了两处set a;语句。计算机将分别设置它们各自的读取计划。具体情况如以下流程:
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
( i)b的循环次数(即对应的b记录行数)-------》第1次(针对b的第1条记录):
(a)先看do循环,do之内的set被执行了5次,v2+2也执行了5次:
do第1次循环:v1=1 do第1次循环:v2=2 ------------》第1行记录:v1=1,v2=2
do第2次循环:v1=2 do第2次循环:v2=4 ------------》第1行记录被覆盖为:v1=2,v2=4
do第3次循环:v1=3 do第3次循环:v2=6 ------------》第1行记录被覆盖为:v1=3,v2=6
do第4次循环:v1=4 do第4次循环:v2=8 ------------》第1行记录被覆盖为:v1=4,v2=8
do第5次循环:v1=5 do第5次循环:v2=10 -------- ---》第1行记录被覆盖为:v1=5,v2=10
(b)do循环之后,执行下一句——set a; 该处的set还是第一次执行:
初次执行该语句:v1=1 ------------------------------------------》第1行记录被覆盖为:v1=1,v2=10(v2未遭到覆盖!)
(i i )b的循环次数(即对应的b记录行数)-------》第2次(针对b的第2条记录):
开头时,在b集第2条记录里,默认认为v1=1。这体现了法则(3)的内容。
之后,程序碰到do循环,虽然last值仍保留成数字1,表示do中的set语句已经触及a的底部,但是do语句每次开始第1次循环时,都不对判断条件加以把关。故虽然until (last)被满足,但do还是被执行了。
do中的set a;明明已经读取到了a的底部,但仍然被执行了,造成“超限读取”,依据法则(5),程序到此终止,且抹消掉b的第2条记录。
故DATA b;循环了2次,但b集只产生了1条记录。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
对输出结果的解释到此完毕。
-------------------------------------------------------------
例2:
- data a;
- input v1;
- cards;
- 1
- 2
- 3
- 4
- 5
- ;
- data b;
- do until (v2>=6);
- v2+1;
- set a;
- put _all_;
- end;
- run;
- proc print data=b;
- run;
空,无输出内容!表明b集无数据!
LOG:
v2=1 v1=1 _ERROR_=0 _N_=1
v2=2 v1=2 _ERROR_=0 _N_=1
v2=3 v1=3 _ERROR_=0 _N_=1
v2=4 v1=4 _ERROR_=0 _N_=1
v2=5 v1=5 _ERROR_=0 _N_=1
LOG中的输出表明b集的第1次循环确实执行过,但为什么没有形成第1条记录呢?——“超限读取”!法则(5)表明b集不可能有记录。就算前面演算得再精彩,黑板擦一擦,什么都没了。
-------------------------------------------------------------
一个更难的例子:
例3:
- data a;
- input v1;
- cards;
- 1
- 2
- 3
- 4
- 5
- ;
- data b(drop=i j);
- do until (v2>2);
- set a; i=1; put i;
- v2+2;
- end;
- set a; j=2; put j;
- run;
- proc print data=b;
- run;
Obs v2 v1
1 4 1
2 6 2
3 8 3
4 10 4
LOG:
1
1
2
1
2
1
2
1
2
这个例子我不详细说了,但这里我提一些问题,以启发各位的思考:
(A)为什么LOG栏的输出结果中,在第1个数字2出现之后,还会间隔着出现数字1呢?提示:do until (...)开始第一次循环时是不对条件(...)把关的!
(B)为什么记录1中v1=1,而v2却是4?请结合法则中的(2)思考。
(C)为什么记录只有4行,而不是5行?请结合法则中的(2)与(5)思考。
(D)data b;总共循环了几次?请结合法则(5)思考。
这更像是一个练习,且难度较大。
-------------------------------------------------------------
更多的例子:
例4:
- data a;
- input v1;
- cards;
- 50
- 60
- ;
- data b;
- if _n_<=2 then do;
- set a;
- v2=6;
- end;
- run;
- proc print data=b;
- run;
Obs v1 v2
1 50 6
2 60 6
3 60 .
- data a;
- input v1;
- cards;
- 50
- 60
- ;
- data b;
- if _n_<=3 then do;
- set a;
- v2=6;
- end;
- run;
- proc print data=b;
- run;
Obs v1 v2
1 50 6
2 60 6
为什么第一段程序的结果与第二段程序的结果不同呢?
两段程序的DATA b;都循环了3次,第一段程序在第3次循环中没有执行任何set语句,故第3行的b记录中v1的值默认与上一行相同。这主要体现了法则(3)、(4)的内容。
第二段程序在第3次循环中又执行了一次set a;语句,a只有2行记录,但该处的set前后共运行了3次,是“超限读取”,因此不形成第3条记录,且程序终止。
-------------------------------------------------------------
例1、例2、例3、例4都弄懂之后,对set语句法则的理解应该就没有问题了。
对set语句法则的解释,到此结束。
「经管之家」APP:经管人学习、答疑、交友,就上经管之家!
免流量费下载资料----在经管之家app可以下载论坛上的所有资源,并且不额外收取下载高峰期的论坛币。
涵盖所有经管领域的优秀内容----覆盖经济、管理、金融投资、计量统计、数据分析、国贸、财会等专业的学习宝库,各类资料应有尽有。
来自五湖四海的经管达人----已经有上千万的经管人来到这里,你可以找到任何学科方向、有共同话题的朋友。
经管之家(原人大经济论坛),跨越高校的围墙,带你走进经管知识的新世界。
扫描下方二维码下载并注册APP
免流量费下载资料----在经管之家app可以下载论坛上的所有资源,并且不额外收取下载高峰期的论坛币。
涵盖所有经管领域的优秀内容----覆盖经济、管理、金融投资、计量统计、数据分析、国贸、财会等专业的学习宝库,各类资料应有尽有。
来自五湖四海的经管达人----已经有上千万的经管人来到这里,你可以找到任何学科方向、有共同话题的朋友。
经管之家(原人大经济论坛),跨越高校的围墙,带你走进经管知识的新世界。
扫描下方二维码下载并注册APP
您可能感兴趣的文章
人气文章
本文标题:关于pinseng“请教一个SAS _n_的问题”中set语句的运用规则总结
本文链接网址:https://bbs.pinggu.org/jg/ruanjianpeixun_sasruanjianpeixun_1254880_1.html
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。



