Builds the candidate set one alternative at a time instead of from the full factorial of all alternatives. This uses far less memory and avoids choice tasks that are the same apart from the order of the alternatives.

build_candidate_set(utility, exclusions = list(), allow_reversed_pairs = FALSE)

Arguments

utility

A named list of utility functions. See the examples and the vignette for examples of how to define these correctly for different types of experimental designs.

exclusions

A list of exclusions Often this list will be pulled directly from the list of options or it is a modified list of exclusions

allow_reversed_pairs

If TRUE, include the profiles of exchangeable alternatives in every order, e.g. both A versus B and B versus A. This also applies to sets of three or more exchangeable alternatives. The default is FALSE.

Value

A data frame with the candidate set

Details

The profiles of each alternative are the full factorial of its attribute levels. Exclusions that only refer to a single alternative are applied to its profiles before the alternatives are combined. Alternatives are exchangeable if their utility functions and profiles are identical apart from the name of the alternative, e.g. two unlabelled alternatives. By default, each choice task contains a set of different profiles for the exchangeable alternatives only once, and the order of the exchangeable alternatives is randomised in each row to ensure that no alternative systematically gets the same profiles. Labelled alternatives are combined with all profiles of the other alternatives, as in the full factorial. Finally, exclusions that refer to more than one alternative are applied.

Because the order of exchangeable alternatives is random, exclusions across exchangeable alternatives must be specified in both directions, e.g. that alt1 dominates alt2 and that alt2 dominates alt1.

With `allow_reversed_pairs = TRUE` and no exclusions, the candidate set is the full factorial without choice tasks where exchangeable alternatives have the same profile. To create a candidate set with attribute levels that are different from those in the utility functions, use expand.grid.

Examples

utility <- list(
  alt1 = "b_x1[0.1] * x1[1:3] + b_x2[-0.2] * x2[c(0, 1)]",
  alt2 = "b_x1      * x1      + b_x2       * x2"
)

build_candidate_set(utility, exclusions = list("alt1_x1 == 1 & alt1_x2 == 0"))
#>    alt1_x1 alt1_x2 alt2_x1 alt2_x2
#> 1        2       0       1       0
#> 2        3       0       1       0
#> 3        1       1       1       0
#> 4        2       1       1       0
#> 5        3       1       1       0
#> 6        2       0       2       0
#> 7        3       0       2       0
#> 8        1       1       2       0
#> 9        2       1       2       0
#> 10       3       1       2       0
#> 11       2       0       3       0
#> 12       3       0       3       0
#> 13       1       1       3       0
#> 14       2       1       3       0
#> 15       3       1       3       0
#> 16       2       0       1       1
#> 17       3       0       1       1
#> 18       1       1       1       1
#> 19       2       1       1       1
#> 20       3       1       1       1
#> 21       2       0       2       1
#> 22       3       0       2       1
#> 23       1       1       2       1
#> 24       2       1       2       1
#> 25       3       1       2       1
#> 26       2       0       3       1
#> 27       3       0       3       1
#> 28       1       1       3       1
#> 29       2       1       3       1
#> 30       3       1       3       1