Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating edge list in R

Tags:

r

edge-list

I have data like this:

ID=c(rep("ID1",3), rep("ID2",2), "ID3", rep("ID4",2))
item=c("a","b","c","a","c","a","b","a")

data.frame(ID,item)

ID1 a
ID1 b
ID1 c
ID2 a
ID2 c
ID3 a
ID4 b
ID4 a

and I would need it as a list of edges like this:

a;b
b;c
a;c
a;c
b;a

the first three edges coming from ID1, fourth from ID2, ID3 has no edges so nothing from that and fifth from ID4. Any ideas on how to accomplish this? melt/cast?

like image 778
ElinaJ Avatar asked Feb 08 '15 11:02

ElinaJ


3 Answers

I'd guess there should be a simple igrpah solution for this, but here's a simple solution using data.table package

library(data.table)
setDT(df)[, if(.N > 1) combn(as.character(item), 2, paste, collapse = ";"), ID]

#     ID  V1
# 1: ID1 a;b
# 2: ID1 a;c
# 3: ID1 b;c
# 4: ID2 a;c
# 5: ID4 b;a
like image 173
David Arenburg Avatar answered Nov 15 '22 06:11

David Arenburg


Try

 res <- do.call(rbind,with(df, tapply(item, ID, 
         FUN=function(x) if(length(x)>=2) t(combn(x,2)))))
  paste(res[,1], res[,2], sep=";")
 #[1] "a;b" "a;c" "b;c" "a;c" "b;a"
like image 38
akrun Avatar answered Nov 15 '22 04:11

akrun


Here is a more scalable solution that uses the same core logic as the other solutions:

library(plyr)
library(dplyr)

ID=c(rep("ID1",3), rep("ID2",2), "ID3", rep("ID4",2))
item=c("a","b","c","a","c","a","b","a")

dfPaths = data.frame(ID, item)
dfPaths2 = dfPaths %>% 
  group_by(ID) %>% 
  mutate(numitems = n(), item = as.character(item)) %>%
  filter(numitems > 1)


ddply(dfPaths2, .(ID), function(x) t(combn(x$item, 2)))
like image 23
tchakravarty Avatar answered Nov 15 '22 05:11

tchakravarty