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:
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
Post a Comment