R의 데이터 프레임 병합: 전체 및 부분 일치

⚡ 스마트 요약

R에서 데이터 프레임 병합은 하나 이상의 공통 키 열을 기준으로 두 테이블을 결합합니다. `merge()` 함수는 내부, 왼쪽, 오른쪽 및 전체 조인을 지원하며, 이 예제에서는 전체 일치 및 부분 일치 조인을 모두 보여줍니다.

  • 🔑 주요 열: merge() 함수는 by를 기준으로 조인하거나, 키의 이름이 각 프레임에서 다를 경우 by.x와 by.y를 기준으로 조인합니다.
  • 🔗 전체 매치: 기본 내부 조인은 두 데이터 프레임 모두에 키가 나타나는 행만 유지합니다.
  • 🧩 부분 일치: all.x = TRUE로 설정하면 첫 번째 프레임의 모든 행이 유지되고 빈칸은 NA로 채워집니다.
  • 📐 치수 확인: 병합 전후의 dim() 값을 비교하여 조인으로 인해 손실되거나 중복된 행을 찾아냅니다.
  • ⚙️ 참여 제어: all, all.x 및 all.y 플래그는 내부, 왼쪽, 오른쪽 또는 전체 외부 동작을 선택합니다.
  • 🛠️ 현대적 대안: dplyr은 각 조인에 대한 이름을 동사 자체에 포함시키고 원래 행 순서를 유지합니다.

R에서 데이터 프레임 병합

우리는 여러 소스로부터 데이터를 얻는 경우가 많습니다. 분석을 수행하려면 다음이 필요합니다. 병합 두 개의 데이터프레임과 하나 이상의 데이터프레임 공통 주요 변수.

R에서의 병합(조인) 유형

예제를 살펴보기 전에 merge() 함수가 SQL 사용자가 기대하는 모든 조인 유형을 수행한다는 점을 알아두면 도움이 됩니다. 이러한 동작은 함수 이름이 아니라 all, all.x, all.y 인수에 의해 제어됩니다.

조인 유형 유지된 행 merge() 호출 dplyr 동등물
내부 조인(기본값) 두 프레임 모두에 존재하는 키만 merge(x, y, by = “k”) inner_join(x, y, by = “k”)
왼쪽 외부 조인 y에 일치하는 항목이 없는 x의 모든 행, NA merge(x, y, by = “k”, all.x = TRUE) left_join(x, y, by = “k”)
오른쪽 외부 결합 x에 일치하는 항목이 없는 y의 모든 행은 NA입니다. merge(x, y, by = “k”, all.y = TRUE) right_join(x, y, by = “k”)
전체 외부 조인 두 프레임의 모든 행 merge(x, y, by = “k”, all = TRUE) full_join(x, y, by = “k”)
교차 결합 모든 행의 조합 merge(x, y, by = NULL) cross_join(x, y)

첫 통화 전에 기억해 두면 좋은 두 가지 사항이 있습니다.

  • `by`를 제외하면 R은 두 프레임이 공유하는 모든 열 이름을 기준으로 병합하는데, 이는 일반적으로 원하는 결과가 아닙니다.
  • merge() 함수는 키 열을 기준으로 결과를 정렬합니다. 입력 순서를 유지하려면 sort = FALSE를 전달하세요.

전체 경기

완전 일치는 대상 테이블에 대응하는 값이 있는 행만 반환합니다. 일치하는 행이 없는 행은 새 데이터 프레임에서 삭제됩니다. 반면 부분 일치는 해당 행을 유지하고 누락된 열에는 NA 값을 채웁니다.

우리는 간단한 것을 볼 것입니다 내부 결합. 내부 조인 키워드는 두 테이블 모두에서 일치하는 값이 있는 레코드를 선택합니다. 두 개의 데이터 세트를 결합하려면 merge() 함수를 사용할 수 있습니다. 우리는 세 가지 인수를 사용합니다:

merge(x, y, by.x = x, by.y = y)

Arguments:
-x: The origin data frame
-y: The data frame to merge
-by.x: The column used for merging in x data frame. Column x to merge on
-by.y: The column used for merging in y data frame. Column y to merge on

예:

변수를 사용하여 첫 번째 데이터세트 만들기

  • 국적

변수를 사용하여 두 번째 데이터세트 만들기

  • 영화 산업

공통 키 변수는 성입니다. 둘을 병합할 수 있습니다. 데이터 프레임 그리고 차원이 7×3인지 확인하십시오.

우리는 stringsAsFactors=FALSE를 데이터프레임에 추가합니다. 왜냐하면 우리는 그렇게 하고 싶지 않기 때문입니다. R 문자열을 변환하기 위해 인자변수는 문자 벡터로 유지되어야 합니다. R 4.0.0부터 data.frame()의 기본값이 문자 벡터이므로, 새 코드에서는 이 인수가 선택 사항이며 이전 코드에서는 문제가 없습니다.

# Create origin dataframe(

producers <- data.frame(   
    surname =  c("Spielberg","Scorsese","Hitchcock","Tarantino","Polanski"),    
    nationality = c("US","US","UK","US","Poland"),    
    stringsAsFactors=FALSE)

# Create destination dataframe
movies <- data.frame(    
    surname = c("Spielberg",
		"Scorsese",
                "Hitchcock",
              	"Hitchcock",
                "Spielberg",
                "Tarantino",
                "Polanski"),    
    title = c("Super 8",
    		"Taxi Driver",
    		"Psycho",
    		"North by Northwest",
    		"Catch Me If You Can",
    		"Reservoir Dogs","Chinatown"),                
     		stringsAsFactors=FALSE)

# Merge two datasets
m1 <- merge(producers, movies, by.x = "surname")
m1
dim(m1)

출력:

surname		nationality		title
1 Hitchcock		UK		Psycho
2 Hitchcock		UK		North by Northwest
3 Polanski		Poland		Chinatown
4 Scorsese		US		Taxi Driver
5 Spielberg		US		Super 8
6 Spielberg		US		Catch Me If You Can
7 Tarantino		US		Reservoir Dogs

공통 키 변수의 이름이 다른 경우 데이터 프레임을 병합해 보겠습니다.

영화 데이터 프레임에서 성을 이름으로 변경합니다. 두 데이터프레임이 동일한지 확인하기 위해 동일(x1, x2) 함수를 사용합니다.

# Change name of ` movies ` dataframe
colnames(movies)[colnames(movies) == 'surname'] <- 'name'
# Merge with different key value
m2 <- merge(producers, movies, by.x = "surname", by.y = "name")
# Print head of the data
head(m2)

출력:

##surname     nationality		title
## 1 Hitchcock          UK		Psycho
## 2 Hitchcock          UK		North by Northwest
## 3 Polanski          Poland		Chinatown
## 4 Scorsese           US		Taxi Driver
## 5 Spielberg          US		Super 8
## 6 Spielberg          US		Catch Me If You Can
# Check if data are identical
identical(m1, m2)

출력:

## [1] TRUE

이는 열 이름이 다르더라도 병합 작업이 수행됨을 보여줍니다.

부분 일치

위의 내부 조인은 대응되는 항목이 없는 모든 항목을 조용히 제거했습니다. 두 데이터프레임에 공통 키 변수가 없는 것은 놀라운 일이 아닙니다. 완전 매칭, 데이터 프레임이 반환됩니다. x 및 y 데이터 프레임 모두에서 행이 발견되었습니다. 와 함께 부분 병합, 다른 데이터 프레임에서 일치하는 행이 없는 행을 유지하는 것이 가능합니다. 이러한 행에는 일반적으로 y의 값으로 채워지는 열에 NA가 있습니다. all.x= TRUE로 설정하면 됩니다.

예를 들어, 영화 데이터프레임에서 영화 정보를 제외하고 프로듀서 데이터프레임에 새로운 프로듀서인 루카스를 추가할 수 있습니다. 만약 `all.x=FALSE`로 설정하면 R은 두 데이터프레임에서 일치하는 값만 결합합니다. 따라서 루카스는 한 데이터프레임에 없기 때문에 결과에 포함되지 않습니다.

all.x= TRUE를 지정할 때와 지정하지 않을 때 각 출력의 차원을 살펴보겠습니다.

# Create a new producer
add_producer <-  c('Lucas', 'US')
#  Append it to the ` producer` dataframe
producers <- rbind(producers, add_producer)
# Use a partial merge 
m3 <-merge(producers, movies, by.x = "surname", by.y = "name", all.x = TRUE)
m3

출력:

아래 콘솔 출력은 누락된 영화 제목을 NA로 대체한 추가 Lucas 행을 보여줍니다.

부분 병합의 콘솔 출력 결과입니다. 제목 열에 Lucas와 NA가 표시됩니다.

# Compare the dimension of each data frame
dim(m1)

출력:

## [1] 7 3
dim(m2)

출력:

## [1] 7 3
dim(m3)

출력:

## [1] 8 3

보시다시피, 새로운 데이터 프레임은 m1과 m2의 7×3에 비해 8×3입니다. R은 영화 데이터 프레임에 일치하는 행이 없는 프로듀서인 Lucas의 제목 열을 NA로 채웁니다.

R에서 merge()와 dplyr의 조인 비교

R의 기본 기능은 하나의 함수와 플래그 세트를 사용하여 모든 조인 문제를 해결합니다. dplyr 대신 패키지는 각 조인에 고유한 동사를 부여하는데, 많은 팀들이 파이프라인에서 이를 더 읽기 쉽다고 생각합니다.

기준 기본 병합() dplyr이 참여합니다
결합을 선택하세요 all.x / all.y / 모든 플래그 동사에 이름이 지정된 함수: left_join(), full_join()
행 순서 sort = FALSE가 아닌 경우 키를 기준으로 정렬됩니다. 왼쪽 테이블의 순서가 유지됩니다.
대형 프레임에서의 속도 느린 일반적으로 더 빠릅니다.
주요 열이 누락되었습니다 오류가 늦게 발생하거나 잘못된 열을 기준으로 병합됩니다. 오류는 즉시
종속성 기본 R 버전이므로 설치할 필요가 없습니다. dplyr 패키지가 필요합니다.

위에 표시된 두 개의 병합은 dplyr 동사로 직접 변환됩니다.

library(dplyr)
# Same inner join as merge(producers, movies, by.x = "surname", by.y = "name")
m4 <- inner_join(producers, movies, by = c("surname" = "name"))
# Same partial merge as all.x = TRUE
m5 <- left_join(producers, movies, by = c("surname" = "name"))

패키지 내에서 종속성이 없어야 하는 경우에는 base merge()를 사용하는 것이 더 안전한 선택입니다. 반면, 가독성과 속도가 더 중요한 대화형 분석 환경에서는 dplyr이 더 나은 선택입니다.

R에서 흔히 발생하는 병합 오류 및 해결 방법

대부분의 병합 문제는 오류 메시지보다는 예상치 못한 행 수로 나타나므로, 모든 조인 후에 dim() 함수를 확인하는 습관을 들이는 것이 좋습니다.

  • 결과값의 행 수가 입력값 두 개보다 많습니다. 두 프레임 모두에서 반복되는 키는 다대다 조인을 생성하며, R은 모든 조합을 반환합니다. 병합하기 전에 table(duplicated(x$k))를 사용하여 키를 검사하십시오.
  • 결과가 비어 있습니다. 키 열은 일반적으로 데이터 유형이 다르거나, 하나에 공백이 포함되어 있는 경우가 있습니다. 병합하기 전에 두 프레임 모두에 str() 함수를 실행하고 trimws() 함수를 사용하여 키를 정리하십시오.
  • 열은 title.x와 title.y 형식으로 반환됩니다. 두 프레임 모두 동일한 이름을 가진 비키 열을 포함합니다. 출처를 명확히 하려면 접미사 = c(“_producer”, “_film”)을 전달하세요.
  • 행들이 원래 순서대로 배열되어 있지 않습니다. merge() 함수는 기본적으로 키를 기준으로 정렬합니다. sort = FALSE를 추가하거나 다른 방법을 사용하세요. 명시적인 종류 나중에.
  • 핵심 비교에서 몇 가지 요인이 잘못되었습니다. 요인 수준이 아닌 문자를 비교하십시오. 이전 R 기본 설정으로 생성된 프레임을 병합하기 전에 키를 as.character()로 감싸십시오.

동일한 병합 작업을 반복적으로 실행해야 하는 경우, 해당 작업을 `<p>` 태그로 묶으세요. 사용자 정의 함수 따라서 실행 간에 인수가 이동하지 않습니다.

자주 묻는 질문

R은 두 프레임이 공유하는 모든 열 이름을 기준으로 병합합니다. 공유 열이 하나뿐이면 편리하지만, 여러 개일 경우 결과가 자동으로 축소되고, 공유 열이 하나도 없을 경우 교차 조인이 반환됩니다. 키 이름을 명시적으로 지정하면 이 세 가지 상황을 모두 피할 수 있습니다.

단일 merge() 호출로는 안 됩니다. 호출을 연결하거나 Reduce(function(x, y) merge(x, y, by = “k”), list(df1, df2, df3))와 같이 리스트를 접으세요. 중복 키가 빠르게 누적되므로 각 단계 후 행 수를 확인해야 합니다.

두 프레임 모두 동일한 이름의 비키 열을 포함하고 있으므로 R은 이를 구분합니다. 복사본에 의미 있는 이름을 지정하려면 접미사 = c(“_producer”, “_film”)을 전달하거나 병합하기 전에 중복 열을 삭제하십시오.

아니요. merge() 함수는 기본적으로 키 열을 기준으로 결과를 정렬합니다. 입력 순서를 유지하려면 sort = FALSE를 전달하거나 다른 방법을 사용하세요. dplyr 왼쪽 프레임의 순서를 유지하는 join입니다.

벡터를 제공하세요: merge(x, y, by = c(“surname”, “year”)). 이름이 다른 경우, 일치하는 벡터를 by.x와 by.y에 전달하세요. 두 벡터는 열의 순서가 동일해야 합니다.

`by = “row.names”` 또는 단축 표현인 `by = 0`을 사용하세요. R은 행 이름을 `Row.names`라는 열로 다시 추가하는데, 일반적으로 분석을 계속하기 전에 이 열의 이름을 바꾸거나 삭제하는 것이 좋습니다.

두 프레임과 행 수를 설명하면 AI 도우미가 중복 키가 원인일 가능성이 높다고 지적하고 duplicated() 검사를 제안합니다. 조인을 변경하기 전에 자체 데이터로 진단을 확인하세요.

예. RStudio 데스크톱 2023.09.0 이상 버전에는 선택 기능이 포함되어 있습니다. GitHub 부조종사 댓글에서 병합 문서를 생성하는 통합 기능입니다. 잘못된 플래그를 선택하면 행 수가 자동으로 변경되므로, 통합 기능에서 선택하는 조인 유형을 확인하세요.

이 게시물을 요약하면 다음과 같습니다.