Combinación única de todos los elementos de dos (o más) vectores


95

Estoy tratando de crear una combinación única de todos los elementos de dos vectores de diferente tamaño en R.

Por ejemplo, el primer vector es

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

y el segundo son las fechas almacenadas como cadenas actualmente

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

Necesito crear un marco de datos con dos columnas 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

Entonces, básicamente, estoy buscando una combinación única al considerar todos los elementos de un vector (a) yuxtapuestos con todos los elementos del segundo vector (b).

Una solución ideal se generalizaría a más vectores de entrada.


Ver también:
Cómo generar una matriz de combinaciones

Respuestas:


139

esto tal vez lo que buscas

> 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

Si el orden resultante no es el que desea, puede ordenar después. Si nombra los argumentos a expand.grid, se convertirán en nombres de columna:

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

Y expand.gridgeneraliza a cualquier número de columnas de entrada.


4
Y sin necesidad plyrde hacer una clasificación:result <- expand.grid(a=a,b=b); result <- result[order(result$a,result$b),];
thelatemail

¿Alguien con más reputación que yo puede aceptar esta respuesta?
Josh

Si el orden y los nombres deben ser como en la pregunta:expand.grid(b=b,a=a)[2:1]
GKi

Tenga en cuenta que el título es Combinaciones únicas: esta respuesta resuelve el problema de OP, pero si las 2 columnas son del mismo tipo de datos y aplica expand.grid, tendrá permutaciones únicas, no combinaciones únicas
Brent

28

El tidyrpaquete proporciona una buena alternativa crossing, que funciona mejor que la expand.gridfunción clásica porque (1) las cadenas no se convierten en factores y (2) la clasificación es más 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

Falta en esto descripción general es la CJfunción de la-paquete. Utilizando:

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

da:

      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: dado que la versión 1.12.2 nombra CJautomáticamente las columnas resultantes (consulte también aquí y aquí ).


4

Desde la versión 1.0.0, tidyrofrece su propia versión de expand.grid(). Se completa la familia existente de expand(), nesting()y crossing()con una función de bajo nivel que trabaja con vectores .

En comparación con base::expand.grid():

Varía el primer elemento más rápido. Nunca convierte cadenas en factores. No agrega ningún atributo adicional. Devuelve un tibble, no un marco de datos. Puede expandir cualquier vector generalizado, incluidos los marcos de datos.

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

puede utilizar la función de orden para ordenar cualquier número de columnas. por tu ejemplo

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`
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.