142 votes

Combinaison unique de tous les éléments de deux vecteurs (ou plus)

J'essaie de créer une combinaison unique de tous les éléments de deux vecteurs de taille différente dans R.

Par exemple, le premier vecteur est

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

et la seconde est constituée de dates stockées sous forme de chaînes de caractères actuellement

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

J'ai besoin de créer un cadre de données avec deux colonnes comme suit

> 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

En gros, je cherche une combinaison unique en considérant tous les éléments d'un vecteur (a) juxtaposés à tous les éléments du second vecteur (b).

Une solution idéale se généraliserait à un plus grand nombre de vecteurs d'entrée.


Voir aussi
Comment générer une matrice de combinaisons

173voto

C'est peut-être ce que vous recherchez

> 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 l'ordre obtenu n'est pas celui que vous souhaitez, vous pouvez effectuer un tri a posteriori. Si vous nommez les arguments de expand.grid ils deviendront des noms de colonnes :

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

Et expand.grid se généralise à n'importe quel nombre de colonnes d'entrée.

47voto

hypothesis Points 106

Les tidyr offre une alternative intéressante crossing qui fonctionne mieux que la méthode classique expand.grid car (1) les chaînes de caractères ne sont pas converties en facteurs et (2) le tri est plus intuitif :

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

25voto

Jaap Points 3814

Manque dans cette r-faq La vue d'ensemble est la CJ -de la fonction tableau.de.données -Emballage. L'utilisation :

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

donne :

      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

NOTE : depuis la version 1.12.2 <code>CJ</code> nomme automatiquement les colonnes résultantes (voir aussi <a href="https://github.com/Rdatatable/data.table/pull/3296" rel="noreferrer">aquí </a>y <a href="https://github.com/Rdatatable/data.table/issues/3295" rel="noreferrer">aquí </a>).

9voto

tmfmnk Points 8978

Depuis la version 1.0.0, tidyr propose sa propre version de expand.grid() . Il complète la famille existante des expand() , nesting() et crossing() avec une fonction de bas niveau qui travaille avec des vecteurs .

Par rapport aux base::expand.grid() :

Varie le premier élément le plus rapidement. Ne convertit jamais les chaînes de caractères en facteurs. N'ajoute pas d'attributs supplémentaires. Renvoie un tibble, pas un cadre de données données. Peut développer n'importe quel vecteur généralisé, y compris les cadres de données.

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

4voto

izan Points 41

Vous pouvez utiliser la fonction order pour trier un nombre quelconque de colonnes.

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`

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X