0

g is an igraph object. I wish to find the cliques (mylist), and then convert this large list object to a dataframe object. i.e. one column with the clique number, another column with the members of this clique.

mylist = maximal.cliques(g)

# error here when converting to dataframe 
cliques_df = mylist %>% 
   map_df(as_tibble)

However, the code produces the error: Error in as.data.frame.default(value, stringsAsFactors = FALSE) : cannot coerce class ‘"igraph.vs"’ to a data.frame

EDIT:

Running vertex_attr_names(g) produces "NodeID" (so NodeID is the node attribute).

However, my g (igraph object) does not seem to have the NodeID displayed as attribute. Is this normal?

g

Link to data file: https://drive.google.com/drive/folders/14eiJhW499lMM5BKaU4Qau-B7ieZCrSKx?usp=sharing

Grace
  • 201
  • 2
  • 13
  • Maybe this post helps? [igraph.vs into a dataframe](https://stackoverflow.com/questions/45068457/turning-an-igraph-vs-into-a-data-frame) – Tim-TU Jul 06 '20 at 11:18
  • I tried that but did not work, gave the error 'not a graph object'. Not sure but it could be because g is igraph.vs object, but after using maximal.cliques(), it is a large list object - which I wish to convert to a dataframe. – Grace Jul 06 '20 at 11:21
  • Then please give us a reproducible example to take a closer look at it. – Tim-TU Jul 06 '20 at 11:24
  • It seems like if I type `dput()`, the list object is too long to copy the reproducible code here. Is there a workaround? – Grace Jul 06 '20 at 12:47

1 Answers1

1

UPDATE: In the attached example you have the clique numbers and clique members in a dataframe. When you are using maximal.cliques(g) the attribute name is kept, but attribute PaperID seems to be dropped. You have to do the following assignment for the attribute name: V(g)$name <- NodeIds and use attributes(x)$name in the second sapply. Take a closer look to the working example attached. I've stated the problem.

library(igraph)
#> 
#> Attache Paket: 'igraph'
#> The following objects are masked from 'package:stats':
#> 
#>     decompose, spectrum
#> The following object is masked from 'package:base':
#> 
#>     union


g <- sample_gnp(100, 0.3)
NodeIds <- paste("A", 1:100, sep =":")
V(g)$name <- NodeIds
V(g)$PaperID <- NodeIds
mylist <- maximal.cliques(g)


clique_number <- sapply(mylist, length)
clique_members <- sapply(mylist, function(x) paste("'", attributes(x)$name, "'", collapse = ",", sep = ""))
str(clique_members)
#>  chr [1:2035] "'A:87','A:81','A:57'" "'A:87','A:81','A:77','A:69'" ...


# empty character vector!!! 
cliques_members2 <- sapply(mylist, function(x) paste("'", attributes(x)$PaperID, "'", collapse = ",", sep = ""))
str(cliques_members2)
#>  chr [1:2035] "''" "''" "''" "''" "''" "''" "''" "''" "''" "''" "''" "''" ...

cliques_df <- data.frame(cliqueNums = clique_number, cliqueMembs = clique_members)
head(cliques_df, n = 10)
#>    cliqueNums                 cliqueMembs
#> 1           3        'A:87','A:81','A:57'
#> 2           4 'A:87','A:81','A:77','A:69'
#> 3           3        'A:87','A:79','A:69'
#> 4           4 'A:87','A:79','A:75','A:51'
#> 5           4 'A:87','A:79','A:75','A:65'
#> 6           3        'A:87','A:69','A:91'
#> 7           3        'A:87','A:65','A:28'
#> 8           3        'A:87','A:65','A:17'
#> 9           3        'A:87','A:57','A:28'
#> 10          3        'A:87','A:57','A:46'

# checks:
mylist[1:10]
#> [[1]]
#> + 3/100 vertices, named, from c3ed415:
#> [1] A:87 A:81 A:57
#> 
#> [[2]]
#> + 4/100 vertices, named, from c3ed415:
#> [1] A:87 A:81 A:77 A:69
#> 
#> [[3]]
#> + 3/100 vertices, named, from c3ed415:
#> [1] A:87 A:79 A:69
#> 
#> [[4]]
#> + 4/100 vertices, named, from c3ed415:
#> [1] A:87 A:79 A:75 A:51
#> 
#> [[5]]
#> + 4/100 vertices, named, from c3ed415:
#> [1] A:87 A:79 A:75 A:65
#> 
#> [[6]]
#> + 3/100 vertices, named, from c3ed415:
#> [1] A:87 A:69 A:91
#> 
#> [[7]]
#> + 3/100 vertices, named, from c3ed415:
#> [1] A:87 A:65 A:28
#> 
#> [[8]]
#> + 3/100 vertices, named, from c3ed415:
#> [1] A:87 A:65 A:17
#> 
#> [[9]]
#> + 3/100 vertices, named, from c3ed415:
#> [1] A:87 A:57 A:28
#> 
#> [[10]]
#> + 3/100 vertices, named, from c3ed415:
#> [1] A:87 A:57 A:46

mylist[[22]]
#> + 5/100 vertices, named, from c3ed415:
#> [1] A:21 A:67 A:62 A:27 A:22
cliques_df[22, ]
#>    cliqueNums                        cliqueMembs
#> 22          5 'A:21','A:67','A:62','A:27','A:22'

Created on 2020-07-07 by the reprex package (v0.3.0)

Tim-TU
  • 408
  • 1
  • 4
  • 13
  • Thanks very much! This is very helpful. However I do want to import the 'NodeID' (instead of index) to the dataframe i.e. the members of the clique should appear as NodeIDs. Though my igraph object `g` has 'NodeID' as a vertex attribute, when I apply `maximal.cliques()`, the `mylist` seems to drop the NodeID. Is there a way to bring that over so that it appears in the dataframe? – Grace Jul 06 '20 at 12:46
  • Maybe you can work with the attributes. I will update the reprex. – Tim-TU Jul 06 '20 at 13:51
  • Thanks for the code. Unfortunately, after running the code, my output is " " (empty) instead of NodeID. I've edited my post to insert a screenshot of my `g` object, in case that's the issue... it does not show the NodeID when viewed in the R environment bar on the right. But when I execute `vertex_attr_names(g)`, the nodeID is shown. Could this be the reason? – Grace Jul 06 '20 at 15:11
  • I would try to set the "NodeID" attribute as the attribute name shown in my reprex. Replace NodeIds with vertex_attr_names(g). If this won't work please try to save the graph g and share it via a link or something like this that I can work with your graph g. Maybe you can also share your findings using a reprex. – Tim-TU Jul 06 '20 at 15:35
  • Thanks, I've tried that too... I edited my post to add the data + codes. (Sorry I can't seem to export an igraph object, so I am attaching the csv file.) – Grace Jul 06 '20 at 16:47
  • 1
    This is a pretty large network. It is running since several minutes to get the `maximal.cliques(g)`. But I've inspected your code. What you have done is using `attributes(x)$PaperID` insode the second `sapply`. My feeling says that only the attribute named _name_ isn't dropped. Try to do the following assignment: `V(g)$name <- V(g)$PaperID` and then use `attributes(x)$name` in the second `sapply`. **EDIT:** I've checked it in my small example and will update the reprex so that you can see that it fails using `attributes(x)$PaperID`. – Tim-TU Jul 07 '20 at 04:17
  • 1
    Thank you for going through it. It works now! My learning point: So the 'node name' needs to be assigned to `V(g)$name`, and this naming cannot be changed (e.g. V(g)$ID would fail). I guess it applies for all igraph objects. – Grace Jul 07 '20 at 13:56
  • Yeah, it seems that the attribute `name` is the attribute (maybe the only one) that is kept. – Tim-TU Jul 07 '20 at 14:05