1.句法规则
MERGE SAS-data-set-1 <(data-set-options)>SAS-data-set-2 <(data-set-options) ><...SAS-data-set-n <(data-set-options)> ><END=variable>;
2.详情
2.1概述
MERGE 语句很灵活,在 SAS 编程中有多种用途。 本节介绍 MERGE 的基本用法。 其他应用包括使用多个 BY 变量、合并两个以上的数据集,以及将一些观察结果与另一个数据集中的所有观察结果合并。
2.2将数据集列表与 MERGE 结合使用
您可以在 MERGE 语句中使用数据集列表。 数据集列表提供了一种快速引用现有数据集组的方法。 这些数据集列表必须是名称前缀列表或编号范围列表。
名称前缀列表是指以指定字符串开头的所有数据集。 例如,合并 SALES1:; 告诉 SAS 合并所有以“SALES1”开头的数据集,例如 SALES1、SALES10、SALES11 和 SALES12。
编号范围列表要求您拥有一系列同名的数据集,但最后一个或多个字符是连续数字。 在编号范围列表中,您可以以任何数字开头并以任何数字结尾。 例如,这些列表引用了相同的数据集:
sales1 sales2 sales3 sales4
sales1-sales4
注意:如果第一个数据集名称的数字后缀包含前导零,则最后一个数据集名称的数字后缀的位数必须大于或等于第一个数据集名称的位数。 否则,会发生错误。 例如,数据集列出 sales001–sales99 和 sales01–sales9 会导致错误。 数据集列表 sales001–sales999 有效。 如果第一个数据集名称的数字后缀不包含前导零,则第一个和最后一个数据集名称的数字后缀中的位数不必相等。 例如,数据集列表 sales1–sales999 是有效的。
使用编号数据集列表时要考虑的其他一些规则如下:
您可以指定范围组。
merge cost1-cost4 cost11-cost14 cost21-cost24;
您可以将编号范围列表与名称前缀列表混合使用。
merge cost1-cost4 cost2: cost33-37;
您可以将单个数据集与数据集列表混合使用。
merge cost1 cost10-cost20 cost30;
数据集列表周围的引号将被忽略。
/* 这两行是一样的 */
merge sales1-sales4;
merge 'sales1'n-'sales4'n;
数据集名称中的空格无效。如果使用引号,则忽略尾随空格。
/* 这些语句中的空格会导致错误 /
merge sales 1-sales 4;
merge 'sales 1'n - 'sales 4'n;
/ 此语句中的尾随空格将被忽略 */
merge 'sales1'n - 'sales4'n;
最大数字后缀为 2147483647。
/* 这个后缀会导致错误 */
merge prod2000000000-prod2934850239;
不允许使用物理路径名。
/* 物理路径名会导致错误 */
%let work_path = %sysfunc(pathname(WORK));
merge "&work_path\dept.sas7bdat"-"&work_path\emp.sas7bdat" ;
2.3一对一合并
一对一合并将来自两个或多个 SAS 数据集的观测值组合成新数据集中的单个观测值。要执行一对一合并,请使用不带 BY 语句的 MERGE 语句。 SAS 将 MERGE 语句中命名的所有数据集中的第一个观测值合并到新数据集中的第一个观测值中,将所有数据集中的第二个观测值合并到新数据集中的第二个观测值中,依此类推。在一对一合并中,新数据集中的观察数量等于 MERGE 语句中指定的最大数据集中的观察数量。有关一对一合并的示例,请参见示例 1。有关详细信息,请参阅 SAS 语言参考:概念中的读取、组合和修改 SAS 数据集。
警告
将数据集与一对一合并合并时要小心。一对一合并有时会产生不良结果。在使用此方法之前,在数据集的代表性样本上测试您的程序。
2.4匹配合并
匹配合并根据公共变量的值将来自两个或多个 SAS 数据集的观测值合并为新数据集中的单个观测值。新数据集中的观察数是所有数据集中每个BY组中最大的观察数之和。要执行匹配合并,请在 MERGE 语句之后立即使用 BY 语句。 BY 语句中的变量必须对所有数据集通用。在 DATA 步中,每个 MERGE 语句只能伴随一个 BY 语句。 MERGE 语句中列出的数据集必须按 BY 语句中列出的变量值的顺序排序,或者它们必须具有适当的索引。有关匹配合并的示例,请参见示例 2。有关详细信息,请参阅 SAS 语言参考:概念中的读取、组合和修改 SAS 数据集。
注意:
MERGE 语句不会在多对多匹配合并中生成笛卡尔积。相反,它执行一对一合并,同时在 BY 组中至少有一个数据集中有观测值。当 BY 组中的所有观测值都已从一个数据集中读取,而另一个数据集中还有更多观测值时,SAS 将执行一对多合并,直到读取了所有 BY 组观测值。
3.比较
- MERGE 结合了来自两个或多个 SAS 数据集的观察结果。 UPDATE 结合了来自两个 SAS 数据集的观察结果。 UPDATE 也会更改或更新主数据集中选定观测值的值。 UPDATE 也可能会添加观察结果。
- 与 UPDATE 一样,MODIFY 通过更改或更新主数据集中选定观测值的值来组合来自两个 SAS 数据集的观测值。
- 使用两个或多个 SET 语句读取观察值获得的结果与使用不使用 BY 语句的 MERGE 语句获得的结果相似。但是,对于 SET 语句,如果观察的数量不相等,SAS 会在从所有数据集中读取所有观察之前停止处理。相反,SAS 继续处理在 MERGE 语句中命名的所有数据集中的所有观测值。
4.举例:
/SAS HELP上的官方示例/
/Example 1: One-to-One Merging/
*定义:
一对一合并数据将多个输入数据集中的行合并为新输出数据集中的一行。
行根据它们在输入数据集中的位置进行组合。
第一个输入数据集中的第一行与第二个输入数据集中的第一行合并,依此类推。;
data data1;
input x $ @@;
datalines;
x1 x2 x3
;
run;
data data2;
input y $ @@;
datalines;
y1 y2 y3 y4 y5 y6
;
run;
data combined;
merge data1 data2;
run;
/Example 2: Match-Merging/
/定义: 匹配合并基于 BY 变量的值将来自两个或多个输入数据集的行合并到输出数据集中的单个行中。/
data data1;
input year x $ @@;
datalines;
2011 x1 2012 x2 2013 x3 2014 x4 2015 x5
;
run;
data data2;
input year y $ @@;
datalines;
2011 y1 2012 y2 2013 y3 2014 y4 2015 y5
;
run;
data combined;
merge data1 data2;
by year;
run;
/Example 3: Merging with a Data Set List/
data d008; job=3; emp=19; run;
data d009; job=3; sal=50; run;
data d010; job=4; emp=97; run;
data d011; job=4; sal=15; run;
data comb;
merge d008-d011;
by job;
run;
proc print data=comb;
run;
/Example 4: Three Table Merge with BY Values and the IN= Data Set Option/
DATA CAFE(KEEP=NAME PLACE CNUM);
INPUT NAME $ @@;
PLACE = 'CAFE ';
CNUM = 'C' || LEFT(PUT(N,2.));
DATALINES;
ANDERSON COOPER DIXON FREDERIC FREDERIC PALMER
RANDALL RANDALL SMITH SMITH SMITH
;
RUN;
DATA VENDING (KEEP=NAME PLACE VNUM);
INPUT NAME $ @@;
PLACE = 'VENDING ';
VNUM = 'V' || LEFT(PUT(N,2.));
DATALINES;
CARTER DANIELS GARY GARY HODGE PALMER RANDALL RANDALL
SMITH SMITH SPENCER SPENCER SPENCER SPENCER
;
RUN;
DATA SNACK (KEEP=NAME PLACE SNUM);
INPUT NAME $ @@;
PLACE = 'SNACK ';
SNUM = 'S' || LEFT(PUT(N,2.));
DATALINES;
BARRETT COOPER DANIELS DIXON DIXON FREDERIC GARY HODGE
HODGE PALMER RANDALL RANDALL SMITH SMITH SMITH SMITH
SPENCER SPENCER
;
RUN;
DATA ALL;
MERGE CAFE(IN=CAFEIN) SNACK(IN=SNACKIN) VENDING(IN=VENDIN);
BY NAME;
CIN=CAFEIN; SIN=SNACKIN; VIN=VENDIN;
RUN;
PROC PRINT;
TITLE 'MERGED DATA';
RUN;
/Example 5: Two Table Merge with a BY Variable and the IN= Data Set Option/
data have_a;
input ID amount_a;
datalines;
1 10
3 15
4 20
7 15
9 12
10 14
;
run;
data have_b;
input ID amount_b;
datalines;
2 15
3 20
4 10
5 12
7 20
8 15
9 10
11 20
;
run;
data want;
merge have_a(in=inA) have_b(in=inB);
by id;
length joinType $ 2;
joinType = cats(inA, inB);
run;
proc print data=want;
run;
quit;