2015-09-25 122 views
0

我有兩個對稱的相關矩陣,其中一個代表另一個矩陣的子集。我想將兩個矩陣合併爲長格式,以便稍後將其用於x,y圖。這是一個小例子。合併兩個不同大小的矩陣

library(reshape) 
library(ggplot2) 

dist1 <- matrix(runif(16),4,4) 
dist2 <- matrix(runif(9),3,3) 
rownames(dist1) <- colnames(dist1) <- paste0("A",1:4) 
rownames(dist2) <- colnames(dist2) <- paste0("A",1:3) 

m1 <- melt(dist1) 
m2 <- melt(dist2) 

final <- merge(m1,m2, by=c("X1","X2")) 
ggplot(final, aes(value.x,value.y)) + geom_point() 

這很好。 final包含儘可能多的x1,x2對,如在較小矩陣m2中發現的那樣。 然而,在我的現實生活中的例子,事情看起來是不同的:

dim(m1) # the large matrix 
[1] 14845516  3 
dim(m2) # the small matrix 
[1] 574564 3 
dim(final) # the merged product 
[1] 286894 4 

真有點奇怪,final的對代表m2比對的一半略多(不同的是相當接近,但不等於m2)中的對角線單元的數量),所以也許merge()確實只找到一個三角形。但是我現在的假設是m2不是m1的子集(儘管它應該是)。所以,我的問題是:

如何檢查m2 [,1:2]中的所有對是否也出現在m1 [,1:2]中?

有沒有更好的選擇來創建一個合併數據框從m1和m2包含每個X1,X2對包含在兩個矩陣?最佳地,只有唯一的對,例如從A1,A2和A2,A1中,只有一對被選中。

謝謝。

回答

1

下面是我認爲是一個更好的方法,應該推廣到更大的設置,雖然沒有直接測試很難說。我不確定你的X1X2變量是什麼,但這應該起作用。合併結果的行數應該等於m2(較小的矩陣)的行數。

我改變了你的第一行至library(reshape2),這與您的代碼的其餘部分這兩個對象生成沿着:

> m1 
    Var1 Var2  value 
1 A1 A1 0.50120206 
2 A2 A1 0.07627305 
3 A3 A1 0.73757589 
4 A4 A1 0.24007736 
5 A1 A2 0.93485899 
6 A2 A2 0.67076761 
7 A3 A2 0.92666447 
8 A4 A2 0.79405152 
9 A1 A3 0.33120170 
10 A2 A3 0.48999764 
11 A3 A3 0.86967692 
12 A4 A3 0.01966199 
13 A1 A4 0.03986184 
14 A2 A4 0.50578328 
15 A3 A4 0.30689141 
16 A4 A4 0.54859405 
> m2 
    Var1 Var2  value 
1 A1 A1 0.56995004 
2 A2 A1 0.81317914 
3 A3 A1 0.51047761 
4 A1 A2 0.16949663 
5 A2 A2 0.21790332 
6 A3 A2 0.75785648 
7 A1 A3 0.75591111 
8 A2 A3 0.92541073 
9 A3 A3 0.07877851 

要合併這些,使用來自dplyr包,例如連接操作

> final <- dplyr::full_join(m1, m2, by=c("Var1","Var2")) 
Warning messages: 
1: In outer_join_impl(x, y, by$x, by$y) : 
    joining factors with different levels, coercing to character vector 
2: In outer_join_impl(x, y, by$x, by$y) : 
    joining factors with different levels, coercing to character vector 

> final 
    Var1 Var2 value.x value.y 
1 A1 A1 0.50120206 0.56995004 
2 A2 A1 0.07627305 0.81317914 
3 A3 A1 0.73757589 0.51047761 
4 A4 A1 0.24007736   NA 
5 A1 A2 0.93485899 0.16949663 
6 A2 A2 0.67076761 0.21790332 
7 A3 A2 0.92666447 0.75785648 
8 A4 A2 0.79405152   NA 
9 A1 A3 0.33120170 0.75591111 
10 A2 A3 0.48999764 0.92541073 
11 A3 A3 0.86967692 0.07877851 
12 A4 A3 0.01966199   NA 
13 A1 A4 0.03986184   NA 
14 A2 A4 0.50578328   NA 
15 A3 A4 0.30689141   NA 
16 A4 A4 0.54859405   NA 

(不要擔心這裏的警告。)

行,列標籤對你的小物件m2永遠是獨一無二的,如果你只想在較小的矩陣中的項目,那麼你可以使用right_join(),如:

> dplyr::right_join(m1, m2, by=c("Var1","Var2")) 
    Var1 Var2 value.x value.y 
1 A1 A1 0.50120206 0.56995004 
2 A2 A1 0.07627305 0.81317914 
3 A3 A1 0.73757589 0.51047761 
4 A1 A2 0.93485899 0.16949663 
5 A2 A2 0.67076761 0.21790332 
6 A3 A2 0.92666447 0.75785648 
7 A1 A3 0.33120170 0.75591111 
8 A2 A3 0.48999764 0.92541073 
9 A3 A3 0.86967692 0.07877851 
Warning messages: 
1: In right_join_impl(x, y, by$x, by$y) : 
    joining factors with different levels, coercing to character vector 
2: In right_join_impl(x, y, by$x, by$y) : 
    joining factors with different levels, coercing to character vector 
+0

我使用'melt'使用原始代碼得到相同的結果。唯一的區別在於'Var1'和'Var2'中的級別排序不同。所以我在這裏看到使用** dplyr **沒有真正的優勢。 –

2

如果M2所有對[1:2]可以確認出現在M1 [1:2]使用從dplyrintersect()功能:

library(dplyr) 
dim(intersect(m2[,1:2],m1[1:2])) 
[1] 9 2 
dim(m2[,1:2]) 
[1] 9 2 

此外,嘗試檢查,如果你的變量編碼爲因素。如果是這樣,如果你在這些變量上合併數據幀,你可能會得到奇怪的結果。最好將它們轉換爲字符。

至於最佳方法從dplyr合併的數據幀,merge從基礎R,以及inner_joindata.table包加入都應該是足夠好的在處理這一任務。 data.table可能是最快的。

而且,如果您只需要唯一對,則應在合併之前運行unique(m1[,1:2])

+0

我同意這有助於解決問題,因爲它可以幫助您找出爲什麼(!)您的合併結果不符合預期。然而,使用'unique(m1 [,1:2])'無助於擺脫重複的條目,例如'A1,A2'和'A2,A1'。 –