楼主: pinseng
11124 25

[原创博文] 请教一个SAS _n_的问题 [推广有奖]

11
pinseng 发表于 2011-11-14 16:43:03
不用if _n_=1,直接do也可以得到x和y的和啊

但是跟temp合并的时候输出就不一样了

今天看了很多资料,还是不明不白

看hopewell老大的帖子,他的风格很喜欢用_n_,不知道能不能找到他来说说怎么回事

12
haizhilan 发表于 2011-11-14 16:58:40
回复pinseng:不用if _n_=1是可以为x和y两列分别计算出总和的,但是这样每执行一个数据步循环,do语句就得执行一遍,对程序运行效率有比较大的影响,当观测数比较多的时候表现就非常明显了。
你说跟temp合并,结果不一样,没太明白,是不是我有疏忽的地方

13
soporaeternus 发表于 2011-11-14 17:03:46
_N_=1的时候遍历一次全表做一次汇总求和,接下来再读入一次把和粘上去。。。。。。
Let them be hard, but never unjust

14
pinseng 发表于 2011-11-14 17:27:31
就是下面这几个的区别

data temp;
input x y@;
datalines;
1 2
3 4
5 6
. 9
6 7
7 .
1 8
6 3
;
run;

data q3;
    do _n_=1 by 1 until (last);
        set temp nobs=obs end=last;
    end;
run;

data q31;
    do _n_=1 by 1 until (last);
        set temp nobs=obs end=last;
    end;
        set temp;
run;


data q32;
    if _n_=1 then do until (last);
        set temp nobs=obs end=last;
    end;
run;

data q33;
    if _n_=1 then do until (last);
        set temp nobs=obs end=last;
    end;
        set temp;
run;

data q333;
        set q32;
        set temp;
run;

15
pinseng 发表于 2011-11-14 17:31:31
上面的q33 跟 q333 区别是什么?导致最后结果不一样

16
haizhilan 发表于 2011-11-14 19:49:14
pinseng 发表于 2011-11-14 17:31
上面的q33 跟 q333 区别是什么?导致最后结果不一样
问题在于这一步:
data q32;
    if _n_=1 then do until (last);
        set temp nobs=obs end=last;
    end;
run;
以下是数据处理过程:
数据步内部的do end循环没有output语句,执行完后应该有x=6, y=3;
此时,从循环跳出,到数据部末尾,该条记录被写入数据集q32;
程序回到数据步开头,这时候 _n_=2,所以if语句不执行,直接走到数据部末尾,该条记录再次被写入数据集q32;
也就是说,数据集q32只有两条一模一样的记录x=6,y=3

17
haizhilan 发表于 2011-11-14 20:00:13
pinseng 发表于 2011-11-14 17:31
上面的q33 跟 q333 区别是什么?导致最后结果不一样
接着上面来说,数据步
data q33;
    if _n_=1 then do until (last);
        set temp nobs=obs end=last;
    end;
        set temp;
run;
执行完后,会生成一个跟temp一模一样的数据集,因为后面那个set temp语句,会按照正常的程序读取temp中的内容,并写入q33.
那么,显然,以下语句
set q32;
set temp;
生成的数据集q333是temp数据集的前两条记录(当然,如果把两个set语句的顺序换一下,为set temp;set q32,那么就会生成跟q32一样的数据集)。
不知道我是否已经解释明白。欢迎大家指教。

18
haizhilan 发表于 2011-11-14 20:03:43
另外,在这里讨论的情况下
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;
如果去掉if then,而直接用 do语句的话,生成的数据集q3将只有1条记录。显然不是我们想要得到的

19
pinseng 发表于 2011-11-15 15:07:31
haizhilan 发表于 2011-11-14 19:49
问题在于这一步:
data q32;
    if _n_=1 then do until (last);
请问这段话是什么意思“程序回到数据步开头,这时候 _n_=2,所以if语句不执行,直接走到数据部末尾,该条记录再次被写入数据集q32;也就是说,数据集q32只有两条一模一样的记录x=6,y=3”。

if语句不执行,直接走到数据部末尾  是指的哪个数据部?if语句不执行,是不是if到end这一段等于没有,为什么还能读进去一条数据呢?

麻烦再给我讲解一下。听了你说的,明白多了,但还有一点糊涂,多谢多谢!

20
pinseng 发表于 2011-11-15 15:11:08
haizhilan 发表于 2011-11-14 20:00
接着上面来说,数据步
data q33;
    if _n_=1 then do until (last);
麻烦再问一下,这个地方,if到end产生了一个观测值(对x和y),然后后面跟着set temp;

平时知道的如果这样
set a;
set b;
最后obs的数目应该跟data最少的那个一样多,为什么这儿跟temp一样多?

也就是想问一下,跟你另一个帖子说的 把 if 到 then去掉的差别到底是为什么?

多谢多谢!

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2026-1-2 07:45