全部版块 我的主页
论坛 数据科学与人工智能 数据分析与数据科学 SAS专版
3651 1
2019-01-24
举个例子,用by id 来一对多合并。
data a;
input id sex$ subject$ score;
cards;
1 m math 100
1 m chinese 99
2 m math 88
2 m chinese 76
;
run;

data b;
input id sex$ age;
cards;
1 f 13
2 f 12
;
run;

data all;
merge a b;
by id ;
run;
因为性别在两个数据集中都存在,应该是后一个数据集b中的性别覆盖掉a中的性别。又因为a中每个id又两条记录,所以b的结果应该重复两次。
我期望的结果是这样的:
id sex score age
1 f math 100 13
1 f chinese 99 13
2 f math 88 12
2 f chinese 76 12
实际的结果却是这样的
id sex score age
1 f math 100 13(第一条记录的性别被b中的覆盖)
1 m chinese 99 13(第二条记录中的性别没有被b覆盖,保留了a中原有的性别)
2 f math 88 12
2 m chinese 76 12

为什么会出现这种结果呢?分数是b中独有的变量,合并之后重复了两次没有问题。
但是性别作为在A中已经存在的变量,为什么一次被b覆盖,一次没有呢?如果想要两次都被B覆盖怎么办?
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

全部回复
2019-1-25 02:19:32
merge statement的运行,是按照它的by variable进行分组的。以你的程序为例,以id分组,id为1的时候,a中的1 m math 100,1 m chinese 99与b中的1 f 13为一组。merge分组之后,在PDV里面开始读入和写出,其中一个性质为,同一组内往PDV中放的时候,不会进行re-initialization,也就是PDV输出一个obs之后,并不会把PDV中的数据清除。当一组全部输出完毕,进入第二组时,才会清零。

在PDV中的运行机制,就以你的程序为例:
第一步,初始化阶段,PDV构架如下:
id     sex     subject     score     age
第二步,将a中第一组id (id=1的那一组)的第一个obs读入
id     sex     subject     score     age
1      m       math        100       .
第三步,将b中第一组id 的第一个obs读入,有相同variable name的就会覆盖,例如sex就会覆盖,age的missing值会被更新
id     sex     subject     score     age
1      f         math        100       13
自此,新数据集all的第一个obs产生并输出到all里面。由于上面也说过,merge在同一个组内,读出第一个obs到新合并数据集后,PDV不会被re-initialized,所以第三步中的全部数据,将会被保留,然后开始下面的读取。
第四步,将a中第一组id的第二个obs读入,sex会被覆盖为m(这个就是你疑问所在),math会被覆盖为chinese,score会被覆盖为99。
id     sex     subject     score     age
1      m       chinese        99       13
由于b中没有第二个obs,而b的第一个obs并不参与all第二个obs的构建,仅仅是age在PDV里面被retain为13,所以这个就作为all的第二个obs输出。自此,merge的第一组id过程完成。然后进入第二组id的merge,此时PDV会进行re-initialization,里面的值都会被清除,便于开始读取第二组id的内容,过程与上面描述一样。

要想知道merge的过程,还是需要仔细研究一下PDV的运作机制,希望这个回答能够对楼主有所帮助。
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

相关推荐
栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群