Perturb a binary graph probabilistically

make_perturbed_graph(
  x,
  prob_tot = NULL,
  prob_0_to_1 = 0,
  prob_1_to_0 = 0,
  combined = FALSE,
  replace = FALSE,
  diag = FALSE
)

Arguments

x

graph of class igraph, network, or matrix

prob_tot

probability of any edge to change (from 1 to 0 or 0 to 1)

prob_0_to_1

probability of any 0 edge to change to a 1

prob_1_to_0

probability of any 0 edge to change to a 1

combined

logical, see details

replace

logical, whether to draw the cells to be changed with replacement

diag

logical, should the diagonal (self-loops) be allowed to change?

Value

the perturbed graph

Details

Given a binary (ie. non-weighted) graph, change some proportion of its edges from 0 to 1 or 1 to 0. There are several ways of doing this:

When prob_tot is specified and combined is set to FALSE, all edges in the graph have the same probability of changing. In this case, prob_0_to 1 and prob_1_to_0 are ignored and, hence, no distinction is made between edges with value 0 or with value 1. This will ignore any choice of prob_0_to 1 and prob_1_to_0.

When prob_tot is NULL, edges with value 0 will change to a 1 with probability prob_0_to 1 and edges with value 1 will change to a 0 with probability prob_1_to 0.

When prob_tot is specified and combined is set to TRUE, first edges with value 0 will change to a 1 with probability prob_0_to 1 and edges with value 1 will change to a 0 with probability prob_1_to 0. After that, the edges in the resulting graph will be perturbated with probability prob_tot (potentially reversing some of the previous changes).

The replace argument allows for edges to be drawn multiple times. This means that fewer edges will change, since the same edge might change from a 0 to a 1 multiple times (or from a 1 to a 0). This is likely rarely useful.

The resulting graph will have the same class as has x.

Examples

g <- snafun::create_random_graph(20, "gnm", m = 100)
make_perturbed_graph(g, prob_tot = .3)
#> IGRAPH d94ddf5 D--- 20 152 -- 
#> + edges from d94ddf5:
#>  [1]  1-> 5  1-> 7  1->11  1->16  1->17  1->18  2-> 1  2->12  2->15  2->18
#> [11]  2->19  3-> 2  3-> 6  3-> 8  3-> 9  3->11  3->13  3->14  3->20  4-> 8
#> [21]  4->10  4->11  4->14  4->17  4->19  5-> 1  5-> 2  5-> 8  5->10  5->15
#> [31]  6-> 1  6-> 3  6-> 5  6-> 8  6-> 9  6->10  6->13  6->14  6->19  6->20
#> [41]  7-> 2  7-> 3  7-> 4  7-> 6  7-> 8  7->16  7->20  8-> 2  8-> 3  8-> 4
#> [51]  8-> 7  8->12  8->13  8->14  8->16  8->20  9-> 2  9-> 3  9-> 5  9-> 6
#> [61]  9-> 7  9->12  9->13  9->17  9->18  9->20 10-> 7 10->13 10->15 10->18
#> [71] 11-> 3 11-> 5 11-> 6 11-> 9 11->10 11->14 11->17 11->18 12-> 1 12-> 3
#> [81] 12-> 4 12-> 5 12-> 6 12->14 12->17 13-> 2 13-> 5 13-> 9 13->10 13->12
#> + ... omitted several edges
# prob_0_to_1 is ignored
make_perturbed_graph(g, prob_tot = .3, prob_0_to_1 = 1)
#> IGRAPH d95059c D--- 20 154 -- 
#> + edges from d95059c:
#>  [1]  1-> 2  1-> 9  1->12  1->13  1->17  1->19  1->20  2-> 1  2-> 3  2-> 6
#> [11]  2-> 8  2->10  2->18  2->19  2->20  3-> 2  3-> 6  3->10  3->13  3->14
#> [21]  3->17  3->18  3->19  3->20  4-> 1  4-> 3  4->15  4->16  4->19  4->20
#> [31]  5-> 1  5-> 4  5-> 6  5->13  5->14  5->15  5->17  5->18  5->19  6-> 3
#> [41]  6-> 7  6-> 8  6->10  6->13  6->20  7-> 3  7-> 5  7-> 8  7-> 9  7->10
#> [51]  7->11  7->12  7->15  7->17  7->19  8-> 2  8-> 3  8-> 4  8-> 6  8->12
#> [61]  8->14  8->15  8->17  8->18  8->19  8->20  9-> 4  9-> 5  9-> 6  9->12
#> [71]  9->13  9->16  9->18  9->20 10-> 2 10-> 7 10-> 9 10->13 10->15 10->16
#> [81] 10->19 11-> 3 11-> 6 11-> 9 11->10 12-> 2 12-> 5 12-> 9 12->13 12->17
#> + ... omitted several edges
# prob_0_to_1 is used first, then prob_tot
make_perturbed_graph(g, prob_tot = .3, prob_0_to_1 = 1, combined = TRUE)
#> IGRAPH d9527d4 D--- 20 266 -- 
#> + edges from d9527d4:
#>   [1] 1-> 2 1-> 3 1-> 4 1-> 5 1-> 6 1-> 7 1-> 8 1-> 9 1->12 1->13 1->15 1->16
#>  [13] 1->17 1->19 1->20 2-> 1 2-> 3 2-> 7 2-> 9 2->12 2->13 2->14 2->16 2->17
#>  [25] 2->20 3-> 2 3-> 4 3-> 5 3-> 6 3-> 7 3-> 9 3->12 3->13 3->14 3->16 3->17
#>  [37] 3->18 3->19 3->20 4-> 2 4-> 3 4-> 5 4-> 6 4-> 7 4-> 8 4-> 9 4->11 4->13
#>  [49] 4->14 4->15 4->17 4->19 4->20 5-> 2 5-> 7 5-> 8 5->12 5->13 5->14 5->16
#>  [61] 5->17 5->18 5->20 6-> 2 6-> 3 6-> 4 6-> 5 6-> 7 6->10 6->11 6->12 6->13
#>  [73] 6->14 6->15 6->16 6->17 6->18 6->19 6->20 7-> 1 7-> 2 7-> 4 7-> 6 7-> 8
#>  [85] 7-> 9 7->10 7->11 7->12 7->13 7->14 7->15 7->16 7->17 7->18 7->19 8-> 1
#>  [97] 8-> 2 8-> 3 8-> 4 8-> 6 8-> 7 8->11 8->13 8->17 8->18 8->20 9-> 2 9-> 6
#> + ... omitted several edges
make_perturbed_graph(snafun::to_matrix(g), prob_tot = .3, prob_0_to_1 = 1)
#>       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
#>  [1,]    0    1    0    0    0    0    0    1    0     0     0     0     1
#>  [2,]    0    0    0    0    1    1    0    1    0     1     0     1     0
#>  [3,]    0    0    0    1    1    0    0    0    1     0     0     0     0
#>  [4,]    0    1    0    0    1    0    0    0    0     0     1     0     0
#>  [5,]    1    1    0    0    0    0    0    0    0     0     1     1     1
#>  [6,]    0    1    0    1    0    0    0    1    0     0     1     0     0
#>  [7,]    1    1    1    0    0    0    0    1    0     1     1     0     0
#>  [8,]    0    1    0    0    0    0    0    0    0     0     0     0     0
#>  [9,]    0    0    0    1    1    0    0    0    0     0     0     1     0
#> [10,]    0    1    0    0    0    0    0    0    1     0     0     0     1
#> [11,]    0    0    1    0    1    0    1    1    0     1     0     0     0
#> [12,]    0    0    0    0    1    0    1    1    1     1     0     0     0
#> [13,]    0    1    1    0    1    0    0    0    0     0     0     1     0
#> [14,]    1    1    1    1    0    1    0    0    1     0     1     0     1
#> [15,]    0    1    1    0    0    0    0    1    0     0     0     0     0
#> [16,]    0    0    1    1    0    1    0    0    0     0     1     0     1
#> [17,]    1    0    1    1    0    0    0    1    1     0     1     0     0
#> [18,]    0    0    0    1    0    1    1    0    0     1     1     0     0
#> [19,]    0    1    0    1    0    1    0    0    1     1     1     0     0
#> [20,]    0    0    0    0    1    1    0    0    0     0     0     0     0
#>       [,14] [,15] [,16] [,17] [,18] [,19] [,20]
#>  [1,]     1     0     1     0     0     1     0
#>  [2,]     1     0     1     0     1     1     0
#>  [3,]     0     0     1     0     1     0     0
#>  [4,]     0     0     1     0     0     0     0
#>  [5,]     1     1     1     1     1     1     0
#>  [6,]     0     0     1     0     1     1     1
#>  [7,]     0     0     1     0     0     1     0
#>  [8,]     1     0     0     1     0     1     0
#>  [9,]     0     0     0     0     0     0     0
#> [10,]     1     1     0     0     0     1     0
#> [11,]     1     0     0     1     0     0     0
#> [12,]     1     0     1     0     1     0     0
#> [13,]     1     0     1     0     1     1     1
#> [14,]     0     1     0     1     0     0     1
#> [15,]     0     0     1     0     1     1     0
#> [16,]     1     1     0     0     1     1     0
#> [17,]     1     0     0     0     1     1     1
#> [18,]     0     1     0     0     0     0     1
#> [19,]     0     1     0     1     1     0     0
#> [20,]     0     0     1     1     0     0     0
make_perturbed_graph(snafun::to_network(g), prob_tot = .3, prob_0_to_1 = 1)
#>  Network attributes:
#>   vertices = 20 
#>   directed = TRUE 
#>   hyper = FALSE 
#>   loops = FALSE 
#>   multiple = FALSE 
#>   bipartite = FALSE 
#>   total edges= 160 
#>     missing edges= 0 
#>     non-missing edges= 160 
#> 
#>  Vertex attribute names: 
#>     vertex.names 
#> 
#> No edge attributes