2つ(またはそれ以上)のベクトルからのすべての要素の一意の組み合わせ


95

Rでサイズの異なる2つのベクトルからすべての要素の一意の組み合わせを作成しようとしています。

たとえば、最初のベクトルは

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

2番目は現在文字列として保存されている日付です

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

このように2列のデータフレームを作成する必要があります

> 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

したがって、基本的には、1つのベクトルのすべての要素(a)を2番目のベクトル(b)のすべての要素と並べて考えることによって、ユニークな組み合わせを探しています。

理想的な解決策は、より多くの入力ベクトルに一般化することです。


参照:
組み合わせの行列を生成する方法

回答:


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

私よりも担当者が多い人はこの回答を受け入れることができますか?
Josh、

順序と名前が質問のとおりである場合:expand.grid(b=b,a=a)[2:1]
GKi

タイトルが一意の組み合わせであることに注意してください-この回答はOPの問題を解決しますが、2つの列が同じデータ型で、expand.gridを適用すると、一意の組み合わせではなく、一意の組み合わせになります
ブレント

27

このtidyrパッケージは、(1)文字列が因子に変換されないため、(2)ソートがより直感的であるためcrossing、従来のexpand.grid関数よりも優れた優れた代替手段を提供します。

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`
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.