I implemented the FR test here and now I would like to test it by means of visualizing the resulting minimum spanning trees in R. The vertices and edges should be plotted in a coordinate system.
Moreover I want to set the color for every dot (depending on to which sample it belongs) and express a possible third dimension through the size of the dots.
This is what I have got so far:
library(ggplot2)
nodes <- data.frame(cbind(c("A", "A", "A", "B", "B", "B"), c(1,2,3,8,2,1), c(6,3,1,4,5,6)))
edges <- data.frame(cbind(c("A", "A", "A"), c("A", "B", "B"), c(1,3,2), c(6,1,5), c(2,8,1), c(3,4,6)))
p <- ggplot() +
geom_point(nodes, aes(x=nodes[,2], y=nodes[,3])) +
geom_line(edges)
p
I also think igraph would be best here...
nodes <- data.frame(a=c("A", "A", "A", "B", "B", "B"), b=c(1,2,3,8,2,1),
d=c(6,3,1,4,5,6))
#cbind made your nodes characters so i have removed it here
edges <- data.frame(a=c("A", "A", "A"), b=c("A", "B", "B"), d=c(1,3,2),
e=c(6,1,5), f=c(2,8,1), g=c(3,4,6))
Here is an example using your data as above, to produce the colours colouring with the coordinate layout system coords
library(igraph)
from <- c(rep(edges[,3],3),rep(edges[,4],2),edges[,5])
to <- c(edges[,4],edges[,5],edges[,6],edges[,5],edges[,6],edges[,6])
myedges <- data.frame(from,to)
actors <- data.frame(acts=c(1,2,3,4,5,6,8))
colouring <- sample(colours(), 7)
sizes <- sample(15,7)
coords<-cbind(x=runif(7,0,1),y=runif(7,0,1))
myg <- graph.data.frame(myedges, vertices=actors, directed=FALSE)
V(myg)$colouring <- colouring
V(myg)$sizes <- sizes
plot(myg,vertex.color=V(myg)$colouring,vertex.size=V(myg)$sizes,
layout=coords,edge.color="#55555533")
for plotting a spanning there are also many options, e.g.
d <- c(1,2,3)
E(myg)$colouring <- "#55555533"
E(myg, path=d)$colouring <- "red"
V(myg)[ d ]$colouring <- "red"
plot(myg,vertex.color=V(myg)$colouring,vertex.size=V(myg)$sizes
,edge.width=3,layout=coords,edge.color=E(myg)$colouring )
with axes:
plot(myg,vertex.color=V(myg)$colouring,vertex.size=V(myg)$sizes
,edge.width=3,layout=coords,edge.color=E(myg)$colouring, axes=TRUE )
and use rescale=FALSE to keep original axes scale
Related
I'm new to using graphs in R, and haven't been able to find a solution to this problem. Take a simple graph
library(igraph)
df <- data.frame(a = c("a","a","a","b","c","f"),
b = c("b","c","e","d","d","e"))
my.graph <- graph.data.frame(df, directed = FALSE)
plot(my.graph)
What I want is to be able to define a function which takes the graph and a set of nodes as arguments and for a logical output as to whether those nodes are connected. For example
my.function(my.graph, c("b", "a", "c"))
# TRUE
my.function(my.graph, c("b", "a", "e"))
# TRUE
my.function(my.graph, c("b", "a", "f"))
# FALSE
Any help appreciated
You are just asking if the induced subgraph is connected, so compute the subgraph and test if it is connected.
my.function = function(g, nodes) {
is_connected(subgraph(g, nodes)) }
my.function(my.graph, c("b", "a", "c"))
[1] TRUE
my.function(my.graph, c("b", "a", "e"))
[1] TRUE
my.function(my.graph, c("b", "a", "f"))
[1] FALSE
I have a massive data file that I am breaking down into day blocks by person and then plotting events that occurred during the day and the duration of those events (either A, B or C)
Data is structured like below: t_z is the interval between rows, period is the event variable, this example is for one individual for one day ( actual data is xdays xpersons)
intervals <- c(0,5.1166667,6.2166667,3.5166667,0.06666667,3.0666667,6.3,
2.3833333,0.06666667,4.7,18.666667,17.383333,21.533333,
0.1,0.08333333,0.85)
period <- c("C", "B", "A", "B", "C", "B", "C", "B",
"C", "B", "C", "B", "C", "B", "C", "B")
i <- as.data.frame(intervals)
p <- as.data.frame(period)
d <- cbind(i,p)
Getting a bar plot is easy enough but it stacks all "periods" into blocks by day:
d$id<-1
e <- ggplot(d,aes(id))
e + geom_bar(aes(fill=period))
Simple aggregated stacked bar of time data:
However, I would like each "period" to be represented discretely and by its magnitude:
Periods as discrete stacked blocks example:
Thanks YBS but your method comes close but the size of the periods is not correct any ideas? The first C=5 is not the same size as the first A=5?
intervals <- c(5, 15, 5, 3,7,3,6, 2)
period <- c("C","B","A","B","C","B","C","B")
d <- data.frame(intervals,period)
colors=c("red","blue","green")
dc <- data.frame(period=unique(d$period),colors)
d2 <- d %>% mutate(nid = paste0(d$period,'_',row_number()))
d3 <- left_join(d2,dc, by="period")
d3$id<-1
e <- ggplot(d3,aes(x=id, y=intervals)) +
geom_col(aes(fill=nid))
e + scale_fill_manual(name='period', labels=d3$period, values=d3$colors )
The trick is to create a newid with all the discrete values, and then reverting back to initial period values via scale_fill_manual. You can use coord_flip() to make it horizontal and change the legend position as necessary. Perhaps this is the desired output.
intervals <- c(0, 5.1166667, 6.2166667, 3.5166667,0.6666667,3.0666667,6.3, 2.3833333)
#,0.06666667 , 4.7,18.666667,17.383333,21.533333, 0.1,0.08333333,0.85)
period <- c("C", "B", "A", "B", "C", "B", "C", "B")
# ,"C", "B", "C", "B", "C", "B", "C", "B")
d <- data.frame(intervals,period)
colors=c("red", "blue","green")
dc <- data.frame(period=unique(d$period),colors)
d2 <- d %>% mutate(nid = paste0(d$period,'_',row_number()))
d3 <- left_join(d2,dc, by="period")
d3$id<-1
e <- ggplot(d3,aes(x=id, y=intervals)) +
geom_col(aes(fill=nid))
e + scale_fill_manual(name='period', labels=d3$period, values=d3$colors )
I'd like to color the nodes of a graph based on an attribute in the original dataframe. But I think I haven't "carried through" that aestetic variable to the graph.
Example here that works:
library(dplyr)
library(igraph)
library(ggraph)
data <-
tibble(
from = c("a", "a", "a", "b", "b", "c"),
to = c(1, 2, 3, 1, 4, 2),
type = c("X", "Y", "Y", "X", "Y", "X")
)
graph <-
graph_from_data_frame(data)
ggraph(graph,
layout = "fr") +
geom_node_point() +
geom_edge_link()
I'd like something like geom_node_point(aes(color = type)), but haven't made type findable in the graph?
The issue here is that you added the type column as an edge-attribute whereas geom_node_point expects a vertex-attribute (see ?graph_from_data_frame: Additional columns are considered as edge attributes.).
Another issue is that type is not consistent for either node column (e.g. a is associated with type X and also Y, the same is true for node 2).
To address the first issue you could add additional vertex information to the vertices argument of the graph_from_data_frame function.
The simplest solution to address both issues is to add the type attribute after creating the graph:
data <-
tibble(
from = c("a", "a", "a", "b", "b", "c"),
to = c(1, 2, 3, 1, 4, 2)
)
graph <- graph_from_data_frame(data)
V(graph)$type <- bipartite.mapping(graph)$type
The bipartite.mapping function adds either TRUE or FALSE consistently to each vertex of different type.
I have data which provides information on flows by actor c, broken down by inputs originating from source s, to partner p.
Network data normally has only one information: Data / Information flows from A->B, B->C etc.
However, my data shows which flows from A->B then goes to C, and which from A->B goes to D.
The data is structured as a three-column edgelist.
source <- c("A", "D", "B", "B")
country <- c("B", "B", "A", "A")
partner <- c("C", "C", "C", "D")
value <- c("5", "0", "2", "4")
df <- data.frame(source, country, partner, value)
df
I kinda dont see how it would be possible to use this as network data - however, if anyone got an idea on how to use that way more fine-grained network that be amazing ((:
best,
moritz
Maybe like this:
library(igraph)
g <- graph_from_data_frame(
rbind(
setNames(df[, c(1, 2, 4)], c("from", "to", "value")),
setNames(df[, c(1, 3, 4)], c("from", "to", "value"))
)
)
plot(g)
I am not sure if the code below is what you want
library(igraph)
v <- c(3,1)
g <- Reduce(union,lapply(v, function(k) graph_from_data_frame(df[-k])))
such that plot(g) gives
I am trying to colour node 6 and 7 regardless of whatever letter is selected from object 'd'.
g <- graph_from_literal(1:2:3:4:5 -- 6:7)
# Rename (sum up all the vertices)
d <- c("a", "b", "c", "d", "e", "f", "g","h", "i", "j")
V(g)$name <- sample(d, 7, replace=TRUE)
colours <- c("red")
V(g)$color <- ifelse(V(g)$name == c('a','e'), "white", colours)
plot.igraph(g, layout=layout_with_dh, vertex.label=V(g)$name,
vertex.size=35,
vertex.color=V(g)$color, #colors.r
vertex.label.cex=0.7,
)
I tried the ifelse() above but they don't seem to take numerical value. I would appreciate some help please.
What I want is that node 6 is e.g. white and 7 is e.g. green and the rest of the other nodes are red.
Thank you!
You could do
V(g)$color <- "red"
V(g)$color[6] <- "white"
V(g)$color[7] <- "green"
You can also do:
V(g)["nameofnode"]$color<-"red"