Kombinasi unik dari semua elemen dari dua (atau lebih) vektor

97

Saya mencoba membuat kombinasi unik dari semua elemen dari dua vektor dengan ukuran berbeda di R.

Misalnya, vektor pertama adalah

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

dan yang kedua adalah tanggal yang disimpan sebagai string saat ini

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

Saya perlu membuat bingkai data dengan dua kolom seperti ini

> 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

Jadi pada dasarnya, saya mencari kombinasi unik dengan mempertimbangkan semua elemen dari satu vektor (a) disandingkan dengan semua elemen vektor kedua (b).

Solusi ideal akan menggeneralisasi ke lebih banyak vektor input.


Lihat juga:
Bagaimana membuat matriks kombinasi

Godel
sumber

Jawaban:

141

ini mungkin yang kamu cari

> 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

Jika urutan yang dihasilkan bukanlah yang Anda inginkan, Anda dapat mengurutkan setelahnya. Jika Anda menamai argumen dengan expand.grid, argumen itu akan menjadi nama kolom:

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

Dan expand.gridmenggeneralisasi ke sejumlah kolom input.

shhhhimhuntingrabbits
sumber
4
Dan tanpa perlu plyrmelakukan semacam:result <- expand.grid(a=a,b=b); result <- result[order(result$a,result$b),];
thelatemail
apakah seseorang dengan reputasi lebih dari saya dapat menerima jawaban ini?
Josh
Jika urutan dan nama harus seperti dalam pertanyaan:expand.grid(b=b,a=a)[2:1]
GKi
Perhatikan bahwa judulnya adalah Kombinasi Unik - jawaban ini memecahkan masalah OP, tetapi jika 2 kolom memiliki tipe data yang sama dan Anda menerapkan expand.grid, Anda akan memiliki permutasi unik, bukan kombinasi unik
Brent
29

The tidyrpaket menyediakan bagus alternatif crossing, yang bekerja lebih baik daripada klasik expand.gridfungsi karena (1) string tidak diubah menjadi faktor dan (2) menyortir lebih intuitif:

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
hipotesa
sumber
13

Hilang dalam hal ini ikhtisar adalah CJ -fungsi dari-paket. Menggunakan:

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

memberikan:

      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

CATATAN: karena versi 1.12.2 CJmemberi nama otomatis kolom yang dihasilkan (lihat juga di sini dan di sini ).

Jaap
sumber
4

Sejak versi 1.0.0, tidyrmenawarkan versinya sendiri expand.grid(). Ini melengkapi keluarga yang ada expand(), nesting()dancrossing() dengan fungsi tingkat rendah yang bekerja dengan vektor .

Jika dibandingkan dengan base::expand.grid():

Memvariasikan elemen pertama tercepat. Jangan pernah mengonversi string menjadi faktor. Tidak menambahkan atribut tambahan apa pun. Mengembalikan tibble, bukan bingkai data. Dapat memperluas vektor umum apa pun, termasuk bingkai data.

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
sumber
3

Anda dapat menggunakan fungsi order untuk mengurutkan sejumlah kolom. sebagai contoh Anda

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
sumber