Унікальне поєднання всіх елементів з двох (або більше) векторів


95

Я намагаюся створити унікальну комбінацію всіх елементів з двох векторів різного розміру в R.

Наприклад, перший вектор - це

a <- c("ABC", "DEF", "GHI")

а другий - дати, що зберігаються як рядки на даний момент

b <- c("2012-05-01", "2012-05-02", "2012-05-03", "2012-05-04", "2012-05-05")

Мені потрібно створити фрейм даних із двома такими стовпцями

> data
    a          b
1  ABC 2012-05-01
2  ABC 2012-05-02
3  ABC 2012-05-03
4  ABC 2012-05-04
5  ABC 2012-05-05
6  DEF 2012-05-01
7  DEF 2012-05-02
8  DEF 2012-05-03
9  DEF 2012-05-04
10 DEF 2012-05-05
11 GHI 2012-05-01
12 GHI 2012-05-02
13 GHI 2012-05-03
14 GHI 2012-05-04
15 GHI 2012-05-05

Отже, в основному, я шукаю унікальну комбінацію, розглядаючи всі елементи одного вектора (а), зіставлені з усіма елементами другого вектора (б).

Ідеальне рішення узагальнило б більше вхідних векторів.


Дивіться також:
Як створити матрицю комбінацій

Відповіді:


139

це, можливо, те, що ти хочеш

> expand.grid(a,b)
   Var1       Var2
1   ABC 2012-05-01
2   DEF 2012-05-01
3   GHI 2012-05-01
4   ABC 2012-05-02
5   DEF 2012-05-02
6   GHI 2012-05-02
7   ABC 2012-05-03
8   DEF 2012-05-03
9   GHI 2012-05-03
10  ABC 2012-05-04
11  DEF 2012-05-04
12  GHI 2012-05-04
13  ABC 2012-05-05
14  DEF 2012-05-05
15  GHI 2012-05-05

Якщо отримане замовлення не є тим, що ви хочете, ви можете відсортувати його пізніше. Якщо вказати аргументи expand.grid, вони стануть іменами стовпців:

df = expand.grid(a = a, b = b)
df[order(df$a), ]

І expand.gridузагальнює для будь-якої кількості вхідних стовпців.


4
І без необхідності plyrпросто робити сортування:result <- expand.grid(a=a,b=b); result <- result[order(result$a,result$b),];
thelatemail

чи може хтось із представниками більше, ніж я, прийняти цю відповідь?
Джош

Якщо порядок та імена повинні бути такими, як у питанні:expand.grid(b=b,a=a)[2:1]
GKi

Зверніть увагу, що заголовок - «Унікальні комбінації» - ця відповідь вирішує проблему OP, але якщо 2 стовпці мають однаковий тип даних, і ви застосуєте expand.grid, ви отримаєте унікальні перестановки, а не унікальні комбінації
Брент

27

tidyrПакет забезпечує хорошу альтернативу crossing, яка працює краще , ніж класичні expand.gridфункції , тому що (1) рядки не перетворюються в чинники , і (2) сортування більш інтуїтивна:

library(tidyr)

a <- c("ABC", "DEF", "GHI")
b <- c("2012-05-01", "2012-05-02", "2012-05-03", "2012-05-04", "2012-05-05")

crossing(a, b)

# A tibble: 15 x 2
       a          b
   <chr>      <chr>
 1   ABC 2012-05-01
 2   ABC 2012-05-02
 3   ABC 2012-05-03
 4   ABC 2012-05-04
 5   ABC 2012-05-05
 6   DEF 2012-05-01
 7   DEF 2012-05-02
 8   DEF 2012-05-03
 9   DEF 2012-05-04
10   DEF 2012-05-05
11   GHI 2012-05-01
12   GHI 2012-05-02
13   GHI 2012-05-03
14   GHI 2012-05-04
15   GHI 2012-05-05

13

У цьому відсутній огляд - це функція CJз-пакет. Використання:

library(data.table)
CJ(a, b, unique = TRUE)

дає:

      a          b
 1: ABC 2012-05-01
 2: ABC 2012-05-02
 3: ABC 2012-05-03
 4: ABC 2012-05-04
 5: ABC 2012-05-05
 6: DEF 2012-05-01
 7: DEF 2012-05-02
 8: DEF 2012-05-03
 9: DEF 2012-05-04
10: DEF 2012-05-05
11: GHI 2012-05-01
12: GHI 2012-05-02
13: GHI 2012-05-03
14: GHI 2012-05-04
15: GHI 2012-05-05

ПРИМІТКА: починаючи з версії 1.12.2 автоматично CJназиває отримані стовпці (див. Також тут і тут ).


4

Починаючи з версії 1.0.0, tidyrпропонує власну версію expand.grid(). Він завершує існуючу сім'ю expand(), nesting()і crossing()з функцією низького рівня , який працює з векторами .

У порівнянні з base::expand.grid():

Найперше змінюється перший елемент. Ніколи не перетворює рядки на фактори. Не додає жодних додаткових атрибутів. Повертає таблицю, а не кадр даних. Може розширити будь-який узагальнений вектор, включаючи кадри даних.

a <- c("ABC", "DEF", "GHI")
b <- c("2012-05-01", "2012-05-02", "2012-05-03", "2012-05-04", "2012-05-05")

tidyr::expand_grid(a, b)

   a     b         
   <chr> <chr>     
 1 ABC   2012-05-01
 2 ABC   2012-05-02
 3 ABC   2012-05-03
 4 ABC   2012-05-04
 5 ABC   2012-05-05
 6 DEF   2012-05-01
 7 DEF   2012-05-02
 8 DEF   2012-05-03
 9 DEF   2012-05-04
10 DEF   2012-05-05
11 GHI   2012-05-01
12 GHI   2012-05-02
13 GHI   2012-05-03
14 GHI   2012-05-04
15 GHI   2012-05-05

3

Ви можете використовувати функцію замовлення для сортування будь-якої кількості стовпців. для вашого прикладу

df <- expand.grid(a,b)
> df
   Var1       Var2
1   ABC 2012-05-01
2   DEF 2012-05-01
3   GHI 2012-05-01
4   ABC 2012-05-02
5   DEF 2012-05-02
6   GHI 2012-05-02
7   ABC 2012-05-03
8   DEF 2012-05-03
9   GHI 2012-05-03
10  ABC 2012-05-04
11  DEF 2012-05-04
12  GHI 2012-05-04
13  ABC 2012-05-05
14  DEF 2012-05-05
15  GHI 2012-05-05

> df[order( df[,1], df[,2] ),] 
   Var1       Var2
1   ABC 2012-05-01
4   ABC 2012-05-02
7   ABC 2012-05-03
10  ABC 2012-05-04
13  ABC 2012-05-05
2   DEF 2012-05-01
5   DEF 2012-05-02
8   DEF 2012-05-03
11  DEF 2012-05-04
14  DEF 2012-05-05
3   GHI 2012-05-01
6   GHI 2012-05-02
9   GHI 2012-05-03
12  GHI 2012-05-04
15  GHI 2012-05-05`
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.