Quantcast
Channel: Active questions tagged r - Stack Overflow
Viewing all articles
Browse latest Browse all 205466

Using purrr or igraph (or any other method instead of nested loops) to generate all possible combinations of directed connections?

$
0
0

I have a dataset that has this sort of a structure:

df
#>   Instance Alice_prefers Bob_prefers Charlie_prefers
#> 1        1           Bob     Charlie           Alice
#> 2        2           Bob       Alice             Bob
#> 3        3           Bob     Charlie             Bob

My desired output would be a dataframe where:

  • every row of the dataframe is one combination of Alice, Bob and Charlie's possible preferences
  • the dataframe contains all possible combinations, i.e. the number of rows in the dataframe is equal to the number of possible combinations.
  • in any given combination (i.e. row), a person prefers one other person, and they cannot prefer themselves, i.e. Alice can choose to prefer Bob or Charlie, but cannot prefer Alice, and cannot prefer Bob and Charlie in the same instance.

    The complete desired output is thus:

#>   instance alice_prefers bob_prefers charlie_prefers
#> 1        1           Bob       Alice           Alice
#> 2        2           Bob       Alice             Bob
#> 3        3           Bob     Charlie           Alice
#> 4        4           Bob     Charlie             Bob
#> 5        5       Charlie       Alice           Alice
#> 6        6       Charlie       Alice             Bob
#> 7        7       Charlie     Charlie           Alice
#> 8        8       Charlie     Charlie             Bob

My current solution works (code below), but seems extremely clunky, and doesn't obviously generalise to more people than just Alice, Bob and Charlie (k = 3). I'm using nested loops.

I have two questions:

  1. There must be a simpler way to generate this output, either with purrr or igraph or something else--is there a better way to do it? I haven't used igraph before.

  2. Currently, the problem is for 3 people (k = 3): Alice, Bob, Charlie. Is there some way I can easily generalise the solution to add more people, so that if I wanted to generate the combinations for say Alice, Bob, Charlie, Don, and Enid, I could just call a function where I pass the k = 5 as an argument? The names of the people can be anything, I've just set them to follow the alphabet to help me work with this.

choices_alice <- c("Bob", "Charlie")
choices_bob <- c("Alice", "Charlie")
choices_charlie <- c("Alice", "Bob")

get_combinations <- function(choices_alice, choices_bob, choices_charlie) {
  instance <- numeric()
  alice_prefers <- character()
  bob_prefers <- character()
  charlie_prefers <- character()
  id <- 1
  for (a_counter in seq_along(choices_alice)) {
    for (b_counter in seq_along(choices_bob)){
      for (c_counter in seq_along(choices_charlie)){
        alice_prefers[id] <- choices_alice[a_counter]
        bob_prefers[id] <- choices_bob[b_counter]
        charlie_prefers[id] <- choices_charlie[c_counter]
        instance[id] <- id
        id <- id + 1
      }

    }
  }
  data.frame(instance, alice_prefers, bob_prefers, charlie_prefers, stringsAsFactors=FALSE)
}

df <- get_combinations(choices_alice, choices_bob, choices_charlie)
df

Viewing all articles
Browse latest Browse all 205466

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>