Merge, Join in SAS

MERGE:

Introduction

The MERGE statement within DATA STEP is used to merge two or more datasets based on one or more common variables in SAS. It is similar to SQL joins.

Create Sample Datasets

The following SAS code creates two sample SAS datasets that will be used to explain examples in this tutorial.

Data A;

Input ID Name$ Height;

cards;

1 A 1

3 B 2

5 C 2

7 D 2

9 E 2

;

run;

Data B;

Input ID Name$ Weight;

cards;

2 A 2

4 B 3

5 C 4

7 D 5

;

run;

Important Steps when using MERGE Statement in SAS

  1. Step 1 : Both the data sets must be SORTED by the variable you want to use for merging.
  2. Step 2 : The variable you want to use for merging must have same name in both the datasets.
  3. Let’s merge dataset A and B
  4. First, Sort both the datasets with PROC SORT. See the code below –
5. proc sort data = a;
6. by id;
7. run;
8. proc sort data = b;
9. by id;
10. run;

Next Step : Use MERGE statement to merge the datasets by the variable ‘ID’.

11. data dummy;
12. merge a (in=x) b(in=y);
13. by id;
14. a = x;
15. b = y;
16. run;
 

What is IN= option in Data Step Merge?

The IN= option tells SAS to create a flag that has either the value 0 or 1. If the observation does not come from the dataset, then the flag returns 0. If the observation comes from the data set, then the flag returns 1.

Since the IN= option creates temporary variables, we need to create permanent variables so that we can see the flag in the dataset. With this lines of code “a = x; b = y;”, we tell SAS to create two variables named a, b and put the same values as stored in variables x and y. You can assign any name you want, not just a.b. See the Output shown in the image below 

In the above image, the highlighted yellow rows are the rows that are common in both the datasets. Hence, the values are 1 in variables A and B. The value 1 in variable A implies these rows come from dataset A and 0 implies these rows do not come from dataset A. The same logic holds for variable B. When variable B has 1, it means these rows come from dataset B.

What Happens If You Don’t Include ‘BY’ Statement in Merging Data?

The BY Statement tells SAS to match records based on the common variable you specify. Without the ‘BY’ statement, it does not perform matching of records. What would happen? Observations are combined based on their relative position in each data set. For example, observation one from the first data set combines with observation one of the second data set, the second observation from the first data set combines with the second observation from the second data set, and so on.

f there is a common variable in the two datasets, the value is overwritten by the value in the right dataset. Since ID and Name are the common variables, the values are overwritten by dataset B.

The number of observations in the combined dataset is equal to the number of observations in the dataset with largest number of observations. For example, dataset A has 5 observations and dataset B has 4 observations so final data would have 5 observations.

Types of JOINS

In this section, we cover different types of joins using the MERGE statement in SAS.

INNER JOIN

It returns rows common to both tables (data sets). In the final merged file, number of columns would be (Common columns in both the data sets + uncommon columns from data set A + uncommon columns from data setB).

proc sort data = a;
by id;
run;
 
proc sort data = b;
by id;
run;
 
Data dummy;
Merge A (IN = X) B (IN=Y);
by ID;
If X and Y;
run;

Note : When using IN= option, SAS considers “If X and Y” equivalent to “If X=1 and Y=1”

LEFT JOIN

It returns all rows from the left table and the matched rows from the right table.

proc sort data = a;
by id;
run;
 
proc sort data = b;
by id;
run;
 
Data dummy;
Merge A (IN = X) B (IN=Y);
by ID;
If X ;
run;

Note : When you use IN= option, SAS considers “If X” equivalent to “If X=1”. We can use either of the If statement.

Explanation

Since the above case is of LEFT JOIN, Data Step Merge returns all observations from dataset A with matching rows from dataset B.

RIGHT JOIN

It returns all rows from the right table, and the matched rows from the left table.

proc sort data = a;
by id;
run;
 
proc sort data = b;
by id;
run;
 
Data dummy;
Merge A (IN = X) B (IN=Y);
by ID;
If Y ;
Run;

Explanation

Since the above case is of RIGHT JOIN, Data Step Merge returns all observations from dataset B with matching rows from dataset A.

FULL JOIN

It returns all rows from the left table and from the right table.

proc sort data = a;
by id;
run;
 
proc sort data = b;
by id;
run;
 
Data dummy;
Merge A B;
by ID;
run;

Note : Since the FULL JOIN is the default type of JOIN in MERGE Statement, it does not require temporary variables with IN option.

Explanation

Since the above case is of FULL JOIN, Data Step Merge returns all observations from dataset A and B.

What happens when the BY variable in Data Step Merge has different length?

When we merge datasets with BY variable having different lengths, the length of the BY variable used during matching is determined by the left-hand side dataset in the merge. If length of dataset A is shorter than B, it may return zero records.

Solution – Include bigger length of the common variable with LENGTH Statement before MERGE statement.

data dummy;

length ID 8;

merge a b;

by id;

run;

Special Cases

  1. If both the tables (data sets) have similar variable name (other than primary key), Data Step MERGE statement would take values of the common variable exist in the TABLE2 (Right table).
  2. If primary key in both the tables (data sets) have duplicate values, Data Step MERGE statement would return a maximum number of values in both the tables. For example, Table 1 has 3 1’s and Table 2 has 2 1’s, Data Step Merge would return 3 1’s. It is called ‘One-to-Many Merge’.
  3. See the special case shown in the image below –

In this case, dataset A contains two 5s and dataset B contains three 5s. When we merged these two tables, it returns three 5s which is maximum number of 5s in both the dataset A and B.

Important Point – Did you notice the variable “name” exists in both the datasets A and B? In this example, the variable “name” is NOT a primary key to merge the tables. It is the variable “id” which is the primary key to merge these tables. When we merged the tables, DATA STEP MERGE takes values of variable “name” from dataset B.

SAS Code for the above special case

data a;

input id name$ height;

cards;

1 a 1

3 b 2

5 a 2

5 b 3

7 d 2

9 e 2

;

run;

data b;

input id name$ weight;

cards;

2 a 2

4 b 3

5 d 4

5 e 5

5 f 6

7 f 5

;

run;

data c;

merge a (in=x) b(in=y);

by id;

if x;

proc print;

run;

Q. Do the “Special Cases” explained above hold true for all types of joins?

Answer is YES. It holds true for all the types of joins.

How to check if merge was done correctly?

  1. Before merging, ask yourself whether the variable type and length of the BY variable is same.
  2. First check the number of observations in the input files and estimate the number of observations should come in the final merged data set.
  3. Check the number of variables in the input files and estimate the number of variables should appear in the final merged data set.
  4. If there are duplicates in the BY variable of the input files, how data step merge has considered these cases? Whether you are getting the desired output?

Many to Many Merge:

The DATA step Merge does not handle many-to-many matching very well. When we perform many to many merges. the result should be a cartesian (cross) product of matching observations. For example, if there are three records that match from one contributing data set to two records from the other, the resulting data set should have 3 × 2 = 6 records.

Data Step MERGE does not create a cartesian product in case of a many-to-many relationship. It will return number of records for a duplicate value equal to maximum number of the duplicate value in both the table.

data dat1;
input ID Info;
cards ;
1 3123
1 1234
2 7482
2 8912
3 1284
;
run;
data dat2;
input ID Info2;
cards ;
1 4444
1 5555
1 8989
2 9099
2 8888
3 8989
;
run;
 
data combined;
merge dat1 dat2 ;
by ID;
run;

Note : In this example, we have 2 1s in dat1 and 3 1s in dat2. The maximum number of 1s in both the tables is 3. So it would return 3 1s in the merged dataset.