2016-10-25 3 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 

궁극적 I는 매트릭스 또는 연속 콜에 값이 각각 시간, I는 rowname 열 이름 쌍이 종단 A 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을 사용하여 0이 아닌 값을 가중치로 반환하십시오. 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 
관련 문제