web-dev-qa-db-fra.com

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 à partir de deux vecteurs de taille différente en R.

Par exemple, le premier vecteur est

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

et le second est les dates stockées sous forme de chaînes 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 bloc de données avec deux colonnes comme celle-ci

> 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

Donc, fondamentalement, je recherche 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 généraliserait à plus de vecteurs d’entrée.


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

82
Godel

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 résultant n'est pas ce que vous voulez, vous pouvez trier après. Si vous nommez les arguments à expand.grid, ils deviendront des noms de colonne:

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

Et expand.grid se généralise à un nombre quelconque de colonnes en entrée.

116

Le paquet tidyr fournit l’alternative Nice crossing, qui fonctionne mieux que le classique expand.grid fonctionne parce que (1) les chaînes 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
21
hypothesis

Il manque dans cet r-faq la fonction CJ- du paquet data.table -. En utilisant:

library(data.table)
CJ(a = a, b = 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

Dans les futures versions de data.table , vous pouvez simplement utiliser: CJ(a, b, unique = TRUE) (voir aussi ici et ici ).

Vous pouvez déjà tirer parti de cette fonctionnalité en définissant les options: options("datatable.CJ.names" = TRUE).

7
Jaap

vous pouvez utiliser la fonction order pour trier un nombre quelconque de colonnes. pour votre exemple

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`
2
izan