全部版块 我的主页
论坛 数据科学与人工智能 数据分析与数据科学 SAS专版
13281 0
2016-06-10
转载
[url=]转载[/url]


https://bbs.pinggu.org/thread-2168568-1-1.htmlhttp://crackman.net/?p=1194
http://www.cnblogs.com/zgw21cn/archive/2008/08/22/1274210.html
http://blog.sina.com.cn/s/blog_9d0b00a40101d4lw.html
http://blog.sina.com.cn/s/blog_8fc24da10101g587.html
多对多merge 解决方案参见他的博客:
http://blog.sina.com.cn/s/blog_6d078e2b0101f02f.html

有两个数据集,第一个为info,包括stkcd,date,price,数据举例如下:stkcd date price
000001 1998-08-20 5
000001 1998-08-21 5.5
600001 1998-08-20 6.5
600002 1998-08-20 7.5
600004 1998-08-21 8
......
第二个为市场数据market,包括date,market_index;
date market_index
1998-08-20 0.56
1998-08-21 0.57
.......
现在需要在第一个数据的每支股票后面加上市场指数,很明显,要用date来合并,但是info中的date并不是唯一的,我这样写:
proc sort data=info;by date;run;
proc sort data=market;by date;run;
proc sql;
create table buyer_price as
select a.*,b.market_index
from info a left join market b on a.date=b.date;
quit;

请问我这样写对吗?还有更好的方法吗?另外,我的这种方法是否适用于多对多合并?
谢谢解惑。
create table buyer_price as
select a.*,b.market_index,c.annoucement_date
from info a left join market b on a.date=b.date
inner join 最后一个数据集名字 c
on a.stkcd =c.stkcd ;
quit;






两个数据集按照某一个变量匹配进行合并时,存在多对多或者一对多的匹配结果,看看下面两个程序:
1.采取的是用DO循环语句,逐个遍历第二个数据集中每一个观测对象,根据指定的条件,输出符合条件的合并后的观测
data AllSubjects(keep=Age Subject);
input Age @;


do i=1 to 3;
input Subject $ @;
output;
end;
datalines;
13 Math History English
14 Math Science English
run;
data schedules_dstep(drop=Age2);
set sashelp.class(where=(Age in (13,14)));
do i=1 to NSubjects;
set AllSubjects(rename=(Age=Age2)) nobs=NSubjects point=i;
if Age=Age2 then output;
end;
run;
proc sort data=schedules_dstep;
by Subject Age Name;
run;
proc print data=schedules_dstep;
by Subject;
id Subject;
title1 “Many-to-many results”;
run;

2.看看SQL语句对这种匹配问题的处理
data AllSubjects(keep=Age Subject);
input Age @;
do i=1 to 3;
input Subject $ @;
output;
end;
datalines;
13 Math History English
14 Math Science English
run;
proc sql;
create table schedules_sql as
select Class.*, Subject
from sashelp.class(where=(Age in (13,14))),
AllSubjects
where Class.Age=AllSubjects.Age
order by Subject, Age, Name;
quit;
proc print data=schedules_sql;
by Subject;
id Subject;
title1 “Many-to-many results”;
run;

两个方法进行一个比较:
1.SQL方法显得代码很简洁,看上去容易理解,没哟SET里面的RENAME等语句。
2.但是SQL由于Cartesian product得生成耗费额外较多的资源,显得效率较低,但是对于数据量比较少的时候,采用SQL是一个不错的选择。


通过示例学SAS(7)--分割和合并数据集

1.从一个数据集中分拆两个子集

Code

如果output没有指明数据子集的名字,SAS将把结果输出到data所指明的每个数据集中。

2.增加观测值到数据集

设有两个数据集,分别为one和two,其内容分别为

Listing of ONE                                    
Obs ID Name Weight
1     7 Adams 210
2     1 Smith 190
3     2 Schneider 110
4     4 Gregory 90

Listing of TWO
Obs ID Name Weight
1    9    Shea 120
2    3    O'Brien 180
3    5    Bessler 207

每个数据集有相同的变量名,变量的长度也相同。一种合并的形式为

data one_two;
    set one two;
run;

得到输出结果为

Listing of one_two
Obs ID Name Weight
1     7  Adams  210
2     1  Smith   190
3     2  Schneider 110
4     4  Gregory  90
5     9  Shea    120
6     3  O'Brien 180
7     5  Bessler 207

数据集two的数据接在one的后面,SAS谓之为串联数据集。如果两个数据集的变量不相同,会发生什么情况呢?假设有第三个数据集,如

Listing of THREE
Obs ID Gender Name
1    10   M     Horvath
2    15   F     Stevens
3     20  M    Brown

数据集Three包含了一个新变量Gender,不存在变量Weight。执行下述代码

data one_three;
    set one three;
run;

输出结果如下

Obs ID Name Weight Gender
1     7 Adams  210
2     1 Smith 190
3     2 Schneider 110
4     4 Gregory 90
5     10 Horvath    .     M
6    15 Stevens     .     F
7    20 Brown       .     M

注意,输出数据集的变量的长度将和第一个数据集的变量的长度相同。最好在合并检查字符型变量的长度。最后,如果一个变量在一个数据集为数值型 ,在另一个数据集为字符型,输出结果会报错。

3.合并两个数据集

例如,有一个雇员集(Employee),含有变量雇员ID和雇员名字。另外一个数据集(Hour)有雇员ID,工作类别和工作时间。现在想增加名字到Hour数据集中。

proc sort data=employee;
   by ID;
run;
proc sort data=hours;
   by ID;
run;
data combine;
merge employee hours;
   by ID;
run;

假如想使得合并后的数据集,仅含有Hour中的雇员。怎么办呢?参看下述代码

data new;
    merge employee(in=InEmploy)
             hours (in=InHours);
     by ID;
     file print;
    put ID= InEmploy= InHours= Name= JobClass= Hours=;
run;

in后面是临时变量名,并不输出到结果中。当数据集中有观测值输出到结果集时,此值设为1,不然设为0.下列代码合并既在employee又在hours中的观测值。

data combine;
   merge employee(in=InEmploy)
            hours(in=InHours);
    by ID;
    if InEmploy and InHours;
run;

如果合并的变量名不相同,那就改名好了。

data sesame;
   merge bert
            ernie(rename=(EmpNo = ID));
    by ID;
run;

在前面的讨论中,每一个by variable的值所对应的观测值只有一个,称之为“ 一对一合并”。如果一个by variable所对应的观测值不只一个,称之为“一对多合并”。例如,有下述两个数据集

Listing of Data Set BERT

ID      X
123    90
222    95
333    100

Listing of Data Set OSCAR
ID      Y
123   200
123   250
222   205
333   317
333   400
333   500

注意到同一个ID号有多条观测值。合并后结果为

Listing of COMBINE
Obs    ID     X     Y
1       123   90   200
2       123   90   250
3       222   95   205
4       333  100   317
5       333  100  400
6       333  100  500

基于ID号的X值被添加到每一条记录中去。如果是“多对多合并”的话,就是一场灾难了。对于每一个by variable的值,两个数据集均有两个以上的观测值。合并后会有什么结果呢?考察以后两个数据集。

Listing of ONE
Obs   ID   X
1     123   90
2     123   80
3     222   95
4     333  100
5     333  150
6     333  200

Listing of TWO
Obs    ID   Y
1     123    3
2     123    4
3     123    5
4     222    6
5     333    7
6     333    8

合并后结果如下

Listing of MANY_TO_MANY
Obs  ID   X   Y
1     123 90   3
2     123 80   4
3     123 80   5
4     222 95   6
5     333 100 7
6     333 150 8
7     333 200 8

SAS会以X中的最后一个值(80)来对应Y的剩下的值。看来,多对多的合并会得到这样奇怪的结果。






二维码

扫码加我 拉你入群

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

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

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

说点什么

分享

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