Question

Why is E(g) not identical to itself

Consider:

library(igraph)
g <- make_ring(3)

identical(g, g)    # TRUE as expected
# [1] TRUE

dput(E(g))
# structure(1:3, is_all = TRUE, class = "igraph.es", env = <weak reference>, graph = "4f82a4da-3975-11ef-8958-675a79d1d14f")


E(g) == E(g)              # test equality.
# [1] TRUE TRUE TRUE

all.equal(E(g), E(g))     # Next try.     
# [1] TRUE

identical(E(g), E(g), ignore.environment = FALSE) # Expecting TRUE.
# [1] FALSE

identical(E(g), E(g), ignore.environment = TRUE) # Expecting TRUE.
# [1] FALSE

Question: Why False?

 4  108  4
1 Jan 1970

Solution

 6

Take a look at unclass(E(g)):

[1] 1 2 3
attr(,"is_all")
[1] TRUE
attr(,"env")
<weak reference>
attr(,"graph")
[1] "a075a1af-ef79-4811-8876-3c0d2d45085f"

It contains a "weak reference", which is an exotic R object that you rarely see. Each time you call E(g) you create a different weak reference, and so identical() says they are not identical.

EDITED to add:

You can read about weak references here: ?rlang::new_weakref. There are also notes here: http://homepage.divms.uiowa.edu/~luke/R/references/weakfinex.html, but it's not clear if they are current.

The code that does the identical() comparison is here:

https://github.com/wch/r-source/blob/ded6c7e0958844d6892c197009abe5879848ba4e/src/main/identical.c#L334-L335

From the comment, it's not clear if the authors of those lines are sure it's doing the right thing. It would probably make more sense to say two weak references are identical if they reference the same object and have the same associated data and finalizer.

2024-07-03
user2554330

Solution

 3

I speculate that identical gives FALSE since E(g) is assigned with different memory addresses between the first and second calls, for example

> library(data.table)

> address(E(g))
[1] "000001a51697f368"

> address(E(g))
[1] "000001a516666e68"

but if you have them pointed to the same reference, then you may obtain TRUE

> e <- E(g)

> identical(e, e)
[1] TRUE
2024-07-03
ThomasIsCoding