2016-10-25 90 views
5

我有一個類似於下面的但更大的矩陣。使用R中的apply將矩陣轉換爲配對列表?

vec <- c(0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0) 
M <- matrix(vec, nrow = 4, byrow = TRUE) 
colnames(M) <- rownames(M) <- LETTERS[1:4] 

    A, B, C, D 
A, 0, 1, 1, 0 
B, 0, 0, 1, 1 
C, 1, 0, 0, 0 
D, 0, 1, 1, 0 

最終,我想一個矩陣或其中,每個連續的呼叫具有值時間,我結束了一個rowname,列名對一個data.frame。因此,鑑於上述矩陣,我結束了與下面的矩陣或數據幀:

A,B 
A,C 
B,C 
B,D 
C,A 
D,B 
D,C 

我可以循環和與expand.grid做到這一點,但是這看起來像是我應該能夠用做應用功能。例如,我可以得到一部分的方式有這樣的:

tmp <- apply(M, 1, function(x) colnames(M)[which(x > 0)]) 

這給了我

$A 
[1] "B" "C" 
$B 
[1] "C" "D" 
$C 
[1] "A" 
$D 
[1] "B" "C" 

如果是容易的,那麼我可以還包括在細胞數(細胞超過0)作爲第三欄?

回答

3

上@弗蘭克的建議有關melt回升,這裏的使用和dplyr一種方法:

library(reshape2) 
library(dplyr) 

M2 <- M %>% 
    melt(.) %>% 
    transmute(pair = paste(Var1, Var2, sep = ","), 
      value = value) %>% 
    filter(value > 0) 

結果的順序是從你表現出什麼不同,但它不是很清楚,我是否該事項給您。

2
library(tidyr) 
M = as.data.frame(M) 
M["rowid"] = row.names(M) 
gather(M, colid, value, -rowid) 
3

您不一定需要使用apply()循環。這裏有一個基於R的想法,它使用which()來查找相關索引,然後進行一些簡單的提取和合並。

wM <- which(M > 0, arr.ind = TRUE) 
matrix(sort(paste(rownames(wM), colnames(M)[wM[,2]], sep = ","))) 
#  [,1] 
# [1,] "A,B" 
# [2,] "A,C" 
# [3,] "B,C" 
# [4,] "B,D" 
# [5,] "C,A" 
# [6,] "D,B" 
# [7,] "D,C" 

另外,還可以代替which使用rowcol

M0 <- M > 0 
paste(rownames(M)[row(M)[M0]], colnames(M)[col(M)[M0]], sep = ",") 
# [1] "C,A" "A,B" "D,B" "A,C" "B,C" "D,C" "B,D" 
4

一種igraph方法

library(igraph) 
as_data_frame(graph_from_adjacency_matrix(M, weighted = TRUE)) 

graph_from_adjacency_matrix()取矩陣作爲輸入並返回的曲線圖。使用weighted=TRUE作爲權重返回非零值。 as_data_frame回報具有關聯屬性的EdgeList都(在這種情況下,權重)

因此,對於你的榜樣,

as_data_frame(graph_from_adjacency_matrix(M, weighted = TRUE)) 
# from to weight 
# 1 A B  1 
# 2 A C  1 
# 3 B C  1 
# 4 B D  1 
# 5 C A  1 
# 6 D B  1 
# 7 D C  1