Changing list by reference in R

Asked

Viewed 42 times

1

I have the following problem. I have 5 graphs (per hour, it won’t matter the structure of each graph, only that I have 5 graphs) and put them inside a list in R. I will make changes to these graphs within a loop that will have 100 loops.

Example:

for (i in 1:100){

for(vile in viles){

  if(sample(1:10,1) <= 1){ # Aresta interna aparecer
    graphInverse <- graph.full(6,directed = TRUE) - vile;
    allEdgesInverse <- get.edgelist(graphInverse);
    randomEdge <- sample(1:length(allEdgesInverse[,1]),1);

    if(length(allEdgesInverse[,1]) != 0){ # Se o grafo nao for completo.
      vile[allEdgesInverse[randomEdge,][1],allEdgesInverse[randomEdge,][2]] <- 1;
    }

  }
  if(sample(1:10,1) <= 1){ # Aresta interna desaparecer
      allEdges <- get.edgelist(vile); 
      randomEdge <- sample(1:length(allEdges[,1]),1);
      vile[allEdges[randomEdge,][1],allEdges[randomEdge,][2]] <- NULL #Vertice deletado
  }

}

}

In the first condition, insert a random edge with probability 0.1 that did not exist, in the second condition, I exclude an existing edge with the same probability. This earlier explanation is just to put it in context. My problem is, with each loop (for the first one) it starts a new loop in the 'viles' list (where it contains all my 5 graphs), I make the appropriate changes, but my 'viles' list is not updated, that is, in the next loop, of the variable 'i', my list is unchanged, That is, the values are still the initials. I’m changing by value, not by reference. Could someone help me find a data structure that, once I change the village, the structure that holds this village is updated with this new town changed or changed by reference, rather than value.

1 answer

1

When you make a for in the form for(i in x), R makes a copy of the object x and does not change it in each iteration.

A simple example is:

> x <- list(a = 1, b =1)
> for(i in x){
+   i <- i + 1
+ }
> x
$a
[1] 1

$b
[1] 1

> x <- list(a = 1, b =1)
> for(i in 1:length(x)){
+   x[[i]] <- x[[i]] + 1
+ }
> x
$a
[1] 2

$b
[1] 2

The correct way to do it in your case is:

for(j in 1:length(viles)){

  if(sample(1:10,1) <= 1){ # Aresta interna aparecer
    graphInverse <- graph.full(6,directed = TRUE) - viles[[j]];
    allEdgesInverse <- get.edgelist(graphInverse);
    randomEdge <- sample(1:length(allEdgesInverse[,1]),1);

    if(length(allEdgesInverse[,1]) != 0){ # Se o grafo nao for completo.
      viles[[j]][allEdgesInverse[randomEdge,][1],allEdgesInverse[randomEdge,][2]] <- 1;
    }

  }
  if(sample(1:10,1) <= 1){ # Aresta interna desaparecer
      allEdges <- get.edgelist(viles[[j]]); 
      randomEdge <- sample(1:length(allEdges[,1]),1);
      viles[[j]][allEdges[randomEdge,][1],allEdges[randomEdge,][2]] <- NULL #Vertice deletado
  }

}

Note that I changed all references to vile, for viles[[j]] besides exchanging the vector traveled by the loop.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.