Question

I would like to create an edge from matching column values in a table, so basically:

   V1  V2  V3
A  1    1   0
B  1    0   1
C  0    1   1
D  1    0   1

if I had a table like so, then I would like to make an edge list where

A - B
A - D
A - C
B - C
B - D

so I would like to create an edge whenever the column values match per row. I've looked over a lot of documentation but I can't seem to figure out anything that does something similar to this. Any help would be appreciated!

Was it helpful?

Solution

I would try the "igraph" package after using crossprod on your data. Assuming your data.frame is called "mydf":

out <- crossprod(t(mydf))
out[lower.tri(out, diag=TRUE)] <- 0

library(igraph)
g <- graph.adjacency(out)
get.edgelist(g)
#      [,1] [,2]
# [1,] "A"  "B" 
# [2,] "A"  "C" 
# [3,] "A"  "D" 
# [4,] "B"  "C" 
# [5,] "B"  "D" 
# [6,] "B"  "D" 
# [7,] "C"  "D" 

If you don't want duplicates, you can use:

g <- graph.adjacency(out > 0)
get.edgelist(g)

OTHER TIPS

Try this:

#dummy data
df <- read.table(text="
A 1 1 0
B 1 0 1
C 0 1 1
D 1 0 1",sep=" ", as.is=TRUE)

#get names where 1 per column
lst <- sapply(2:ncol(df), function(j)
  df[df[,j]==1,1])
#make combinations
lst_comb <- sapply(1:(ncol(df)-1), function(i)
  combn(lst[[i]],2))
#output
matrix(sort(unique(
  unlist(
    sapply(1:length(lst_comb),function(i){
      x <- t(lst_comb[[i]])
      paste0(x[,1],"-",x[,2])
      })))))

#     [,1]  
#[1,] "A-B"
#[2,] "A-C"
#[3,] "A-D"
#[4,] "B-C"
#[5,] "B-D"
#[6,] "C-D"

Here is my approach based on combn:

sort(unique(unlist(apply(df, 2, function(x)combn(rownames(df)[which(x==1)], 2, FUN=paste, collapse=" - ")))))

whith df as you data, gives you:

[1] "A - B" "A - C" "A - D" "B - C" "B - D" "C - D"
dat<- read.table(text=" ID     V1    V2   V3
                        A      1     1    0
                        B      1     0    1
                        C      0     1    1
                        D      1     0    1", header= TRUE)

library(reshape2)
library(tnet)

dat2 <- melt(dat, id= "ID")
dat2 <- dat2[dat2$value > 0 ,]
dat3 <- as.tnet(cbind(dat2[,1],dat2[,2]), type="binary two-mode tnet")
dat3 <- projecting_tm(dat3, method = "sum")[1:2]

dat3[dat3 == 1] <- "A" # there is an easier way to change names
dat3[dat3 == 2] <- "B"
dat3[dat3 == 3] <- "C"
dat3[dat3 == 4] <- "D"


dat3[!duplicated(t(apply(dat3, 1, sort))), ]

#  i j
#1 A B
#2 A C
#3 A D
#5 B C
#6 B D
#9 C D
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top