control edge width with value and width in r visnetwork package - r

I'm trying to visualize my network with visNetwork package. But I found myself totally confused about controling node size and edge width. In the first example, I set value=1 in nodes and value=0.1in edges. In the second example, I set value=10 in nodes and width=0.1 in edges. However, in both graphs, size of nodes appear to be the same. Changing edge width seems to work with width not value. I don't know why. I did see people use value in edges for edge width control.
Can anyone clarify me on this issue? Also, what is the range of values for node size and edge width?
nodes1 <- data.frame(id = 1:10,
label = paste("Node", 1:10),# add labels on nodes
value = 1, #**
color = c("darkblue"))
edges1 <- data.frame(from = sample(1:10,8),
to = sample(1:10, 8),
value = 0.1 #**
)
visNetwork::visNetwork(nodes1, edges1, width = "150%", physics=F)
nodes2 <- data.frame(id = 1:10,
label = paste("Node", 1:10),# add labels on nodes
value = 10, #**
color = c("darkblue"))
edges2 <- data.frame(from = sample(1:10,8),
to = sample(1:10, 8),
width = 0.1 #**
)
visNetwork::visNetwork(nodes2, edges2, width = "150%", physics=F)

it looks like size of the nodes works based on comparison . If it is set one value than graph just reflect the same size of nodes on optimal scale, thus it is not changed
if you put value equal to different number you'll see nodes of different size
nodes2 <- data.frame(id = 1:10,
label = paste("Node", 1:10),# add labels on nodes
value = 1:10, #**
color = c("darkblue"))
edges2 <- data.frame(from = sample(1:10,8),
to = sample(1:10, 8),
width = 0.1 #**
)
visNetwork::visNetwork(nodes2, edges2, width = "150%", physics=F)

Related

Sort multiple nodes into rows in DiagrammeR in R

I am building a large map where a number of observed variables map onto latent variables. When using DiagrammeR to generate the map, all the observed items (indicated by squares) appear in a single row. I was wondering if there was a way to sort them into multiple rows, say 5 or 10 in a row? The example below is based on actual data where there are 30+ items that map to one latent variable. The final map will have multiple sets of these, but right now, I am working on getting one to display correctly:
library(tidyverse)
library(DiagrammeR)
nodes <- create_node_df(
n=33,
nodes = 33,
label = make.unique(rep(letters, length.out = 33), sep=''),
tooltip = make.unique(rep(letters, length.out = 33), sep=''),
fontsize= 7,
shape = c("ellipse", "ellipse", rep("square", 31)),
fillcolor = "white",
width = 1,
height = 1,
)
# lines
edges <- create_edge_df(
from=c(1,rep(2,32)),
to = c(2,3,seq(3, 33, 1)),
)
create_graph(nodes_df = nodes,
edges_df = edges,
) %>%
render_graph(layout="tree")
This renders as:
However, what I am going for is more like:

Venn diagram (4 sets) with R: problem with percentages

I am trying to draw a Venn diagram with four logical variables. I have tried many different R packages but with each of them I have faced some problems. So far, the best result I have achieved by using the ggvenn package. However, the problem is, that it shows the percentages of the intersections based on the observations included in the diagram, instead of all observations in the data.
Below is an example Venn diagram and its code to illustrate the problem. So my question is: is there some way to display the percentages in relation to the total amount of observations in the data. For instance, in the diagram below the intersection of ABCD consists of 45 observation and thus the correct proportion would be 4.5% (i.e. 45/1000) instead of 4.7%.
I would really appreciate if someone could help me out with this.
library(ggvenn)
a <- sample(x = c(TRUE, TRUE, FALSE), size = 1000, replace = TRUE)
b <- sample(x = c(TRUE,FALSE, FALSE), size = 1000, replace = TRUE)
c <- sample(x = c(TRUE, FALSE, FALSE, FALSE), size = 1000, replace = TRUE)
d <- sample(x = c(TRUE, TRUE, TRUE, FALSE), size = 1000, replace = TRUE)
df <- tibble(values = c(1:1000), A=a, B=b, C=c, D=d)
ggvenn(df,
fill_color = c("black", "grey70", "grey80", "grey90"),
show_percentage = TRUE,
digits = 1,
text_size = 2.5)
A quick fix for this problem would be to use the latest Github version of {ggvenn}:
remove.packages("ggvenn")
devtools::install_github("yanlinlin82/ggvenn")
Then, by default, there will be also a percentage for the observations that are outside A/B/C/D. This gives you the percentages you're looking for:

R how to increase distance between grids when using plot function?

I'm learning the Numerical Ecology with R. However, I found all my plots lacking the distance between bars or grids.
myplot
textbook's plot
spe.KM.cascade <-
cascadeKM(
spe.norm2,
inf.gr = 2,
sup.gr = 10,
iter = 100,
criterion = "ssi"
)
dev.new(
title = "CascadeKM",
width = 10,
height = 6,
noRStudioGD = TRUE
)
plot(spe.KM.cascade, sortg = TRUE, border = 'white')
I want to know how to add white borders for every grid.

R visNetwork: create new type of edges

I want to create a PAG(parental ancestral graph) with visNetwork for my shiny app.
In order to do that i have to create edges that have both circles and arrows.
According to the visNetwork package i can convert the arrows to circles like this
visNetwork(nodes, edges) %>%
visEdges(arrows = list(to = list(enabled = TRUE,
scaleFactor = 2, type = 'circle')))
But i want to have both an arrow and a circle, or two circles in one edge like in this picture
PAG
The arrows.from.type and arrows.to.type seem to be working but i now i have this problem.
I want to draw this graph according to an adjacency matrix
So i have this code
i = 1
j = 1
for(i in i:ncol(results))
{
j = i
for(j in j:nrow(results))
{
if(results[j,i]==1)
{
dashBoard = c(dashBoard,TRUE)
colorBoard = c(colorBoard, "green")
if(results[i,j]==1)
{
fromtest <- c(fromtest,Cnames[i])
totest <- c(totest,Rnames[j])
arrfrom <-c(arrfrom,"circle")
arrto<-c(arrto,"circle")
}
else if(results[i,j]==2)
{
fromtest<-c(fromtest,Cnames[i])
totest<-c(totest,Rnames[j])
arrfrom <-c(arrfrom,"circle")
arrto<-c(arrto,"arrow")
}}
That goes on for every possible combination except 1,1 and 1,2
In the end the edges are printed like that
edgesprint <-data.frame(from = fromtest,
to = totest,
arrows.from.type=arrfrom,
arrows.to.type=arrto,
dashes = dashBoard,
physics = FALSE,
smooth = FALSE,
width = 3,
shadow = TRUE,
color = list(color = colorBoard, highlight = "red", hover = "green"),
links = links)
This method works good but sometimes without changing any code i get this error
error in data.frame arguments imply differing number of rows
You can set individual arrow types in the edges data frame by adding columns arrows.to.type and arrows.from.type:
library(visNetwork)
library(magrittr)
nodes <- data.frame(id=c("a","b","c","d"), label=c("a","b","c","d"))
edges <- data.frame(
from = c("a","a","a"),
to = c("b","c","d"),
arrows.from.type = c(NA,"circle","circle"),
arrows.to.type = c("arrow","circle",NA)
)
visNetwork(nodes, edges)
Result:
This approach works for all other attributes you can set through visNodes and visEdges. See here for an example.

How have labels inside the scaled nodes in visNetwork?

In visNetwork, by default text doesn't go inside nodes, instead it appears below it:
require(visNetwork, quietly = TRUE)
nodes <- data.frame(id = 1:3, label=2014:2016 ,value=1:3)
edges <- data.frame(from = c(1,2), to = c(1,3))
visNetwork(nodes, edges, width = "100%")
Seems like the only way to solve this issue is to use set shape property to circle:
require(visNetwork, quietly = TRUE)
nodes <- data.frame(id = 1:3, label=2014:2016 ,value=1:3,shape='circle')
edges <- data.frame(from = c(1,2), to = c(1,3))
visNetwork(nodes, edges, width = "100%")
The problem is that, as you can see in the figure above, now with labels inside circle scaling nodes using value property don't work.
So the question is how to have both options ("scale" and "text inside") at the same time?
PS: What a pity, there is no visNetwork tag!
I found a tricky way to solve this bug. setting up font.size instead of value property works fine. You need to scale it for best visualization. For instance I scale it 10 times bigger:
require(visNetwork, quietly = TRUE)
nodes <- data.frame(id = 1:3, label=2014:2016 ,font.size =(1:3)*10,shape='circle')
edges <- data.frame(from = c(1,2), to = c(1,3))
visNetwork(nodes, edges, width = "100%")
I've found another way, adding spaces on bot sides of the label.
That will keep all fonts the same size.
n <- 5L
nodes <- data.frame(id = 1:3, label=paste0(strrep(" ",n), 2014:2016,
strrep(" ",n)) ,value=1:3,shape='circle')
edges <- data.frame(from = c(1,2), to = c(1,3))
visNetwork(nodes, edges, width = "100%")
If the length of the labels is not the same you may want to try other criteria.

Resources