2013-01-03 53 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) 

由於id2 == 200在x數據集中沒有匹配,所以合併拋出錯誤。不幸的是,我丟失了ID和所有信息! (它應該在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與id2匹配的位置,並標記沒有的id。所以我會得到一個新的向量,稱之爲標誌,如果x $ id在y $ id2中有一個匹配,則它的值爲1,否則爲零。這樣,我可以知道1:1映射失敗的位置。我可以通過重新編寫這些NAs來獲得一些牽引力,但是當id2 == 200時會引發錯誤呢?它只是丟棄信息。

我試圖追加的行,沒有運氣,它看起來像我應該放棄合併爲好,也許這是更好地擰循環或函數來執行這些方針的東西:在X每個觀測

ID2 =其中(ID2)對應於ID - 月 - 年

標誌= 1,如果上述長度爲== 1,否則爲0

希望這一切都有道理。我會非常感謝任何幫助或指導。

+0

'cbind'創建矩陣,而不是數據框。您創建'x'和'y'的調用應該是'x < - data.frame(id,X1,month,year)'和'y < - data.frame(id2,Y1)'。 –

+0

由於'x'中有兩行'x $ id == 1',因此您得到了兩個'y $ id2 == 1'的觀察值。如果合併看到與連接標準相匹配的多個觀察值,它將爲每個可能的組合創建一行。這是設計並且非常有用。 –

回答

0

如果你正在尋找這東西x$idy$id2,那麼你可以使用

x$id %in% y$id2 

得到返回匹配的邏輯載體。然而,它並不能保證1對1的對應關係。只是一對多。然後,您可以將此向量添加到您的數據幀

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

看什麼的x排在y有一個相應的ID。

要了解哪些意見是1比1,你可以不喜歡

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)]) 

篩選出出現比y$id2一次更多的元素。你也可以將它添加到x

x$match.y.unique <- (x$id %in% y$id2) & !(x$id %in% y$id2[duplicated(y$id2)]) 

同樣的程序可以爲y來完成,以確定哪些y比賽的排在x,哪些匹配唯一。

+0

'duplicateated'返回一個布爾向量。你想'y $ id2 [重複(y $ id2)]' –

+0

對!我意識到自己的錯誤,並在編輯屏幕上花了幾分鐘時間試圖記住正確的語法。謝謝你的收穫。 –

+0

謝謝!當y $ id2 == 200並且在x $ id中沒有匹配時,它看起來像這個選項不起作用。它應該是假的,但實際上是: 'test < - (x $ id%in%y $ id2)&!(x $ id%in%y $ id2 [duplicated(y $ id2)])' 'test < - data.frame(x,y,test)' 'test [1:20,]#first 20 rows' 在第11行中,我們有id2對應於不是1:1的id,應該是'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" 

如果您使用的data.frame功能(因爲dataframes是什麼merge應該與其合作)它會成功:

> 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爲你做出這樣的決定。