Reconstruct symmetric matrix from values in long-form
An igraph
solution where you read in the dataframe, with the value assumed as edge weights. You can then convert this to an adjacency matrix
dat <- read.table(header=T, text=" one two value
a b 30
a c 40
a d 20
b c 10
b d 05
c d 30")
library(igraph)
# Make undirected so that graph matrix will be symmetric
g <- graph.data.frame(dat, directed=FALSE)
# add value as a weight attribute
get.adjacency(g, attr="value", sparse=FALSE)
# a b c d
#a 0 30 40 20
#b 30 0 10 5
#c 40 10 0 30
#d 20 5 30 0
Yet another approach is reshape::cast
df.long = data.frame(one=c('a','a','a','b','b','c'),
two=c('b','c','d','c','d','d'),
value=c(30,40,20,10,05,30) )
# cast will recover the upper/lower-triangles...
df <- as.matrix( cast(df.long, one ~ two, fill=0) )
# b c d
# a 30 40 20
# b 0 10 5
# c 0 0 30
So we construct matrix with full indices, and insert:
df <- matrix(nrow=length(indices), ncol=length(indices),dimnames = list(indices,indices))
diag(df) <- 0
# once we assure that the full upper-triangle is present and in sorted order (as Robert's answer does), then we
df[upper.tri(df)] <- as.matrix( cast(df.long, one ~ two, fill=0) )
df[lower.tri(df)] <- df[upper.tri(df)]
UPDATE: the original sketch included these manual kludges
Then the same approaches to add the missing row 'd' and column 'a', and fill the lower triangle by adding the transpose t(df) :
df <- cbind(a=rep(0,4), rbind(df, d=rep(0,3)))
# a b c d
# a 0 30 40 20
# b 0 0 10 5
# c 0 0 0 30
# d 0 0 0 0
df + t(df)
# a b c d
# a 0 30 40 20
# b 30 0 10 5
# c 40 10 0 30
# d 20 5 30 0