Как создать уникальный список комбинаций из нескольких векторов? - PullRequest
0 голосов
/ 17 января 2019

Я хочу определить, сколько видов пиццы можно заказать на разные виды хлеба, используя всего 2 разных начинки. Но я хочу создать список уникальных комбинаций.

Я использовал функцию комбинаций () из пакета договоренностей, чтобы создать список уникальных комбинаций, и я сделал это для начинки. Я изо всех сил пытаюсь выяснить, как включить корки.

toppings <- c("Pepperoni", "Canadian Bacon", "Sausage", "Italian Sausage")
crust <- c("Thick", "Thin", "Cracker")
toppingcombo <- combinations(toppings)
pizza <- arrangements::combinations(c(crust, toppings), 3)

Последняя строка кода вместо этого показывает это как результат.

     [,1]    [,2]            
[1,] "Thick" "Thin"          
[2,] "Thick" "Tuscano"       
[3,] "Thick" "Pepperoni" 

Хотелось бы, чтобы результаты показали:

     [,1]    [,2]        [,3]            
[1,] "Thick" "Sausage"   "Bacon"         
[2,] "Thick" "Pepperoni" "Sausage       

Но избегайте создания дубликатов, таких как "Толстый / Бекон / Колбаса", так как это то же самое, что и строка [1,], но с начинками в другом порядке.

Ответы [ 4 ]

0 голосов
/ 17 января 2019

Подумайте о создании списка матриц, передав оба вектора в sapply, затем в конце свяжите строки со всеми элементами:

pizza_list <- sapply(crust, function(x,y) cbind(x, t(combn(y, m=2))), toppings, simplify=FALSE)

pizza <- do.call(rbind, pizza_list)
colnames(pizza) <- c("Crust", "Toppings1", "Toppings2")

pizza    
#       Crust     Toppings1        Toppings2        
#  [1,] "Thick"   "Pepperoni"      "Canadian Bacon" 
#  [2,] "Thick"   "Pepperoni"      "Sausage"        
#  [3,] "Thick"   "Pepperoni"      "Italian Sausage"
#  [4,] "Thick"   "Canadian Bacon" "Sausage"        
#  [5,] "Thick"   "Canadian Bacon" "Italian Sausage"
#  [6,] "Thick"   "Sausage"        "Italian Sausage"
#  [7,] "Thin"    "Pepperoni"      "Canadian Bacon" 
#  [8,] "Thin"    "Pepperoni"      "Sausage"        
#  [9,] "Thin"    "Pepperoni"      "Italian Sausage"
# [10,] "Thin"    "Canadian Bacon" "Sausage"        
# [11,] "Thin"    "Canadian Bacon" "Italian Sausage"
# [12,] "Thin"    "Sausage"        "Italian Sausage"
# [13,] "Cracker" "Pepperoni"      "Canadian Bacon" 
# [14,] "Cracker" "Pepperoni"      "Sausage"        
# [15,] "Cracker" "Pepperoni"      "Italian Sausage"
# [16,] "Cracker" "Canadian Bacon" "Sausage"        
# [17,] "Cracker" "Canadian Bacon" "Italian Sausage"
# [18,] "Cracker" "Sausage"        "Italian Sausage"

Rextester Demo

0 голосов
/ 17 января 2019

Я внесу некоторые изменения в ваши входные данные для достижения желаемой цели.

Данные

toppings <- c("Pepperoni", "Canadian Bacon", "Sausage", "Italian Sausage")
crust <- data.frame(crust = c("Thick", "Thin", "Cracker"))

library(arrangements)
topping_combo <- as.data.frame(combinations(toppings, k = 2, n = length(toppings)))
colnames(topping_combo) <- c("topping_1", "topping_2")

Итак, теперь у нас есть два кадра данных: crust только с одним столбцом и тремя строками, по одному для каждого типа коры; topping_combo - это кадр данных 6x2, который содержит все возможные 2-комбинации комбинаций начинки.

Код

Следующий код предлагает одно возможное решение для создания кадра данных, в котором каждая строка является типом пиццы, как вы и просили. Мы используем функцию crossing из пакета tidyr.

library(tidyr)
crossing(crust, topping_combo)

выход

     crust      topping_1       topping_2
1    Thick      Pepperoni  Canadian Bacon
2    Thick      Pepperoni         Sausage
3    Thick      Pepperoni Italian Sausage
4    Thick Canadian Bacon         Sausage
5    Thick Canadian Bacon Italian Sausage
6    Thick        Sausage Italian Sausage
7     Thin      Pepperoni  Canadian Bacon
8     Thin      Pepperoni         Sausage
9     Thin      Pepperoni Italian Sausage
10    Thin Canadian Bacon         Sausage
11    Thin Canadian Bacon Italian Sausage
12    Thin        Sausage Italian Sausage
13 Cracker      Pepperoni  Canadian Bacon
14 Cracker      Pepperoni         Sausage
15 Cracker      Pepperoni Italian Sausage
16 Cracker Canadian Bacon         Sausage
17 Cracker Canadian Bacon Italian Sausage
18 Cracker        Sausage Italian Sausage
0 голосов
/ 17 января 2019

С помощью базы R, аналогичной ответу @ RicS, вы можете составить таблицу комбинаций топингов и скрестить ее с корочками в два этапа, используя expand.grid и cbind:

top_combo = t(combn(toppings, 2))
eg = expand.grid(crust = crust, tc = seq_len(nrow(top_combo)))
res = cbind(eg, top_combo[eg$tc, ])

     crust tc              1               2
1    Thick  1      Pepperoni  Canadian Bacon
2     Thin  1      Pepperoni  Canadian Bacon
3  Cracker  1      Pepperoni  Canadian Bacon
4    Thick  2      Pepperoni         Sausage
5     Thin  2      Pepperoni         Sausage
6  Cracker  2      Pepperoni         Sausage
7    Thick  3      Pepperoni Italian Sausage
8     Thin  3      Pepperoni Italian Sausage
9  Cracker  3      Pepperoni Italian Sausage
10   Thick  4 Canadian Bacon         Sausage
11    Thin  4 Canadian Bacon         Sausage
12 Cracker  4 Canadian Bacon         Sausage
13   Thick  5 Canadian Bacon Italian Sausage
14    Thin  5 Canadian Bacon Italian Sausage
15 Cracker  5 Canadian Bacon Italian Sausage
16   Thick  6        Sausage Italian Sausage
17    Thin  6        Sausage Italian Sausage
18 Cracker  6        Sausage Italian Sausage
0 голосов
/ 17 января 2019

Следующее использует dplyr для создания всех комбинаций между crust и toppings через expand.Затем toppings сортируются по алфавиту (topping_1 <<code>topping_2) и извлекается набор unique.

> library(tidyverse)
> df <- data.frame(
  toppings = c(
    'Pepperoni',
    'Canadian Bacon',
    'Sausage',
    'Italian Sausage'
  ),
  crust = c(
    'Thick', 
    'Thin',
    'Cracker',
    NA # to match the number of toppings
  ),
  stringsAsFactors = FALSE
)

> pizza <- df %>% expand(
  crust,
  toppings,
  toppings
) %>% transmute(
  crust = crust,
  topping_1 = if_else(
    toppings < toppings1,
    toppings,
    toppings1
  ),
  topping_2 = if_else(
    toppings < toppings1,
    toppings1,
    toppings
  )
) %>% filter(
  !is.na(crust), # Remove no-base pizzas
  topping_1 != topping_2 # Remove double-toppings of the same kind
) %>% unique() # Keep only unique combinations across crust, topping_1 and topping_2

> pizza
# A tibble: 18 x 3
   crust   topping_1       topping_2      
   <chr>   <chr>           <chr>          
 1 Cracker Canadian Bacon  Italian Sausage
 2 Cracker Canadian Bacon  Pepperoni      
 3 Cracker Canadian Bacon  Sausage        
 4 Cracker Italian Sausage Pepperoni      
 5 Cracker Italian Sausage Sausage        
 6 Cracker Pepperoni       Sausage        
 7 Thick   Canadian Bacon  Italian Sausage
 8 Thick   Canadian Bacon  Pepperoni      
 9 Thick   Canadian Bacon  Sausage        
10 Thick   Italian Sausage Pepperoni      
11 Thick   Italian Sausage Sausage        
12 Thick   Pepperoni       Sausage        
13 Thin    Canadian Bacon  Italian Sausage
14 Thin    Canadian Bacon  Pepperoni      
15 Thin    Canadian Bacon  Sausage        
16 Thin    Italian Sausage Pepperoni      
17 Thin    Italian Sausage Sausage        
18 Thin    Pepperoni       Sausage        
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...