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:
There must be a simpler way to generate this output, either with
purrr
origraph
or something else--is there a better way to do it? I haven't usedigraph
before.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 thek = 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