Setting subgraph/cluster attributes in Rgraphviz - r

I want to plot a graph via Rgraphviz but I can't handle the design attributes of the clusters that I set.
There are similar questions already on SO and elsewhere but none has a real minimal working example and none of them is answered. So I want to try to ask a complete question to receive a complete answer. As an introduction to the package, I read the paper "How To Plot A Graph Using Rgraphviz" by Gentry, Gentleman, and Huber.
My example network:
library(Rgraphviz)
set.seed(123)
V <- letters[1:6]
M <- 1:4
g1 <- randomGraph(V, M, 0.2)
If I want to plot it, I can easily give it some attributes via a list:
attributes <- list(node = list(shape = "rectangle", fixedsize = FALSE),
graph = list(layout = "dot", bgcolor = "transparent"))
plot(g1, attrs = attributes )
Plotting it via plot(g1) gives the following result:
Now I want to define two clusters/subgraphs. This can be done this way:
sg1= subGraph(c("a", "e", "f"), g1)
sg2= subGraph(c("b", "c", "d"), g1)
subGList <- vector(mode = "list", length = 2)
subGList[[1]] <- list(graph = sg1, cluster = TRUE)
subGList[[2]] <- list(graph = sg2, cluster = TRUE)
Plotting the graph again now including a subGlist argument:
plot(g1, attrs = attributes , subGList = subGList)
So, obviously, there has been a change in the setting and even though it would be convenient having the clusters a little bit more separated, the result is ok.
Now if I want to define cluster-specific styles or try to have them framed, I start having problems. According to page 4 of the mentioned introductory paper one can simply add an element called attrs to the sublists of subGlist.
To my understanding, it should work this way:
subGList[[1]] <- list(graph = sg1,
cluster = TRUE,
attrs = c(fontcolor = "red"))
plot(g1, attrs = attrs, subGList = subGList)
Unfortunately, it doesn't. As mentioned, I would like to frame my clusters (similar to this SO post) but as I can't even handle the fontcolors of the clusters, I think I make a somehow more fundamental mistake.
My complete code:
library(Rgraphviz)
set.seed(123)
V <- letters[1:6]
M <- 1:4
g1 <- randomGraph(V, M, 0.2)
attributes <- list(node = list(shape = "rectangle", fixedsize = FALSE),
graph = list(layout = "dot", bgcolor = "transparent"))
#plot(g1, attrs = attributes )
sg1= subGraph(c("a", "e", "f"), g1)
sg2= subGraph(c("b", "c", "d"), g1)
subGList <- vector(mode = "list", length = 2)
subGList[[1]] <- list(graph = sg1, cluster = TRUE)
subGList[[2]] <- list(graph = sg2, cluster = TRUE)
#plot(g1, attrs = attributes , subGList = subGList)
subGList[[1]] <- list(graph = sg1,
cluster = TRUE,
attrs = c(fontcolor = "red"))
plot(g1, attrs = attrs, subGList = subGList)
I hope someone can help! Thank you

Related

R igraph cluster nodes with the same colour (feature)

# example data
library(igraph)
links <- cbind.data.frame(from = rep("A", 6),
to = LETTERS[1:6],
weight = rep((1:3), each =2))
nodes <- nodes <- cbind.data.frame(id = LETTERS[1:6],
feature = rep((1:3), each =2))
net <- graph_from_data_frame(d = links, vertices = nodes, directed = T)
V(net)$color <- V(net)$feature
plot(net, vertex.size=30, edge.arrow.size = 0)
This is what I get:
What I want is to cluster the same colored nodes together, something similar as shown in the figure below. How can I do it?
Maybe the option mark.groups in plot could help
plot(net,mark.groups = split(V(net)$name,V(net)$color))
which gives

How to shorten code for "visRemoveNodes" using loop in rstudio

I have constructed multiple protein - protein networks for diseases in shiny app and I ploted them using visnetwork. I found the articulation points for each network and I want to remove them.
My code for a disease looks like this:
output$plot54 <- renderVisNetwork({
alsex <- as.matrix(alsex)
sel1 <- alsex[,1]
sel2 <- alsex[,2]
n10 <- unique(c(sel1,sel2))
n10 <- as.data.frame(n10)
colnames(n10) <- "id"
ed10 <- as.data.frame(alsex)
colnames(ed10) <- c("from", "to", "width")
n10
g <- graph_from_data_frame(ed10)
articulation.points(g)
nodes4 <- data.frame(n10, color = ifelse(n10$id=="CLEC4E"|n10$id=="ACE2"|n10$id=="MYO7A"|n10$id=="HSPB4"
|n10$id=="EXOSC3"|n10$id=="RBM45"|n10$id=="SPAST"|n10$id=="ALMS1"|n10$id=="PIGQ"
|n10$id=="CDC27"|n10$id=="GFM1"|n10$id=="UTRN"|n10$id=="RAB7B"|n10$id=="GSN"|n10$id=="VAPA"|n10$id=="GLE1"
|n10$id=="FA2H"|n10$id=="HSPA4"|n10$id=="SNCA"|n10$id=="RAB5A"|n10$id=="SETX","red","blue"))
visNetwork(nodes4, ed10, main = "Articulation Points") %>%
visNodes (color = list(highlight = "pink"))%>%
visIgraphLayout()%>%
visOptions(highlightNearest = list(enabled = T, hover = T),
nodesIdSelection = T)%>%
visInteraction(keyboard = TRUE)
})
observe({
input$delete54
visNetworkProxy("plot54") %>%
visRemoveNodes(id="CLEC4E")%>%visRemoveEdges(id = "CLEC4E")%>%
visRemoveNodes(id="ACE2")%>%visRemoveEdges(id = "ACE2")%>%
visRemoveNodes(id="MYO7A")%>%visRemoveEdges(id = "MYO7A")%>%
visRemoveNodes(id="HSPB4")%>%visRemoveEdges(id = "HSPB4")%>%
visRemoveNodes(id="EXOSC3")%>%visRemoveEdges(id = "EXOSC3")%>%
visRemoveNodes(id="RBM45")%>%visRemoveEdges(id = "RBM45")%>%
visRemoveNodes(id="SPAST")%>%visRemoveEdges(id = "SPAST")%>%
visRemoveNodes(id="ALMS1")%>%visRemoveEdges(id = "ALMS1")%>%
visRemoveNodes(id="PIGQ")%>%visRemoveEdges(id = "PIGQ")%>%
visRemoveNodes(id="CDC27")%>%visRemoveEdges(id = "CDC27")%>%
visRemoveNodes(id="GFM1")%>%visRemoveEdges(id = "GFM1")%>%
visRemoveNodes(id="UTRN")%>%visRemoveEdges(id = "UTRN")%>%
visRemoveNodes(id="RAB7B")%>%visRemoveEdges(id = "RAB7B")%>%
visRemoveNodes(id="GSN")%>%visRemoveEdges(id = "GSN")%>%
visRemoveNodes(id="VAPA")%>%visRemoveEdges(id = "VAPA")%>%
visRemoveNodes(id="GLE1")%>%visRemoveEdges(id = "GLE1")%>%
visRemoveNodes(id="FA2H")%>%visRemoveEdges(id = "FA2H")%>%
visRemoveNodes(id="HSPA4")%>%visRemoveEdges(id = "HSPA4")%>%
visRemoveNodes(id="SNCA")%>%visRemoveEdges(id = "SNCA")%>%
visRemoveNodes(id="RAB5A")%>%visRemoveEdges(id = "RAB5A")%>%
visRemoveNodes(id="SETX")%>%visRemoveEdges(id = "SETX")
})
Using
g <- graph_from_data_frame(ed10)
articulation.points(g)
I found the articulation points, and I marked them with red color using ifelse as you can see in nodes4 vector.
My questions:
How to shorten my code in ifelse using loop, so I don't have to write the articullation points one by one manually.
How to shorten my code in visRemoveNodes and visRemoveEdges using loop, so I don't have to write them one by one manually as well.
Crossed posted at:
https://community.rstudio.com/t/how-to-shorten-code-for-visremovenodes-using-loop/72506
The answer for the second question is:
observe({
l <- c("CLEC4E","ACE2", "MYO7A", "HSPB4", "EXOSC3", "RBM45","SPAST","ALMS1",
"PIGQ","CDC27","GFM1","UTRN",
"RAB7B", "GSN", "VAPA", "GLE1","FA2H","HSPA4",
"SNCA","RAB5A","SETX") #we put all genes that we want to delete in a vector
for (i in l){
input$delete54
visNetworkProxy("plot54")%>%
visRemoveNodes(id= i)%>%visRemoveEdges(id = i)
}
})

saving and naming files in R automatically based on input filename

I have generated several Utilisation Distributions (UD) with AdehabitatHR and stored them as Geotiffs. I am now using the same UDs with the Lattice package to generate some maps and saving them to a high-res tiff image with LZW compression. Problem is that I have literally hundreds of maps to make, save and name. Is there a way automatically do this once i have loaded all the necessary files from a directory? Each one of my UDs has the following structure of the filename "UD_resolution_species_area_year_season. tif" and in the final name I give to my map I would like to keep the same structure (or entire filename) but add the prefix "blablabla_" e.g. "blablabla_UD_resolution_species_area_year_season.tiff". The image also include a main name, a capital letter, which should also change.
At the moment I am using the following:
rlist = list.files(getwd(), pattern = "tif$", full.names = FALSE)
for (i in rlist) {
assign(unlist(strsplit(i, "[.]"))[1], raster(i))
}
shplist = list.files(getwd(), pattern = "shp$", full.names = FALSE)
for (i in shplist) {
assign(unlist(strsplit(i, "[.]"))[1], readOGR(i))
}
UD <- 'UD_resolution_species_area_year_season'
ext <- extent(UD) + 0.3 # set the extent for the plot
aa <-
quantile(UD,
probs = c(0.25, 0.75),
type = 8,
names = TRUE)
my.at <- c(aa[1], aa[2])
my.at <- round(my.at, 3)
maxval <- maxValue(UD)
tiff(
"C:/myworkingdirectory/maps/blablabla_UD_resolution_species_area_year_season.tiff",
res = 600,
compression = "lzw",
width = 15,
height = 15,
units = "cm"
)
levelplot(
UD,
xlab = "",
ylab = "",
xlim = c(ext[1], ext[2]),
ylim = c(ext[3], ext[4]),
margin = FALSE,
contour = FALSE,
col.regions = viridis(1000),
colorkey = list(at = seq(0, maxval)),
main = "A",
maxpixels = 2e5
) + latticeExtra::layer(sp.polygons(Land, fill = "grey50", col = NA)) + contourplot(
`UD`,
at = my.at[1],
labels = FALSE,
margin = FALSE,
lty = 2,
col = "orange",
pretty = TRUE
) + contourplot(
UD,
at = my.at[2],
labels = FALSE,
margin = FALSE,
lty = 2,
col = "red",
pretty = TRUE,
)
dev.off()
It is a common beginners mistake to use assign. Do not use it, it creates the type of trouble you are now facing. In stead, you can make lists and/or use a loop.
Also what you are asking is basic R stuff, but you are complicating the question with adding lots of irrelevant detail about setting the extent, and levelplot. It is better to learn about doing these basic things by removing the clutter and focus on a simple case first. That is also how you should write questions for this forum.
In essence you have a bunch of files you want to process. Below I show how you can loop over a vector of the names and then loop and do what you need to do in that loop.
library(raster)
rastfiles <- list.files(pattern = "tif$", full.names=TRUE)
outputfiles <- file.path("output/path", paste0("prefix_", basename(rastfiles)))
for (i in 1:length(rastfiles))
r <- raster(rastfiles[i])
png(outputfiles[i])
plot(r)
dev.off()
}
You can also first read all the files into a list
rastfiles <- list.files(pattern = "tif$", full.names=TRUE)
rlist <- lapply(rastfiles, raster)
names(rlist) <- gsub(".tif$", "", basename(rastfiles))
rastfiles <- list.files(pattern = "shp$", full.names=TRUE)
slist <- lapply(shpfiles, readOGR)
names(slist) <- gsub(".shp$", "", basename(shpfiles))
And perhaps create a vector of output filenames
outputtif <- file.path("output/dir", basename(rastfiles))
And then loop over the items in the list, or the output filenames

plotly Sankey diagram: Can I make 4 or more links between two nodes?

I created a Sankey diagram using the plotly package.
Please look at below example. I tried to make five streams, 1_6_7, 2_6_7, and so on. But two of five links between 6 and 7 disappeared. As far as I see, plotly allows to make only three or less links between two nodes.
Can I remove this restrictions ? Any help would be greatly appreciated.
Here is an example code and the outputs:
d <- expand.grid(1:5, 6, 7)
node_label <- 1:max(d)
node_colour <- scales::alpha(RColorBrewer::brewer.pal(7, "Set2"), 0.8)
link_source_nodeind <- c(d[,1], d[,2]) - 1
link_target_nodeind <- c(d[,2], d[,3]) - 1
link_value <- rep(100, nrow(d) * 2)
link_label <- rep(paste(d[,1], d[,2], d[,3], sep = "_"), 2)
link_colour <- rep(scales::alpha(RColorBrewer::brewer.pal(5, "Set2"), 0.2), 2)
p <- plotly::plot_ly(type = "sankey",
domain = c(x = c(0,1), y = c(0,1)),
orientation = "h",
node = list(label = node_label,
color = node_colour),
link = list(source = link_source_nodeind,
target = link_target_nodeind,
value = link_value,
label = link_label,
color = link_colour))
p

Printing Venn Diagram after calculating overlap

I'm trying to use the calculate.overlap function within the VennDiagram package to first calculate and then print a Venn Diagram. I was able to calculate the overlap of my data set but looking for help how to print the Venn graphic. Can anyone provide assistance? I read through the documentation but didn't find this.
> library('VennDiagram')
# A simple single-set diagram
cardiome <- letters[1:10]
superset <- letters[8:24]
overlap <- calculate.overlap(
x = list(
"Cardiome" = cardiome,
"SuperSet" = superset
)
);
Another simple example that shows how to print a Venn diagram using the VennDiagram package:
library(VennDiagram)
cardiome <- letters[1:10]
superset <- letters[8:24]
overlap <- calculate.overlap(
x <- list("Cardiome"=cardiome, "SuperSet"=superset))
venn.plot <- draw.pairwise.venn(
area1 = length(cardiome),
area2 = length(superset),
cross.area = length(overlap),
category = c("Cardiome", "Superset"),
fill = c("blue", "red"),
lty = "blank",
cex = 2,
cat.cex = 2,
cat.pos = c(180, 180),
cat.dist = 0.05,
cat.just = list(c(0, 1), c(1, 1))
)
grid.draw(venn.plot)
savePlot(filename="venndiag", type="png")
Venn diagrams with item labels inside the sets:
library(RAM)
vectors <- list(Cardiome=cardiome, Superset=superset)
group.venn(vectors=vectors, label=TRUE,
fill = c("blue", "red"),
cat.pos = c(180, 180),
lab.cex=1.1)
The funtion venn.diagram() does it. For instance in your example
venn.diagram(x = list(
"Cardiome" = cardiome,
"SuperSet" = superset
), "plot_venn")
It saves to working directory. Type getwd() to see what it is set to.
See the
?venn.diagram()
for more info.
?venn.diagram suggests this
library('VennDiagram')
venn.plot <- venn.diagram(
x = list(
cardiome = letters[1:10],
superset = letters[8:24]
),
filename = NULL
);
grid.draw(venn.plot);

Resources