Get a vertex in a vertex sequence - r

A vertex sequence by igraph seems not be a sequence. For example:
The v sequence by V( module.net ) is a sequence, since I can access it by [deg==1]. But why it does't work when I try peripheral[1]? Any possible explanation for this?
The dataset for this example is not easy to be included, sorry for that.
//
I find the answer, the index of first vertex 'MED24' is 4, instead of 1. So if I want to get the first vertex, I have to do peripheral[1]. But this seems a little unreasonable. A replicatable example:
g = graph.ring(5)
V(g)$name = c('node1', 'node2', 'node3','node4','node5')
temp = V(g)[2:3]
If you want to access 'node3' from temp, you have to use temp[3] instead of temp[2]

I've always had trouble with vertex sequences and edge sequences. The problem with the indexing operator on those objects is that is searched by vector name, not position. So peripheral[1] is looking to see if vector 1 is in the list, it's not extracting the first element in the list.
The best i've come up with is converting the sequence to a simple vector and re-indexing the vector list. For example
el <- cbind(letters[1:5], letters[c(2,3,5,1,4)])
gg <- graph.edgelist(el)
p <- V(gg)[c(2,3)]
V(gg)[as.vector(p)[1]]
Actually, if you just want to extract the name of a particular vertex, then
p$name[1]
would work.

Related

Delete vertices from a graph with igraph but maintaining their original names

With the following code
library('igraph')
g <- barabasi.game(10,directed=FALSE)
I obtained the graph depicted in the picture:
Suppose I wanted to remove the vertex 1. In this case, I would expect a picture like this:
which I produced manually. But, if I apply the code
g<-delete_vertices(g, 1)
I instead obtain the graph:
where the number of each vertex has been modified. How can I maintain the original number of each vertex?
You can retain names if you explicitly add vertex names prior to the deletion
vertex_attr(g) <- list(name = 1:10)

Create a list where each element is a pair of contiguous members from given vector

Or how to split a vector into pairs of contiguous members and combine them in a list?
Supose you are given the vector
map <-seq(from = 1, to = 20, by = 4)
which is
1 5 9 13 17
My goal is to create the following list
path <- list(c(1,5), c(5,9), c(9,13), c(13,17))
This is supposed to represent the several path segments that the map is sugesting us to follow. In order to go from 1 to 17, we must first take the first path (path[1]), then the second path (path[2]), and all the way to the end.
My first attempt lead me to:
path <- split(aux <- data.frame(S = map[-length(map)], E = map[-1]), row(aux))
But I think it would be possible without creating this auxiliar data frame
and avoiding the performance decrease when the initial vector (the map) is to big. Also, it returns a warning message which is quite alright, but I like to avoid them.
Then I found this here on stackoverflow (not exactly like this, this is the adapted version for my problem):
mod_map <- c(map, map[c(-1,-length(map))])
mod_map <- sort(mod_map)
split(mod_map, ceiling(seq_along(mod_map)/2))
which is a simpler solution, but I have to use this modified version of my map.
Pherhaps I'm asking too much as I already got two solutions. But, could it be possible to have a third one, so that I don't have so use data frames as in my first solution and can use the original map, unlike my second solution?
We can use Map on the vector ('map' - better not to use function names - it is a function from purrr) with 1st and last element removed and concatenate elementwise
Map(c, map[-length(map)], map[-1])
Or as #Sotos mentioned, split can be used which would be faster
split(cbind(map[-length(map)], map[-1]), seq(length(map)-1))

loop through vector in R to delete objects containing pattern above certain limit

Trying to figure out how to loop through a vector and eliminate components containing a particular pattern above a predetermined limit. For example, in the following vector, I might want to keep just the first two instances of both the "a_a_" and "b_b_" components.
x <- c("a_a_a", "a_a_b", "a_a_c", "a_a_d", "b_b_a", "b_b_b", "b_b_c", "b_b_d")
The resulting vector, after the loop deleting extraneous components, would be like this:
x = "a_a_a", "a_a_b", "b_b_a", "b_b_b"
The tricky part is that the code must first detect what is contained in the pattern, then loop through the (extremely long) vector to find all matching patterns, and establish a means of counting instances so that once it hits that given level, it then eliminates all matching components thereafter.
Any help is greatly appreciated.
You can use grep to identify which elements have the patterns and keep only the first two.
patterns = c("a_a", "b_b")
keep = NULL
for(p in patterns) { keep = c(keep, grep(p,x)[1:2]) }
x = x[keep]
x
[1] "a_a_a" "a_a_b" "b_b_a" "b_b_b"

Calculate number of common neighbors in igraph R

Can anyone help me to find the number of common neighbors of two vertices using igraph R.
I tried to get this with following command but it returned with list().
intersect(neighborhood(graph=TD1,order=1,nodes=714),neighborhood(graph=TD1,order=1,nodes=4211))
>>>> list()
Thanks
Anna
neighborhood() returns a list of integer vectors, one for each source node you passed in. Since you only have a single source node, you have to extract the first element of the list that neighborhood() returns before passing them to intersect():
intersect(
neighborhood(graph=TD1, order=1, nodes=714)[[1]],
neighborhood(graph=TD1, order=1, nodes=4211)[[1]]
)

R colon operator on list of matrices

I've created a list of matrices in R. In all matrices in the list, I'd like to "pull out" the collection of matrix elements of a particular index. I was thinking that the colon operator might allow me to implement this in one line. For example, here's an attempt to access the [1,1] elements of all matrices in a list:
myList = list() #list of matrices
myList[[1]] = matrix(1:9, nrow=3, ncol=3, byrow=TRUE) #arbitrary data
myList[[2]] = matrix(2:10, nrow=3, ncol=3, byrow=TRUE)
#I expected the following line to output myList[[1]][1,1], myList[[2]][1,1]
slice = myList[[1:2]][1,1] #prints error: "incorrect number of dimensions"
The final line of the above code throws the error "incorrect number of dimensions."
For reference, here's a working (but less elegant) implementation of what I'm trying to do:
#assume myList has already been created (see the code snippet above)
slice = c()
for(x in 1:2) {
slice = c(slice, myList[[x]][1,1])
}
#this works. slice = [1 2]
Does anyone know how to do the above operation in one line?
Note that my "list of matrices" could be replaced with something else. If someone can suggest an alternative "collection of matrices" data structure that allows me to perform the above operation, then this will be solved.
Perhaps this question is silly...I really would like to have a clean one-line implementation though.
Two things. First, the difference between [ and [[. The relevant sentence from ?'[':
The most important distinction between [, [[ and $ is that the [ can
select more than one element whereas the other two select a single
element.
So you probably want to do myList[1:2]. Second, you can't combine subsetting operations in the way you describe. Once you do myList[1:2] you will get a list of two matrices. A list typically has only one dimension, so doing myList[1:2][1,1] is nonsensical in your case. (See comments for exceptions.)
You might try lapply instead: lapply(myList,'[',1,1).
If your matrices will all have same dimension, you could store them in a 3-dimensional array. That would certainly make indexing and extracting elements easier ...
## One way to get your data into an array
a <- array(c(myList[[1]], myList[[2]]), dim=c(3,3,2))
## Extract the slice containing the upper left element of each matrix
a[1,1,]
# [1] 1 2
This works:
> sapply(myList,"[",1,1)
[1] 1 2
edit: oh, sorry, I see almost the same idea toward the end of an earlier answer. But sapply probably comes closer to what you want, anyway

Resources