我正在尝试创建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
所以基本上,我正在寻找一个独特的组合,考虑一个向量的所有元素(a)与第二个向量(b)的所有元素并列。
理想的解决方案可以推广到更多的输入向量。
答案 0 :(得分:113)
这可能就是你追求的目标
> 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
概括为任意数量的输入列。
答案 1 :(得分:20)
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
答案 2 :(得分:6)
此r-faq概述中缺少的是data.table包中的CJ
函数。使用:
library(data.table)
CJ(a = a, b = 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
在data.table的将来版本中,您可以使用:CJ(a, b, unique = TRUE)
(另请参见here和here)。
通过设置选项options("datatable.CJ.names" = TRUE)
,您已经可以充分利用此功能。
答案 3 :(得分:1)
您可以使用订单功能对任意数量的列进行排序。为你的例子
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`
答案 4 :(得分:1)
从1.0.0版开始,tidyr
提供了自己的expand.grid()
版本。 completes the existing family of expand()
, nesting()
, and crossing()
with a low-level function that works with vectors。
与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