Combinação única de todos os elementos de dois (ou mais) vetores


94

Estou tentando criar uma combinação única de todos os elementos de dois vetores de tamanhos diferentes em R.

Por exemplo, o primeiro vetor é

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

e o segundo são as datas armazenadas como strings atualmente

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

Eu preciso criar um quadro de dados com duas colunas como esta

> 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

Então, basicamente, estou procurando uma combinação única considerando todos os elementos de um vetor (a) justapostos com todos os elementos do segundo vetor (b).

Uma solução ideal seria generalizar para mais vetores de entrada.


Veja também:
Como gerar uma matriz de combinações

Respostas:


138

isso talvez seja o que você está procurando

> 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

Se a ordem resultante não for a que você deseja, você pode classificar depois. Se você nomear os argumentos como expand.grid, eles se tornarão nomes de colunas:

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

E expand.gridgeneraliza para qualquer número de colunas de entrada.


4
E sem precisar plyrapenas fazer uma espécie:result <- expand.grid(a=a,b=b); result <- result[order(result$a,result$b),];
thelatemail

Alguém com mais reputação do que eu é capaz de aceitar essa resposta?
Josh

Se a ordem e os nomes devem ser como na pergunta:expand.grid(b=b,a=a)[2:1]
GKi

Observe que o título é Combinações únicas - esta resposta resolve o problema de OP, mas se as 2 colunas forem do mesmo tipo de dados e você aplicar expand.grid, você terá permutações exclusivas, não combinações exclusivas
Brent

27

O tidyrpacote oferece uma boa alternativa crossing, que funciona melhor do que a expand.gridfunção clássica porque (1) as strings não são convertidas em fatores e (2) a classificação é mais intuitiva:

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

Faltando neste visão geral é a CJfunção - do-pacote. Usando:

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

dá:

      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

NOTA: desde a versão 1.12.2, CJas colunas resultantes são autonames (veja também aqui e aqui ).


4

Desde a versão 1.0.0, tidyroferece sua própria versão do expand.grid(). Ele completa a família existente de expand(), nesting()e crossing()com uma função de baixo nível que funciona com vetores .

Quando comparado com base::expand.grid():

Varia o primeiro elemento mais rápido. Nunca converte strings em fatores. Não adiciona nenhum atributo adicional. Retorna um tibble, não um quadro de dados. Pode expandir qualquer vetor generalizado, incluindo frames de dados.

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

2

você pode usar a função de ordem para classificar qualquer número de colunas. pelo seu exemplo

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`
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.