2017-04-22 162 views
2

我有一个矩阵如下:(邻接矩阵)更好的方法来创建边缘列表矩阵使用邻接矩阵

R S K 
A 1 1 0 
B 0 1 0 
C 1 0 0 
D 1 0 0 
E 0 0 1 
F 0 0 1 

的目的是得到一个正方形矩阵,这将有尺寸为行的数量和上述矩阵中的列。这个矩阵将使用上述矩阵填写(如果作为1,那么SA也应该是1),结果应该是这样的(边列表矩阵),

A B C D E F R S K 
A 0 0 0 0 0 0 1 1 0 
B 0 0 0 0 0 0 0 1 0 
C 0 0 0 0 0 0 1 0 0 
D 0 0 0 0 0 0 1 0 0 
E 0 0 0 0 0 0 0 0 1 
F 0 0 0 0 0 0 0 0 1 
R 1 0 1 1 0 0 0 0 0 
S 1 1 0 0 0 0 0 0 0 
K 0 0 0 0 1 1 0 0 0 

我写了下面的代码运行良好,我想知道是否有一种有效的方法来实现上述结果?

#READ THE FIRST DATA FRAME 
df <- read.table(text = "R S K 
1  1  0 
0  1  0 
1  0  0 
1  0  0 
0  0  1 
0  0  1", header=TRUE) 

#INPUT THE ROW NAMES IN df 
rownames(df)<-LETTERS[1:6] 
#INITIALIZE A SQUARE MATRIX WITH #ROWS=#COLUMNS=#(ROWS OF df)+#(COLUMNS OF df) 
godmat<-matrix(0, nrow = sum(dim(df)), ncol= sum(dim(df))) 
# ASSING ROW AND COLUMN NAMES 
rownames(godmat) <- c(rownames(df),colnames(df)) 
colnames(godmat) <- c(rownames(df),colnames(df)) 

#fill the matrix using df 
for (i in colnames(godmat)) 
    for (j in colnames(godmat)) { 
    godmat[i,j]=tryCatch({ godmat[i,j]<-df[which(rownames(df)==i), which(colnames(df)==j)]}, error = function(cond) { return(0)}) 
    #godmat[j,i]=godmat[i,j] 
    } 

#fill the matrix using df by copying the elements already filled 
for (i in colnames(godmat)) 
    for (j in colnames(godmat)) { 
    godmat[j,i]=godmat[i,j] 
    } 

回答

1

我们创造的0的matrix基于第一数据集的uniquedimnameslength。基于该rownames和两个数据集的colnames之间的match,我们给“M1”至“M2”的价值观,以转置与“M2”

un1 <- unique(unlist(dimnames(m1))) 
m2 <- matrix(0, length(un1), length(un1), dimnames = list(un1, un1)) 
i1 <- match(rownames(m1), rownames(m2), nomatch =0) 
j1 <- match(colnames(m1), rownames(m2), nomatch = 0) 
m2[i1, j1] <- m1 
t(m2)+m2 
# A B C D E F R S K 
#A 0 0 0 0 0 0 1 1 0 
#B 0 0 0 0 0 0 0 1 0 
#C 0 0 0 0 0 0 1 0 0 
#D 0 0 0 0 0 0 1 0 0 
#E 0 0 0 0 0 0 0 0 1 
#F 0 0 0 0 0 0 0 0 1 
#R 1 0 1 1 0 0 0 0 0 
#S 1 1 0 0 0 0 0 0 0 
#K 0 0 0 0 1 1 0 0 0 
+0

谢谢,这就是我一直在寻找的东西。一个问题@akrun,将不参加将保持秩序完好?我知道这对您提供的解决方案没有任何影响。 – vivek

+0

@vivek如果你想要一个自定义的订单,那么你可能不得不基于'match'或'factor'对其进行排序。 – akrun

0

你可以做到这一点使用merge添加它和rbindcbind在基R:

nm <- rownames(df) 
m <- matrix(0,nrow(df),nrow(df),dimnames = list(nm,nm)) 
p1 <- merge(m, df, by = "row.names")[-1] 
p2 <- cbind(t(df),matrix(0,ncol(df),ncol(df),dimnames = list(names(df),NULL))) 
colnames(p2) <- c(nm, names(df)) 
res <- rbind(p1,p2) 
rownames(res) <- c(nm, names(df)) 

# A B C D E F R S K 
# A 0 0 0 0 0 0 1 1 0 
# B 0 0 0 0 0 0 0 1 0 
# C 0 0 0 0 0 0 1 0 0 
# D 0 0 0 0 0 0 1 0 0 
# E 0 0 0 0 0 0 0 0 1 
# F 0 0 0 0 0 0 0 0 1 
# R 1 0 1 1 0 0 0 0 0 
# S 1 1 0 0 0 0 0 0 0 
# K 0 0 0 0 1 1 0 0 0 

p1是其中邻接矩阵连接列方向。 p2是行方式,然后是rbind(p1,p2)。这两个是主要部分。其余的只是设置名称。