Reputation: 311
I have a matrix as follows: (adjacency matrix)
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
The objective is to get a square matrix, which will have dimension as number of rows and columns in the above matrix. This matrix would be filled using the above matrix (if A-S is 1, then S-A should be also 1) and the results should look like this (edge-list matrix),
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
I have written the following code which works well, I was wondering if there is an efficient way to achieve the above result?
#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]
}
Upvotes: 2
Views: 428
Reputation: 12935
You could do this using merge
and rbind
and cbind
in base 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
is where adjacency matrix is attached column-wise. p2
is the row-wise one and then rbind(p1,p2)
. These two are the main parts. The rest are just setting the names.
Upvotes: 0
Reputation: 887711
We create a matrix
of 0's based on the length
of unique
dimnames
of the first dataset. Based on the match
between the rownames
and colnames
of both the datasets, we assign the values of 'm1' to 'm2', take the transpose and add it with '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
Upvotes: 1