dplyr - R: transform a dataframe into a visnetwork -


i new user of "visnetwork" package in r, , wondering way transform long data.frame visnetwork

i have kind of dataframe:

data<-data.frame(link=c("a","a","b","b","c","c","d","d","e","e"),node=c("alpha","beta","gamma","delta","alpha","delta","gamma","beta","alpha","beta"),        sign=c(1,-1))     link  node sign 1     alpha    1 2      beta   -1 3     b gamma    1 4     b delta   -1 5     c alpha    1 6     c delta   -1 7     d gamma    1 8     d  beta   -1 9     e alpha    1 10    e  beta   -1 

and goal transform in "visnetwork" one:

library(visnetwork) nodes <- data.frame(id = c("alpha","beta","gamma","delta"),                 label=c("alpha","beta","gamma","delta")) edges <- data.frame(from = c("alpha","beta","delta","delta"), = c("beta","gamma","gamma","alpha"),                 label=c("a+e","d","b","c"),                 arrows="middle") visnetwork(nodes, edges) %>%   visoptions(nodesidselection = true) 

any idea how ?

what have tried far:

nodes <- data.frame(id=c(distinct(data,as.character(node))),                 label=c(distinct(data,as.character(node)))) colnames(nodes)[1]<-"id" colnames(nodes)[2]<-"label"  edges<-tbl_df(data)  %>%    group_by(link) %>%    arrange(node) %>%   summarise(nodes  = paste(node, collapse =","))  %>%   arrange( nodes) %>%    separate(nodes,c("from","to"),sep=",") %>%    mutate(label=as.character(link)) %>%    mutate(arrows="middle")   visnetwork(nodes, edges) 

you need 2 tables visnetwork, 1 nodes , 1 links.

starting data example, nodes table can names of nodes , give them ids too.

data <- data.frame(link=c("a","a","b","b","c","c","d","d","e","e"), node=c("alpha","beta","gamma","delta","alpha","delta","gamma","beta","alpha","beta"), sign=c(1,-1))  nodes.df = data.frame(id = 1:length(unique(data$node)), label = sort(unique(data$node)) ) 

the links harder need aggregate data table each row becomes link node node b.

using dplyr far elegant solution:

library(dplyr) temp.links = as.character(unique(data$link)) # iterate through link names i.e. a, b... # , generate data.frame of link name, here there links.df = data.frame(t(sapply(temp.links, function(x) c(x, unlist(select(filter(data, link == x), node))) ))) # set names colnames(links.df) = c('label', 'from', 'to') # default width 1 aggregate next links.df$width = 1 # aggregate links same , values summing width , combining labels links.df = merge(aggregate( width ~ + , links.df , sum), aggregate( label ~ + to, links.df, function(x) paste0(x, collapse=' + '))) 

now have our nodes.df , links.df , ready plot

visnetwork(nodes.df, links.df) %>% vislayout(randomseed = 123) 

example resembles desired:

example

if data long , aggregations join bunch of named links connecting 2 nodes label a+b+c become long. don't label edges/links names rather width or weight of edge.


Comments

Popular posts from this blog

mysql - Dreamhost PyCharm Django Python 3 Launching a Site -

java - Sending SMS with SMSLib and Web Services -

java - How to resolve The method toString() in the type Object is not applicable for the arguments (InputStream) -