it looks like source/target is not zero indexed networkd3 [duplicate] - r

This question already has an answer here:
forceNetwork is not zero indexed
(1 answer)
Closed 5 years ago.
I am trying to make an interactive website traffic diagram using web traffic data.
Using networkd3 packages.
It is just a simpleNetwork, however keeps giving me this warning and force closes RStudio.
library(networkD3)
simpleNetwork(data.frame(BWT2012$Visitors, 1:189157, fontSize = 16, nodeColour = "blue", nodeClickColour = "red", textColour = "black", opacity = 0.6, zoom = T))
Warning Message: It looks like Source/Target is not zero-indexed. This
is required in Javascript and so your plot may not render.
I have been researching for hours however cannot seem to find how this works. I understand that javascript reads from 0 and r from 1. That is why it is not working.

it is very difficult for anyone to help you because you haven't provided a reproducible example, i.e. we have no idea what your data frame BWT2012 looks like
there seems to be a bug in your code... data.frame(BWT2012$Visitors, 1:189157, fontSize = 16, nodeColour = "blue", nodeClickColour = "red", textColour = "black", opacity = 0.6, zoom = T) will not work no matter what BWT2012 looks like because you're passing elements to the data.frame function that are of different lengths. I suspect you meant for it to be simpleNetwork(data.frame(BWT2012$Visitors, 1:189157), fontSize = 16, nodeColour = "blue", nodeClickColour = "red", textColour = "black", opacity = 0.6, zoom = T), where the first argument of the simpleNetwork() function is a complete data.frame() with BWT2012$Visitors as its first argument and 1:189157 as its second argument, i.e. you intend to pass to the simpleNetwork() function a data frame that has the first column/variable equal to BWT2012$Visitors and the second column equal to 1:189157
Assuming #2 above is correct, the data frame you are trying to pass is telling simpleNetwork that the values in BWT2012$Visitors are the sources of each link, and the values in 1:189157 are the targets of each link. That seems like a very unlikely scenario, so I would make sure you're getting what you think you're getting.
The warning you mention is just a warning... it will not stop the function from running. In many (maybe all since recent changes in networkd3) cases it will still plot the graph, though the results might be unexpected. For instance...
Source <- c(1, 1, 2)
Target <- c(2, 3, 3)
NetworkData <- data.frame(Source, Target)
simpleNetwork(NetworkData)
Using the example from #4, if you wanted to renumber your source and target ids so that they were 0-indexed and avoid the warning, you could do...
Source <- c(1, 1, 2)
Target <- c(2, 3, 3)
Source <- Source - 1
Target <- Target - 1
NetworkData <- data.frame(Source, Target)
simpleNetwork(NetworkData)

Related

R: automatically assigning all colors

I am working with the R programming language. I have this data:
letters = replicate(52, paste(sample(LETTERS, 10, replace=TRUE), collapse=""))
values = rnorm(52, 100, 100)
my_data = data.frame(letters, values)
I am trying to plot this data:
library(ggplot2)
library(waffle)
waffle(my_data, size = 0.6, rows = 10)
But this gives me the error:
! Insufficient values in manual scale. 51 needed but only 8 provided.
Run `rlang::last_error()` to see where the error occurred.
Normally, I would have manually provided the colors - but 51 colors are a lot to insert manually. Is there some automatic way that can recognize how many colors are required and then fill them all in?
Thanks!
You can use a vector of 53 colors using a palette function such as scales::hue_pal()(53) (note I have had to alter the way the input data is used, since your unmodified example data and code simply returns an error)
waffle(setNames(abs(round(my_data$values/10)),
my_data$letters), size = 0.6, rows = 10,
colors = scales::hue_pal()(53)) +
theme(legend.position = "bottom")
The obvious caveat is that 53 discrete colors is far too many to have in a waffle plot. It is simply unintelligible from a data visualisation point of view. Whatever you are trying to demonstrate, there will certainly be a better way to do it than a waffle chart with 53 discrete colors.

Cellular Automaton in R - disappearing states change color in levelplot

Good afternoon everyone!
Currently working on a cellular automaton in R (modelling of an epidemic applied to invasive species). Cells can be in 4 different states: 0, 1, 2, 3. So far I've made a plot (using levelplot) of the matrix, and watch it change for a fixed number of steps (according to a set rule and the number of each type of neighbours).
Code is as follows (the entire script is not shown):
matriu # matrix with cells in either state (0,1,2,3)
colors <- colorRampPalette(c("green", "red", "white", "blue"))
graph <- levelplot(matriu, col.regions = colors, cuts = 3)
print(graph)
As the automaton changes step by step, it is possible to lose 1 or 2 states. This means the matrix can transition from having states (0,1,2,3) to having states (0,1,2) or (1,2).
I've tried to embed a couple of images of the coloured matrix with 4 states vs. 3 states, but since it's first I'm posting a question here, appareantly they'll show up as image (hope it works!).
Levelplot with 4 states:
Levelplot with 3 states:
When the 4 states are present, state 2 is shown as white, but when only 3 states remain (second picture), state 2 is shown as blue.
My question is: how to prevent to colors from shifting, in the event that one or more states disappear?
I'm just starting to learn to code using R, so this page has been very useful lately. Thanks to all of you that keep this place alive!
Use the at argument for levelplot. For example:
library(lattice)
set.seed(123)
matriu <- matrix(sample(0:3, 100, replace = TRUE), nc = 10)
colors <- colorRampPalette(c("green", "red", "white", "blue"))
graph <- levelplot(matriu, col.regions = colors, at = c(-.1, .5:2.5, 3.1))
graph
matriu <- matrix(sample(1:2, 100, replace = TRUE), nc = 10)
graph <- levelplot(matriu, col.regions = colors, at = c(-.1, .5:2.5, 3.1))
graph
P.s. Welcome to SO -- please try to provide a minimal working example (e.g. some fake data for matriu) with your question.

How can I change the vertex color when plotting a network using igraph depending on specific actor attribute?

I am estimating networks with ERGMs using the statnet suite in R. I would like to visualize the network using the igraph package with size by degree centrality and node color by leadership position. For explanation: it's a shared leadership network and I want to visualize whether an individual has a formal leadership position (LSPosition = 1), visualized in black, or not (LSPosition = 0), visualized in white.
This is my code up to now (graphExample is my network, Data_Axample is an actor attribute data set):
library(igraph)
degreeExample <- centralization.degree(graphExample)$res
V(graphExample)$size <- degreeExample
V(graphExample)$LSPosition <- Data_Example$LSPosition
colrs <- colors(c("black","white"))
V(graphExample)$color <- colrs[V(graphExample)$LSPosition]
E(graphExample)$arrow.size <- 0.5
plot(graphExample, vertex.label = NA, vertex.label.family = "Arial")
legend("bottomleft", c("Employee in no leading position",
"Employee in a leading position"),
pch = 21, col = "#777777", pt.bg = colrs, pt.cex = 2, cex = 0.8, bty = "n", ncol = 1)
The problem is, that for colrs <- colors(c("black","white")) I get the following error:
Error in if (distinct) c[!duplicated(t(col2rgb(c)))] else c :
argument is not interpretable as logical
In addition: Warning message: In if (distinct) c[!duplicated(t(col2rgb(c)))] else c :
the condition has length > 1 and only the first element will be used
I also tried the following:
V(graphExample)$color <- ifelse(V(graphExample)$LSPosition==1, "black", ifelse(V(graphExample)$LSPosition==0, "white"))
But I get the error:
Error in ifelse(V(graphSLO_V1)$PositionO == 0, "white") :
argument "no" is missing, with no default.
How can I set the colors?
There are two problems here. First, the colors function lists all of the available colors by name. I think that you are just trying to get a list with the colors "black" and "white. That is simpler than what you tried. All you need is colrs <- c("black","white") . But according to your description, V(graphExample)$LSPosition will have values of either 0 or 1. The list colrs should be indexed by 1 or 2. The simple thing to do would be to simply shift the indices by using
V(graphExample)$color <- colrs[V(graphExample)$LSPosition + 1]
But that will make (LSPosition = 0) be black (you wanted white) and (LSPosition = 1) be white (you wanted black). So I would use the line with the +1 as above, but change the definition of colrs to colrs <- c("white", "black")

R Circular Chord Plots

Im learning how to create circular plots in R, similiar to CIRCOS
Im using the package circlize to draw links between origin and destination pairs based on if the flight was OB, Inbound and Return. The logic fo the data doesnt really matter, its just a toy example
I have gotten the plot to work based on the code below which works based on the following logic
Take my data, combine destination column with the flight type
Convert to a matrix and feed the origin and the new column into circlize
Reference
library(dplyr)
library(circlize)
# Create Fake Flight Information in a table
orig = c("IE","GB","US","ES","FI","US","IE","IE","GB")
dest = c("FI","FI","ES","ES","US","US","FI","US","IE")
direc = c("IB","OB","RETURN","DOM","OB","DOM","IB","RETURN","IB")
mydf = data.frame(orig, dest, direc)
# Add a column that combines the dest and direction together
mydf <- mydf %>%
mutate(key = paste(dest,direc)) %>%
select (orig, key)
# Create a Binary Matrix Based on mydf
mymat <- data.matrix(as.data.frame.matrix(table(mydf)))
# create the objects you want to link from to in your diagram
from <- rownames(mymat)
to <- colnames(mymat)
# Create Diagram by suppling the matrix
par(mar = c(1, 1, 1, 1))
chordDiagram(mymat, order = sort(union(from, to)), directional = TRUE)
circos.clear()
I like the plot a lot but would like to change it a little bit. For example FI (which is Finland) has 3 measurements on the diagram FI IB, FI OB and FI. I would like to combine them all under FI if possible and distinguish between the three Types of flights using either a colour scheme, Arrows or even adding an additional track which acts as an umbrella for IB OB and RETURN flights
So for Example,
FI OB would be placed in FI but have a one way arrow to GB to signify OB
FI IB would be placed in FI but have a one way arrow into FI
FI RETURN (if it exists) would have a double headed arrow
Can anyone help, Has anyone seen anything similiar been done before?
The end result should just have the countries on the plot once so that someone can see very quickly which countries have the most amount of flights
I have tried following other posts but am afraid im getting lost when they move to the more advanced stuff
Thank you very much for your time
First, I think there is a duplicated record (IE-FI-IB) in your data.
I will first attach the code and figure and then explain a little bit.
df = data.frame(orig, dest, direc, stringsAsFactors = FALSE)
df = unique(df)
col = c("IB" = "red",
"OB" = "blue",
"RETURN" = "orange",
"DOM" = "green")
directional = c("IB" = -1,
"OB" = 1,
"RETURN" = 2,
"DOM" = 0)
diffHeight = c("IB" = -0.04,
"OB" = 0.04,
"RETURN" = 0,
"DOM" = 0)
chordDiagram(df[1:2], col = col[df[[3]]], directional = directional[df[[3]]],
direction.type = c("arrows+diffHeight"),
diffHeight = diffHeight[df[[3]]])
legend("bottomleft", pch = 15, legend = names(col), col = col)
First you need to use the development version of circlize for which
you can install it by
devtools::install_github("jokergoo/circlize")
In this new version, chordDiagram() supports input variable as a data frame and drawing two-head arrows for the links (just after reading your post :)).
In above code, col, directional, direction.type and diffHeight can all be set as a vector which corresponds to rows in df.
When directional argument in chordDiagram() is set to 2, the corresponding link will have two directions. Then if direction.type contains arrows, there will be a two-head arrow.
Since diffHeight is a vector which correspond to rows in df, if you want to visualize the direction for a single link both by arrow and offset of the roots, you need to merge these two options as a single string as shown in the example code "arrows+diffHeight".
By default direction for links are from the first column to the second column. But in your case, IB means the reversed direction, so we need to set diffHeight to a negative value to reverse the default direction.
Finally, I observe you have links which start and end in a same sector (ES-ES-DOM and US-US-DOM), you can use self.link argument to control how to represent such self-link. self.link is set to 1 in following figure.
Do you need the arrows because the color coding in the graph is telling the From / To story already (FROM -> color edge FROM COUNTRY, TO is color of the FROM COUNTRY arriving at the TO COUNTRY, IF FROM == TO Its own color returns at its own base (see US or ES for example)).
library(dplyr)
library(circlize)
# Create Fake Flight Information in a table
orig = c("IE","GB","US","ES","FI","US","IE","IE","GB")
dest = c("FI","FI","ES","ES","US","US","FI","US","IE")
mydf = data.frame(orig, dest)
# Create a Binary Matrix Based on mydf
mymat <- data.matrix(as.data.frame.matrix(table(mydf)))
# create the objects you want to link from to in your diagram
from <- rownames(mymat)
to <- colnames(mymat)
# Create Diagram by suppling the matrix
par(mar = c(1, 1, 1, 1))
chordDiagram(mymat, order = sort(union(from, to)), directional = TRUE)
circos.clear()
BY the way -> there is also a OFFSET difference on the edge that tells if it is FROM (wider edge) or TO (smaller edge)

Problems with pheatmap usage

I'm trying to play around with pheatmap and getting stuck at the very beginning.
Creating a toy example:
library(pheatmap)
set.seed(1)
my.mat <- matrix(rnorm(90), nrow = 30, ncol = 30)
rownames(my.mat) <- 1:30
colnames(my.mat) <- 1:30
col.scale = colorRampPalette(c("red", "blue"), space = "rgb")(10)
breaks.size = 11
pheatmap(my.mat, color = col.scale, breaks = breaks.size, border_color = NA, cellwidth = 10, cellheight = 10)
Throws this error message:
Error in unit(y, default.units) : 'x' and 'units' must have length > 0
And the plot it produces doesn't seem right:
For example, I can't understand why the top right cells are white. i also thought the setting cellwidth = 10 and cellheight = 10 means getting square cells and not rectangular. And finally, if anyone knows if it's possible to have the row names and col names apear on the same side of the heat map as the dendograms (i.e., at the tips of the dendogram), that'll be great.
Well, the reason you are getting that error is that you are using the breaks= parameter incorrectly. From the ?pheatmap help page
breaks: a sequence of numbers that covers the range of values in mat and is one element longer than color vector. Used for mapping values to colors. Useful, if needed to map certain values to certain colors, to certain values. If value is NA then the breaks are calculated automatically.
You can't just pass a single value like you might with other functions.
Also i'm not sure what you are saying about the cells not being square. You are plotting a 30x30 square shape (at least it is for me). Because you are clustering, you're only getting one color per cluster.
I'm guessing part of the problem may be you're only generating 90 random variables for a 900 cell matrix so those values are repeating (your data is very structured). Perhaps you meant
my.mat <- matrix(rnorm(900), nrow = 30, ncol = 30)
doing so gives you the following plot

Resources