BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Walternate
Obsidian | Level 7

Hi,

 

I have two data files. Each one has an ID variable, var1-var7 (which are the same variables on each file), and then the first file has some additional variables not found on the other file. The ID variable is unique on both files, BUT on File1 can sometimes be missing. Some of the IDs match across files, but there are also IDs that are unique to each. If the ID is missing, var1 - var7 will be missing, but other vars can be populated. If the IDs match across both files, var1-var7 will only be populated on File2. 

 

FILE1

ID   var1    var2    var3....var7    other_vars...

1                                                     xyz

2       d                    e          f           xyz

.                                                      xyz

 

FILE2

ID   var1    var2    var3....var7   

1       a         b          c      d

3       a         b          c      d

 

What I want is to combine the files such that:

1. All records from File1 and File2 are kept (even those with no ID)

2. If a record is in both files, the var1-var7 values come from File2

3. If a record is just in File1 or just in File2, all values should remain intact for all variables. 

 

I considered using UPDATE to update File1 using File2 (as the update process is essentially what I want to do), but the missing ID variables seemed to be problematic when I tried. I also tried using a data step merge and then a PROC SQL join, but in both of those cases, either the File1-only or File2-only values were being overwritten.

1 ACCEPTED SOLUTION

Accepted Solutions
tsap
Pyrite | Level 9
DATA WORK.HAVE_1;
FORMAT 	 ID	1. Var1 $1. 	Var2 $1. 	Var3 $1. 	Var4 $1. 	Var5 $1. 	Var6 $1.	Var7 $1.	OtherVar $3.;
INFORMAT ID	1. Var2 $1. 	Var2 $1. 	Var3 $1. 	Var4 $1. 	Var5 $1. 	Var6 $1.	Var7 $1.	OtherVar $3.;
INPUT    ID		VAR1 		VAR2 		VAR3 		VAR4 		VAR5 		VAR6		VAR7		OtherVar;
INFILE DATALINES DLM='|' DSD;
DATALINES;
1||||||||xyz
2|d||e||||f|xyz
.||||||||xyz
;

DATA WORK.HAVE_2;
FORMAT 	 ID	1. Var1 $1. 	Var2 $1. 	Var3 $1. 	Var4 $1. 	Var5 $1. 	Var6 $1.	Var7 $1.;
INFORMAT ID	1. Var2 $1. 	Var2 $1. 	Var3 $1. 	Var4 $1. 	Var5 $1. 	Var6 $1.	Var7 $1.;
INPUT    ID		VAR1 		VAR2 		VAR3 		VAR4 		VAR5 		VAR6		VAR7;
INFILE DATALINES DLM='|' DSD;
DATALINES;
1|a|b|c| | | |d
3|a|b|c| | | |d
;



PROC SQL;
CREATE TABLE WORK.WANT	AS
	SELECT a.ID, b.VAR1, b.VAR2, b.VAR3, b.VAR4, b.VAR5, b.VAR6, b.VAR7, a.OtherVar

	FROM 		WORK.Have_1 AS a
	INNER JOIN	WORK.Have_2 AS b	ON a.ID=b.ID
UNION
	SELECT a.ID, a.VAR1, a.VAR2, a.VAR3, a.VAR4, a.VAR5, a.VAR6, a.VAR7, a.OtherVar
	FROM 		WORK.Have_1 AS a
	LEFT JOIN	WORK.Have_2 AS b	ON a.ID=b.ID
	WHERE b.ID IS NULL
UNION
	SELECT a.ID, a.VAR1, a.VAR2, a.VAR3, a.VAR4, a.VAR5, a.VAR6, a.VAR7, b.OtherVar

	FROM 		WORK.Have_2 AS a
	LEFT JOIN	WORK.Have_1 AS b	ON a.ID=b.ID
	WHERE b.ID IS NULL;
QUIT;

 

 

resulting output aligns with the request in your post:

ID	Var1	Var2	Var3	Var4	Var5	Var6	Var7	OtherVar
.								xyz
1	a	b	c				d	xyz
2	d		e				f	xyz
3	a	b	c				d	

View solution in original post

5 REPLIES 5
novinosrin
Tourmaline | Level 20

Will this be close to your need?

 

proc sort data=file1(where=(not missing(id)) out=file1_sort;
by id;
run;

proc sort data=file2(where=(not missing(id)) out=file2_sort;
by id;
run;

data temp;
set file1_sort(in=a) file2_sort(in=b);
by id;
if last.id;
run;

/*Now you could filter file1 and file2 keeping only the missing ids and append them to the above temp*/
anhl1206
Fluorite | Level 6

Have you tried adding in an identity variable to your dataset and using that to merge? e.g.:

data one;
set file1;
file1=1;
proc sort data=one;
by ID;
run;

data two;
set file2;
file2=1;
proc sort data=two;
by ID;
run;

data new;
merge one two;
by ID;
if file1 eq 1 or file2 eq 1;
run;

 

tsap
Pyrite | Level 9
DATA WORK.HAVE_1;
FORMAT 	 ID	1. Var1 $1. 	Var2 $1. 	Var3 $1. 	Var4 $1. 	Var5 $1. 	Var6 $1.	Var7 $1.	OtherVar $3.;
INFORMAT ID	1. Var2 $1. 	Var2 $1. 	Var3 $1. 	Var4 $1. 	Var5 $1. 	Var6 $1.	Var7 $1.	OtherVar $3.;
INPUT    ID		VAR1 		VAR2 		VAR3 		VAR4 		VAR5 		VAR6		VAR7		OtherVar;
INFILE DATALINES DLM='|' DSD;
DATALINES;
1||||||||xyz
2|d||e||||f|xyz
.||||||||xyz
;

DATA WORK.HAVE_2;
FORMAT 	 ID	1. Var1 $1. 	Var2 $1. 	Var3 $1. 	Var4 $1. 	Var5 $1. 	Var6 $1.	Var7 $1.;
INFORMAT ID	1. Var2 $1. 	Var2 $1. 	Var3 $1. 	Var4 $1. 	Var5 $1. 	Var6 $1.	Var7 $1.;
INPUT    ID		VAR1 		VAR2 		VAR3 		VAR4 		VAR5 		VAR6		VAR7;
INFILE DATALINES DLM='|' DSD;
DATALINES;
1|a|b|c| | | |d
3|a|b|c| | | |d
;



PROC SQL;
CREATE TABLE WORK.WANT	AS
	SELECT a.ID, b.VAR1, b.VAR2, b.VAR3, b.VAR4, b.VAR5, b.VAR6, b.VAR7, a.OtherVar

	FROM 		WORK.Have_1 AS a
	INNER JOIN	WORK.Have_2 AS b	ON a.ID=b.ID
UNION
	SELECT a.ID, a.VAR1, a.VAR2, a.VAR3, a.VAR4, a.VAR5, a.VAR6, a.VAR7, a.OtherVar
	FROM 		WORK.Have_1 AS a
	LEFT JOIN	WORK.Have_2 AS b	ON a.ID=b.ID
	WHERE b.ID IS NULL
UNION
	SELECT a.ID, a.VAR1, a.VAR2, a.VAR3, a.VAR4, a.VAR5, a.VAR6, a.VAR7, b.OtherVar

	FROM 		WORK.Have_2 AS a
	LEFT JOIN	WORK.Have_1 AS b	ON a.ID=b.ID
	WHERE b.ID IS NULL;
QUIT;

 

 

resulting output aligns with the request in your post:

ID	Var1	Var2	Var3	Var4	Var5	Var6	Var7	OtherVar
.								xyz
1	a	b	c				d	xyz
2	d		e				f	xyz
3	a	b	c				d	
Walternate
Obsidian | Level 7

That's perfect, thank you!

tsap
Pyrite | Level 9
You're welcome. Glad I could help.

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 5 replies
  • 1318 views
  • 1 like
  • 4 in conversation