R에서 데이터 프레임이 흩어져있을 때 그것들을 합치는, 즉 병합 방법에 대해 알아본다.
데이터프레임을 병합하는 건 생각보다 단순하지가 않다. 병합할 때 기준이 되는 값을 무엇으로 삼을 것인지, 어디서 어디로 가져올지, 공통적인 값만 가져올지 혹은 다 가져올지(없는 건 그냥 공백으로 남기더라도) 등을 결정해야 하기 때문이다.
본 포스팅에서는 테이블 병합에 주로 활용되는 아래의 함수/메서드들을 소개한다.
inner_join()
full_join()
left_join()
,right_join()
bind_rows()
물론 SQL 같은 걸 다뤄보았다면 제목만 봐도 어느정도 다 아는 내용일 거다.
Inner Join
inner join은 공통이 되는 값(교집합)만 가져오는 거다. 공통으로 가져올 기준이 없다면 버려진다.
그림으로 설명하면 이런 느낌?

dplyr에 있는 inner_join()
을 쓰면 된다. 이렇게.
df_1 %>%
inner_join(df_2)
예를 들어 df_1에는 컬럼 A와 B가 있고, df_2에는 컬럼 A와 C가 있었다면, 병합된 테이블은 컬럼 A, B, C로 구성될 거다.
dplyr에 있는 inner_join()
을 쓰면 된다. 이렇게.
inner_join(df_1, df_2)
이렇게 써도 되고.
df_1 %>%
inner_join(df_2)
예를 들어 df_1에는 컬럼 A와 B가 있고, df_2에는 컬럼 A와 C가 있었다면, 병합된 테이블은 컬럼 A, B, C로 구성될 거다.
파이프 %>%
로 연결하면 3개 이상의 테이블을 손쉽게 연결할 수 있다. 이렇게.
joined_df <- df_1 %>%
inner_join(df_2) %>%
inner_join(df_3)
각 테이블에 병합의 기준으로 삼을 열이 있는 경우, 즉 일치하는 컬럼명이 존재하는 경우에는 위에 제시된 방법으로 해도 아무런 문제가 없다.
그러나 기준이 되는 열 이름이 다를 수가 있다.
※ 병합의 기준이 되는 열을 지정해야 할 때
아래와 같은 두 개의 테이블이 있다고 해보자.

주문 테이블 Orders에 적힌 고객 아이디(customer_id
)가 고객 테이블 Customers에 적힌 아이디(id)
와 같은 것이니 이걸 기준으로 삼아야 한다. (Orders 테이블의 id는 주문 정보다. 다른 거다.)
방법 1. 컬럼 이름을 변경해서 맞춰준다.
dplyr의 컬럼 명을 바꿔주는 함수 rename()
을 사용해서 공통의 컬럼으로 만들어준 후에 병합을 시키면 된다.
customers <- customers %>%
rename(customer_id = id)
inner_join(orders, customers)
방법 2. by
를 사용해서 기준 컬럼을 직접 지정한다.
inner_join()
함수를 호출할 때 by
인자를 사용해서 병합의 기준이 되는 컬럼을 지정해도 된다.
이렇게.
orders %>%
inner_join(customers,
by = c('customer_id' = 'id'))
그런데 이렇게 되면 id라는 같은 이름을 가진 열이 2개 존재하는 꼴이기 때문에 병합된 테이블에는 id_x, id_y 이런 식으로 표시가 된다.

그래서 공통된 이름이 생길 경우를 대비해 suffix
를 지정해서 아래와 같이 해결할 수 있다.
orders %>%
inner_join(customers,
by = c('customer_id' = 'id'),
suffix = c('_order','_customer'))

id_orders, id_customers 로 생성된 걸 알 수 있다.
Full Join
위에서 설명한 inner join 방식은 공통이 되는 값을 찾아 병합하기 때문에 값들이 누락될 수 있다.
예를 들어 orders 테이블에 customer_id가 5라는 값을 가진 행이 있었는데, customer 테이블에서 id가 5인 고객이 없다면 애초에 orders에 있던 그 행은 병합 과정에서 사라지는 거다.
그래서 누락되는 값 없이 모두(합집합) 가져오는 방식이 바로 full join이다. 모든 행이 다 보존된다.
그림으로 설명하면 이런 느낌?

방법은 inner_join()과 마찬가지다. full_join()
을 쓰면 된다.
df_1 %>%
full_join(df_2)
공통으로 찾을 수 없는 항목은 NA
가 들어간다.
Left Join & Right Join
병합할 때 특정 테이블을 기준으로 삼을 수도 있다. 특정 테이블에 있는 건 일단 모두 살려두고, 이것과 겹치는 게 있는 경우에만 가져와서 병합하는 방식이다.
left_join()
혹은 right_join()
을 사용하면 된다.


사용법은 간단하다.
left_1_2 <- df_1 %>%
left_join(df_2)
좌우 바뀌는 건 어렵지 않으니 right_join()
은 현실적으로 크게 의미 없다. 그냥 left_join()
만 알아도 된다.
Bind Rows
이건 위에서 살펴본 테이블 병합과는 조금 개념이 다르다.
그냥 말 그대로 데이터 세트가 여러개로 쪼개져 있을 때 같은 구조로 행만 덧붙이기 위해 사용하는 방법이다. 당연히 모든 열이 동일한 이름을 가지고 있어야 한다.
dplyr의 bind_rows() 함수. 사용 방법은 아래와 같다.
df_all <- df_1 %>%
bind_rows(df_2)
어려울 게 하나도 없다.
R로 데이터프레임, 테이블 합치는 방법은 여기까지.