Unikalne połączenie wszystkich elementów z dwóch (lub więcej) wektorów

98

Staram się stworzyć unikalną kombinację wszystkich elementów z dwóch wektorów różnej wielkości w R.

Na przykład pierwszy wektor to

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

a druga to daty przechowywane obecnie jako ciągi znaków

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

Muszę utworzyć ramkę danych z dwiema kolumnami, takimi jak ta

> 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

Zasadniczo szukam unikalnej kombinacji, biorąc pod uwagę wszystkie elementy jednego wektora (a) zestawione ze wszystkimi elementami drugiego wektora (b).

Idealne rozwiązanie uogólniłoby na więcej wektorów wejściowych.


Zobacz też:
Jak wygenerować macierz kombinacji

Godel
źródło

Odpowiedzi:

143

może tego szukasz

> 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

Jeśli wynikowa kolejność nie jest tym, czego chcesz, możesz później posortować. Jeśli nazwiesz argumenty na expand.grid, staną się one nazwami kolumn:

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

I expand.griduogólnia dowolną liczbę kolumn wejściowych.

shhhhimhuntingrabbits
źródło
4
I bez konieczności plyrsortowania:result <- expand.grid(a=a,b=b); result <- result[order(result$a,result$b),];
thelatemail
czy ktoś z większą liczbą przedstawicieli niż ja jest w stanie zaakceptować tę odpowiedź?
Josh
Jeśli kolejność i nazwy powinny być takie jak w pytaniu:expand.grid(b=b,a=a)[2:1]
GKi
Zwróć uwagę, że tytuł to Unique Combinations - ta odpowiedź rozwiązuje problem OP, ale jeśli dwie kolumny są tego samego typu danych i zastosujesz expand.grid, będziesz mieć unikalne permutacje, a nie unikalne kombinacje
Brent
30

tidyrPakiet zawiera alternatywę ładne crossing, który działa lepiej niż klasycznych expand.gridfunkcji, ponieważ (1) struny nie są konwertowane na czynniki i (2) sortowanie jest bardziej intuicyjny:

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
hipoteza
źródło
13

Brakuje w tym przegląd to CJfunkcja z pliku-pakiet. Za pomocą:

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

daje:

      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

UWAGA: od wersji 1.12.2 automatycznie CJnadaje nazwy wynikowym kolumnom (zobacz także tutaj i tutaj ).

Jaap
źródło
4

Od wersji 1.0.0 tidyroferuje własną wersję expand.grid(). To uzupełnia istniejącą rodzinę expand(), nesting()oraz crossing()z funkcji niskiego poziomu, który współpracuje z wektorami .

W porównaniu z base::expand.grid():

Najszybciej zmienia pierwszy element. Nigdy nie konwertuje ciągów znaków na czynniki. Nie dodaje żadnych dodatkowych atrybutów. Zwraca tibble, a nie ramkę danych. Może rozszerzyć dowolny uogólniony wektor, w tym ramki danych.

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
tmfmnk
źródło
3

możesz użyć funkcji kolejności do sortowania dowolnej liczby kolumn. na twój przykład

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`
izan
źródło