2013-01-03 1 views
0

두 데이터 세트를 함께 결합하려고합니다. x와 y라고 부르세요. 나는 y의 ID 변수가 x의 ID 변수의 부분 집합이라고 믿는다. 하지만 x가 y보다 많은 ID를 포함하고 있지만 매핑을 알지 못하기 때문에 순수한 의미는 아닙니다. 즉, x 및 y의 ID 중 일부 (전부는 아님)가 1 : 1과 일치 할 수 있습니다.R에서 복잡한 병합이있어 일치하지 않는 관측에 플래그를 지정 하시겠습니까?

나의 궁극적 인 목표는이 1 : 1 매핑이 실패한 곳을 파악하고 이러한 관찰에 플래그를 지정하는 것입니다. 나는 병합이 갈 길을 알았지 만 아닐 수도 있다고 생각했다. 예를 들면 다음과 같습니다.

id <- c(1:10, 1:100) 

X1 <- rnorm(110, mean = 0, sd = 1) 
year <- c("2004","2005","2006","2001","2002") 
year <- rep(year, 22) 

month = c("Jul","Aug","Sep","Oct","Nov","Dec","Jan","Feb","Mar","Apr") 
month <- rep(month, 11) 

#dataset X 
x <- cbind(id, X1, month, year) 

#dataset Y 
id2 <- c(1:10, 200) 
Y1 <- rnorm(11, mean = 0 , sd = 1) 
y <- cbind(id2,Y1) 

#merge on the IDs; but we get an error because when id2 == 200 in y we don't 
#have a match in x 
result <- merge(x, y, by.x="id", by.y = "id2", all =TRUE) 

id 데이터가 = 200인데도 x 데이터 세트에서 일치하지 않으므로 병합 오류가 발생합니다. 불행히도, 나는 신분증과 모든 정보도 잃어 버렸습니다! (행 111에서 200과 같아야 함) :

tail(result) 
     id     X1 month year   Y1 
106 95 -0.0748386054887876 Nov 2002   NA 
107 96 0.196765325477989 Dec 2004   NA 
108 97 0.527922135906927 Jan 2005   NA 
109 98 0.197927230533413 Feb 2006   NA 
110 99 -0.00720474886698309 Mar 2001   NA 
111 <NA>     <NA> <NA> <NA> -0.9664941 

더 많은 것은 병합 된 파일의 ID 변수에 대한 중복 된 관찰을 얻습니다. id2 == 1 관측은 한 번만 존재했지만 두 번 복사했습니다 (예 : Y1은 1.55를 두 번 사용함).

head(result) 
    id     X1 month year  Y1 
1 1 -0.67371266313441 Jul 2004 1.553220 
2 1 -0.318666983469993 Jul 2004 1.553220 
3 10 -0.608192898092431 Apr 2002 1.234325 
4 10 -0.72299929212347 Apr 2002 1.234325 
5 100 -0.842111221826554 Apr 2002  NA 
6 11 -0.16316681842082 Jul 2004  NA 

이 병합으로 인해 의도 한 것보다 복잡한 것이 있습니다. 나는 x에있는 모든 관찰을 검사하고 id가 y에서 id2와 일치하는 곳을 찾아 내고 그렇지 않은 것을 찾아 낼 수 있기를 바랬다. 그래서 나는 새 벡터를 얻을 것이고, flag라고 부르면, x $ id가 y $ id2에 일치하면 1을 취하고 그렇지 않으면 0을 취합니다. 이렇게하면 1 : 1 매핑이 실패한 곳을 알 수있었습니다. 잠재적으로 NAs를 다시 코딩하여이 문제에 대한 견인력을 얻을 수 있지만 id2 == 200 일 때 발생하는 오류는 무엇입니까? 그냥 정보를 버립니다.

내가 행운과 행으로 추가 시도 나는 아마도 그것은 루프를 짜는 것이 좋습니다뿐만 아니라 병합을 포기 또는 이러한 라인을 따라 뭔가 할 작동합니다 것 같습니다 : X의 모든 관찰

을 (ID2)에 대응

ID = ID2 개월 년

플래그 = 1 위의 길이 등 == 1, 그렇지 않으면 0

이면

바라건대이 모든 것이 의미가 있습니다. 나는 어떤 도움이나지도에 대해 매우 감사 할 것입니다. 당신이 x$id에서 일을 y$id2에있는 찾고 있다면

+0

'cbind'는 데이터 프레임이 아닌 행렬을 생성합니다. 'x'와'y'를 만들기위한 호출은'x

+0

'x $ id == 1' 인'x'에 두 개의 행이 있으므로'y $ id2 == 1'에 대한 두 가지 관찰 결과가 나옵니다. 병합에 조인 기준과 일치하는 여러 관측치가있는 경우 가능한 조합마다 행을 만듭니다. 이것은 의도적으로 설계된 것으로 매우 유용합니다. –

답변

0

, 당신은 일치를 반환 논리적 벡터를 얻을 수

x$id %in% y$id2 

를 사용할 수 있습니다. 그러나 일대일 대응은 보장하지 않습니다. 단지 1 대 다수. 그런 다음 x의 행 y에 해당 ID가 무엇인지 확인하려면 데이터 프레임

x$match.y <- x$id %in% y$id2 

이 벡터를 추가 할 수 있습니다.

는 관측이 1 대 1있는, 한 번 y$id2에서 이상 나타날 요소를 필터링하는

y$id2[duplicated(y$id2)] #vector of duplicate elements in y$id2 
(x$id %in% y$id2) & !(x$id %in% y$id2[duplicated(y$id2)]) 

처럼 뭔가를 할 수 참조하십시오.또한 x이를 추가 할 수 있습니다

같은 절차가 고유하게 일치 x에서 어떤 y 경기의 행, 그리고 어떤 것들 결정 y을 위해 할 수있는
x$match.y.unique <- (x$id %in% y$id2) & !(x$id %in% y$id2[duplicated(y$id2)]) 

.

+0

'duplicated'는 부울 벡터를 반환합니다. 당신은'y $ id2 [duplicated (y $ id2)]'를 원한다. –

+0

맞다! 실수를 깨닫고 편집 화면에서 올바른 구문을 기억하려고 몇 분을 보냈습니다. 캐치를 가져 주셔서 감사합니다. –

+0

고마워! 이 옵션은 y $ id2 == 200 일 때 잘 작동하지 않고 x $ id가 일치하지 않는 것 같습니다. false 여야하지만 사실이됩니다. 'test <- (x $ id % in % y $ id2) &! (x $ id2 [duplicated (y $ id2)])' 'test [1:20,] # first 20 rows' 11 번 행에서 우리는 1 : 1이 아닌 id에 해당하는 id2를 가지고 있고, 'FALSE'가되어야하지만 'TRUE'가됩니다. 그러면 모든 후속 라인이 엉망이됩니다. 그래서 우리는 행 12에 2 == 1 = TRUE를 갖습니다. –

0

병합에 실패한 이유는 x와 y에 대해 두 개의 다른 구조 (하나는 숫자 행렬이고 다른 하나는 문자 행렬)를 제공했기 때문입니다. data.frame을 선택해야하는 경우 cbind을 사용하는 것은 일반적인 실패 전략입니다.

> str(x) 
chr [1:110, 1:4] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "1" "2" ... 
- attr(*, "dimnames")=List of 2 
    ..$ : NULL 
    ..$ : chr [1:4] "id" "X1" "month" "year" 
> str(y) 
num [1:11, 1:2] 1 2 3 4 5 6 7 8 9 10 ... 
- attr(*, "dimnames")=List of 2 
    ..$ : NULL 
    ..$ : chr [1:2] "id2" "Y1" 

(dataframes 함께 작업하도록되어 무엇 merge 때문에) 당신은 성공했을 data.frame 기능을 사용하는 경우 :

다음
> x <- data.frame(id, X1, month, year); y <- data.frame(id2,Y1) 
> str(result <- merge(x, y, by.x="id", by.y = "id2", all =TRUE)) 
'data.frame': 111 obs. of 5 variables: 
$ id : num 1 1 2 2 3 3 4 4 5 5 ... 
$ X1 : num 1.5063 2.5035 0.7889 -0.4907 -0.0446 ... 
$ month: Factor w/ 10 levels "Apr","Aug","Dec",..: 6 6 2 2 10 10 9 9 8 8 ... 
$ year : Factor w/ 5 levels "2001","2002",..: 3 3 4 4 5 5 1 1 2 2 ... 
$ Y1 : num 1.449 1.449 -0.134 -0.134 -0.828 ... 

> tail(result <- merge(x, y, by.x="id", by.y = "id2", all =TRUE)) 
    id   X1 month year  Y1 
106 96 -0.3869157 Dec 2004  NA 
107 97 0.6373009 Jan 2005  NA 
108 98 -0.7735626 Feb 2006  NA 
109 99 -1.3537915 Mar 2001  NA 
110 100 0.2626190 Apr 2002  NA 
111 200   NA <NA> <NA> -1.509818 

당신이 당신의 'X'인수의 중복이있는 경우, 당신 해야 결과에서 중복. !duplicated을 적절하게 (병합 전이나 후에) 사용하는 것은 귀하의 책임이지만, merge이 그러한 결정을 내릴 것으로 기대할 수는 없습니다.

관련 문제