# Function set\_edge\_attr does not seem to work

**URL:** <https://igraph.discourse.group/t/function-set-edge-attr-does-not-seem-to-work/1280>\
**Category:** Usage\
**Tags:** R\
**Created:** [29 June 2022 16:40 UTC](https://igraph.discourse.group/t/function-set-edge-attr-does-not-seem-to-work/1280 "2022-06-29T16:40:10Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![KeesP](https://avatars.discourse-cdn.com/v4/letter/k/2bfe46/32.png) [@KeesP](https://igraph.discourse.group/u/KeesP)\
**Post date:** [29 June 2022 16:40 UTC](https://igraph.discourse.group/t/function-set-edge-attr-does-not-seem-to-work/1280/1 "2022-06-29T16:40:10Z")

</div>

The following code

```auto
library(igraph)
g1 <- make_ring(3) %>% set_edge_attr("weight", value = seq(3) )
edge_attr(g1)

```

gives as expected

```auto
$weight
[1] 1 2 3

```

However, similar code:

```auto
g2 <- make_ring(3)
set_edge_attr(g2, "weight", value = seq(3) )
edge_attr(g2)

```

gives  
`list()`

I would expect the same output. Any thoughts why this isn’t the case?

---

<div class="post-metadata">

**Author:** ![szhorvat](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/szhorvat/32/3_2.png) [@szhorvat](https://igraph.discourse.group/u/szhorvat)\
**Post date:** [29 June 2022 17:15 UTC](https://igraph.discourse.group/t/function-set-edge-attr-does-not-seem-to-work/1280/2 "2022-06-29T17:15:45Z")

</div>

`set_edge_attr` does not mutate an existing graph. It returns a new graph with modified attributes.

---

<div class="post-metadata">

**Author:** ![KeesP](https://avatars.discourse-cdn.com/v4/letter/k/2bfe46/32.png) [@KeesP](https://igraph.discourse.group/u/KeesP)\
**Post date:** [29 June 2022 18:35 UTC](https://igraph.discourse.group/t/function-set-edge-attr-does-not-seem-to-work/1280/3 "2022-06-29T18:35:51Z")

</div>

Thanks. I missed that.

In my opinion the documentation is too cryptic.  
In stead of

> Set edge attributes

it should be something like:

> set\_edge\_attr creates a new graph, updating the edge attributes.

---

<div class="post-metadata">

**Author:** ![szhorvat](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/szhorvat/32/3_2.png) [@szhorvat](https://igraph.discourse.group/u/szhorvat)\
**Post date:** [29 June 2022 19:34 UTC](https://igraph.discourse.group/t/function-set-edge-attr-does-not-seem-to-work/1280/4 "2022-06-29T19:34:02Z")

</div>

This is not specific to `set_edge_attr` but a fundamental principle of R. Like typical functional languages, R uses call-by-value, and functions cannot modify their arguments. All other functions will _return_ modified values as well, instead of modifying variables passed to them.

---

<div class="post-metadata">

**Author:** ![KeesP](https://avatars.discourse-cdn.com/v4/letter/k/2bfe46/32.png) [@KeesP](https://igraph.discourse.group/u/KeesP)\
**Post date:** [1 July 2022 15:28 UTC](https://igraph.discourse.group/t/function-set-edge-attr-does-not-seem-to-work/1280/5 "2022-07-01T15:28:41Z")

</div>

To close this topic:

`g$main <- "This is bad practice"`

However:

`g <- set_graph_attr(g, name="main", value="This is functional programming good practice")`

---

<div class="post-metadata">

**Author:** ![szhorvat](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/szhorvat/32/3_2.png) [@szhorvat](https://igraph.discourse.group/u/szhorvat)\
**Post date:** [1 July 2022 15:41 UTC](https://igraph.discourse.group/t/function-set-edge-attr-does-not-seem-to-work/1280/6 "2022-07-01T15:41:23Z")

</div>

First, I have to say that I rarely use R and can’t really say what is / isn’t considered good practice … My involvement with igraph is mainly through its C core and Mathematica interface.

However, I would not say that `g$main <- "This is bad practice"`. I don’t think there’s anything wrong with that.

My point was that it is not possible to write an R function that changes a variable. The following is not possible:

```auto
x <- 1
f(x)
# now the value of x is 2

```

Only this is possible:

```auto
f <- function(a) { a + 1 }
x <- 1
x <- f(x)

```

This is because conceptually, R works with values, not with references. Some other languages, like Python, work with references, and you can do this:

```auto
In [1]: a=[1,2,3]

In [2]: b=a

In [3]: b[1]=100

In [4]: a
Out[4]: [1, 100, 3]

```

Notice that modifying `b` modified `a` as well. More accurately, `a` and `b` refer to the same data structure. In R each variable name is associated with an independent value. Modifying one variable will never affect another. Thus modifying a (local) function argument won’t change the (global) variable that was passed to the function.

---

<div class="post-metadata">

**Author:** ![szhorvat](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/szhorvat/32/3_2.png) [@szhorvat](https://igraph.discourse.group/u/szhorvat)\
**Post date:** [1 July 2022 16:08 UTC](https://igraph.discourse.group/t/function-set-edge-attr-does-not-seem-to-work/1280/7 "2022-07-01T16:08:50Z")

</div>

All that said, generally speaking, improvements to the documentation are very welcome. Feel free to open pull requests with doc improvements. The R/igraph docs certainly need an update.

---

<div class="post-metadata">

**Author:** ![KeesP](https://avatars.discourse-cdn.com/v4/letter/k/2bfe46/32.png) [@KeesP](https://igraph.discourse.group/u/KeesP)\
**Post date:** [1 July 2022 20:58 UTC](https://igraph.discourse.group/t/function-set-edge-attr-does-not-seem-to-work/1280/8 "2022-07-01T20:58:35Z")

</div>

The argument is that the statement

```auto
`g$main <- "This is bad practice"`

```

is based on the internal structure of the graph g. In the (unlikely) case that it is decided to move $main to another position, the code will fail.

In contrast, retrieving data by functions get\*attr is independent of the internal representation of g and is therefore more robust.

I admit this is a rather purist approach.
