Combinazione unica di tutti gli elementi di due (o più) vettori


95

Sto cercando di creare una combinazione unica di tutti gli elementi da due vettori di dimensioni diverse in R.

Ad esempio, il primo vettore è

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

e il secondo sono le date attualmente memorizzate come stringhe

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

Devo creare un data frame con due colonne come questa

> 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

Quindi, in pratica, sto cercando una combinazione unica considerando tutti gli elementi di un vettore (a) giustapposti con tutti gli elementi del secondo vettore (b).

Una soluzione ideale sarebbe generalizzare a più vettori di input.


Vedi anche:
Come generare una matrice di combinazioni

Risposte:


139

questo forse quello che stai cercando

> 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 l'ordine risultante non è quello che desideri, puoi ordinare in seguito. Se assegni un nome agli argomenti expand.grid, diventeranno nomi di colonna:

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

E expand.gridgeneralizza a qualsiasi numero di colonne di input.


4
E senza dover plyrfare solo una sorta:result <- expand.grid(a=a,b=b); result <- result[order(result$a,result$b),];
telegrafo

qualcuno con più rappresentanza di me è in grado di accettare questa risposta?
Josh

Se l'ordine e i nomi devono essere come nella domanda:expand.grid(b=b,a=a)[2:1]
GKi

Nota che il titolo è Combinazioni uniche - questa risposta risolve il problema OP, ma se le 2 colonne sono dello stesso tipo di dati e applichi expand.grid, avrai permutazioni uniche, non combinazioni uniche
Brent

27

Il tidyrpacchetto fornisce una bella alternativa crossing, che funziona meglio della expand.gridfunzione classica perché (1) le stringhe non vengono convertite in fattori e (2) l'ordinamento è più intuitivo:

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

Manca in questo panoramica è la CJ-funzione dal-pacchetto. Utilizzando:

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: dalla versione 1.12.2 CJnomina automaticamente le colonne risultanti (vedi anche qui e qui ).


4

Dalla versione 1.0.0, tidyroffre la propria versione di expand.grid(). Si completa la famiglia esistente di expand(), nesting()e crossing()con una funzione di basso livello che funziona con i vettori .

Rispetto a base::expand.grid():

Varia il primo elemento più veloce. Non converte mai le stringhe in fattori. Non aggiunge attributi aggiuntivi. Restituisce una tabella, non un frame di dati. Può espandere qualsiasi vettore generalizzato, compresi i frame di dati.

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

è possibile utilizzare la funzione di ordine per ordinare un numero qualsiasi di colonne. per il tuo esempio

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`
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.