2016-10-25 7 views
5

私は以下のような行列を持っていますが、より大きいです。Rでの適用を使用して行列をペアリストに変換します。

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番目の列として?

答えて

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 
関連する問題