🍄

5.2.3. 데이터 병합

1. MERGE

이번 챕터에서는 데이터를 결합하는 방법에 대해 알아보도록 하겠습니다. 우선 데이터의 수평적 1대 1결합부터 알아보도록 하겠습니다. 아래 실행 결과를 미리 보시고 어떻게 결합할지 생각해보세요.
subject_test1_1subject_test1_1
subject_test1_1
mysas.subject_test1_1
data mysas.subject_test1_1; input id name $9. class_ $ subject $ score ; datalines; 101 이호준 1반 computer 92 102 이호중 1반 computer 80 201 이길동 2반 computer 90 202 이준호 2반 computer 86 ; run; proc print data=mysas.subject_test1_1; run;
 
subject_test2subject_test2
subject_test2
mysas.subject_test2
data mysas.subject_test2; input id phonenumber $16.; datalines; 101 010-1234-5678 102 010-9876-5432 201 010-4567-1565 202 010-7536-9512 ; run; proc print data=mysas.subject_test2; run;
 
공통된 기준변수를 가지고 있어야 합니다.
data mysas.join; merge mysas.subject_test1_1 mysas.subject_test2; by id; run; proc print data=mysas.join; run;
 
로그를 보시면 에러가 나타날 것입니다. by 변수가 데이터 셋에 대해서 정렬되지 않았습니다. 병합하기 전에 기준변수를 기준으로 각각의 데이터셋을 정렬을 해줘야합니다. BY 변수를 기준으로 정렬합니다.
 
proc sort data=라이브러리명.데이터셋; by 정렬할 변수; run;
 
proc sort data=mysas.subject_test1_1; by id; run; proc sort data=mysas.subject_test2; by id; run;
 
각각의 데이터셋을 정렬한 후에 다시 결합을 하면 1:1 수평적 결합이 된 것을 확인할 수 있습니다. 또한, 가로로 결합된다는 것을 확인할 수 있습니다.
 
notion imagenotion image
 

2. 조인의 종류

 
w3school → 우리 자료로 만들어야 함w3school → 우리 자료로 만들어야 함
w3school → 우리 자료로 만들어야 함
 

2.1 full join

full join은 집합에서의 합집합입니다. 아래 데이터를 보고 어떻게 합쳐질지 생각해보시고 실습을 해보시고 코드를 실행해 보시면 보다 이해하기 쉽습니다.
mysas.subject_test1_1mysas.subject_test1_1
mysas.subject_test1_1
mysas.phonehwmysas.phonehw
 
phonehw이라는 테이블을 만들도록 하겠습니다.
data mysas.phonehw; input id name $10. type $ number$16.; datalines; 101 이호준 company 004-050-1200 101 이호준 phone 010-1234-5678 102 이호중 home 012-134-7894 201 이길동 phone 010-4567-1565 202 이준호 phone 010-7536-9512 ; run; proc print data=mysas.phonehw; run;
 
이전에 만들었던 mysas.subject_test1_1mysas.phonehw를 병합하도록 하겠습니다. mysas.subject_test1_1이 없으시다면 아래 코드를 실행해줍니다.
 
data mysas.subject_test1_1; input id name $9. class_ $ subject $ score ; datalines; 101 이호준 1반 computer 92 102 이호중 1반 computer 80 201 이길동 2반 computer 90 202 이준호 2반 computer 86 ; run; proc print data=mysas.subject_test1; run;
 
병합하기 전에 꼭 정렬을 해 주시길 바랍니다.
 
proc sort data=mysas.phonehw; by id; run; proc sort data=mysas.subject_test1_1; by id; run;
 
data mysas.fulljoin; merge mysas.subject_test1_1 mysas.phonehw; by id; run; proc print data=mysas.fulljoin; run;
 
notion imagenotion image
 

2.2 inner join

inner join은 집합에서의 교집합입니다.
mysas.subject_test1_1mysas.subject_test1_1
mysas.subject_test1_1
 
mysas.phonehw2mysas.phonehw2
mysas.phonehw2
 
mysas.phonehw2 테이블을 만들어 보도록 하겠습니다.
data mysas.phonehw2; input id name $10. type $ number$16.; datalines; 101 이호준 company 004-050-1200 101 이호준 phone 010-1234-5678 102 이호중 home 012-134-7894 201 이길동 phone 010-4567-1565 202 이준호 phone 010-7536-9512 203 이준길 phone 010-1563-4595 ; run; proc print data=mysas.phonehw2; run;
 
마찬가지로 병합해 주기 전에 정렬을 해야 합니다.
proc sort data=mysas.phonehw2; by id; run; proc sort data=mysas.subject_test1_1; by id; run;
 
data mysas.innerjoin; merge mysas.phonehw2(in=emps) mysas.subject_test1_1(in=cell); by id; if emps=1 and cell=1; run; proc print data=mysas.innerjoin; run;
 
data mysas.innerjoin;data mysas.innerjoin;
data mysas.innerjoin;
 
결과를 보시면 name 변수가 두 테이블에서 중복되는 값들만 출력해 주는 것을 보여줍니다.
 

2.3 right join

오른쪽 테이블 기준으로 합쳐집니다.
data mysas.rightjoin; merge mysas.subject_test1_1(in=emps) mysas.phonehw2(in=cell); by id; if emps=0 and cell=1; run;
 
notion imagenotion image
 
아래 데이터와 비교해보겠습니다.
 
mysas.subject_test1_1mysas.subject_test1_1
mysas.subject_test1_1
mysas.phonehw2mysas.phonehw2
mysas.phonehw2
 

2.4 left join

왼쪽 테이블 기준으로 합쳐집니다.
data mysas.data11; merge mysas.data3(in=emps) mysas.data9(in=cell); by name; if emps=1 or cell=0; run;
 
notion imagenotion image
 

2.5 둘다 0인 경우

둘다 0인 경우는 왼쪽 테이블과 오른쪽 테이블 중 서로 겹치지 않는 부분을 출력해 줍니다. 교집합의 반대인 두 테이블의 차집합을 의미합니다.
data mysas.data11; merge mysas.data3(in=emps) mysas.data9(in=cell); by name; if emps=0 or cell=0; run;
 
notion imagenotion image
 

3. SET

데이터의 수직적 1대 1결합 (데이터 구조가 동일할 때)하는 방법입니다.
data 라이브러리.통합데이터셋; set 라이브러리.데이터셋1 라이브러리.데이터셋2; run;
 
data mysas.set1; set mysas.subject_test1_1 mysas.phonehw2; run; proc print data=mysas.set1; run;
 
notion imagenotion image
위의 결과를 보면 set은 세로로 출력된다는 것을 알 수 있습니다.
 

3.1 칼럼명이 일치하지 않는 경우

1) 만약 해당 칼럼에 데이터가 없다면, 없는대로 빈 칸으로 출력합니다.
2) 두 테이블의 동일 이름 칼럼 간 데이터 길이가 다른 경우에는 SET명령어로 두 개 이상의 테이블을 이어붙일 때 기준이 되는 것은 첫 번째로 지정된 테이블입니다.
앞에서 설명했듯이 SAS는 명령어를 에서부터 읽고 왼쪽에서부터 읽습니다. 이 같은 기준에 따라 SET명령어에서 가장 위에 있는 테이블을 먼저 읽어 들이게 됩니다. 이에 따라 통합된 테이블의 칼럼 NAME은 길이가 10인 상태로 생성이 됩니다. 이 상황에서 두 번째로 나오는 테이블 B의 칼럼 NAME의 길이가 14라면, 테이블 B의 뒤쪽 길이가 2만큼 잘리게 됩니다.
그렇기에 칼럼들의 행을 이어줄 때는 길이를 유심히 살피셔야 합니다.
 

3.2 칼럼의 속성이 다른 경우

변수 Gender 이(가) 모두 문자와 숫자로 정의되었다면 Error가 나게 됩니다. 그렇다면 둘 중 한 변수의 이름을 바꾸거나, 테이블을 생성할 때 변수의 속성을 동일하게 만들거나, 이미 만들어진 테이블의 속성을 변경해야 합니다.