90 votes

Collage de deux vecteurs avec des combinaisons de tous les éléments des vecteurs

J'ai deux vecteurs :

vars <- c("SR", "PL")
vis <- c(1,2,3)

Sur la base de ces vecteurs, je voudrais créer le vecteur suivant :

"SR.1"  "SR.2"  "SR.3"  "PL.1"  "PL.2"  "PL.3"

Avec paste J'obtiens le résultat suivant :

paste(vars, vis, sep=".")
 [1] "SR.1" "PL.2" "SR.3"

Comment puis-je créer le vecteur dont j'ai besoin ?

98voto

juba Points 15701

Vous pouvez l'utiliser, mais il existe peut-être une solution plus simple :

R> apply(expand.grid(vars, vis), 1, paste, collapse=".")
[1] "SR.1" "PL.1" "SR.2" "PL.2" "SR.3" "PL.3"

expand.grid redonne un data.frame qui, lorsqu'il est utilisé avec apply , apply le convertira en un matrix . C'est tout simplement inutile (et inefficace sur les grandes données). outer donne un matrix et prend également un argument de fonction. Il sera également plus efficace pour les données volumineuses.

Utilisation de outer :

as.vector(outer(vars, vis, paste, sep="."))
# [1] "SR.1" "PL.1" "SR.2" "PL.2" "SR.3" "PL.3"

46voto

ewancarr Points 561

Une autre option consiste à utiliser le each argument de rep :

paste(rep(vars, each = length(vis)), vis, sep = ".")

Je trouve cela plus simple que les solutions basées sur apply o expand.grid .

21voto

Jaap Points 3814

Une autre option utilisant sprintf en combinaison avec expand.grid :

eg <- expand.grid(vis, vars)
sprintf('%s.%s', eg[,2], eg[,1])

ce qui donne :

[1] "SR.1" "SR.2" "SR.3" "PL.1" "PL.2" "PL.3"

Explication :

  • Avec expand.grid vous créez toutes les combinaisons des deux vecteurs.
  • sprintf colle les deux vecteurs ensemble selon le format spécifié ( '%s.%s' ). Chaque %s du format est remplacé par les éléments des vecteurs.

12voto

Uwe Points 21553

Cette ancienne question a déjà une réponse acceptée. Mais comme elle est utilisée comme cible de doublon, je pense qu'il est utile d'ajouter une réponse à cette question. data.table qui utilise le joint croisé función CJ() :

library(data.table) 
options(datatable.CJ.names=FALSE) # required with version version 1.12.0+
CJ(vars, vis)[, paste(V1, V2, sep =".")]
#[1] "PL.1" "PL.2" "PL.3" "SR.1" "SR.2" "SR.3"

Dans le cas où la commande originale est importante :

CJ(vars, vis, sorted = FALSE)[, paste(V1, V2, sep =".")]
#[1] "SR.1" "SR.2" "SR.3" "PL.1" "PL.2" "PL.3"

Edita: CJ() a changé de comportement par défaut avec la version 1.12.0

Comme annoncé dans le notes de publication de la version 1.12.0 (Point 3) l'option par défaut options(datatable.CJ.names=TRUE) a changé. CJ() nomme maintenant automatiquement ses entrées exactement as data.table() fait.

Ainsi, le code ci-dessus doit être modifié pour data.table version 1.12.0 et supérieure :

library(data.table)   ### version 1.12.0+
CJ(vars, vis)[, paste(vars, vis, sep =".")]

y

CJ(vars, vis, sorted = FALSE)[, paste(vars, vis, sep =".")]

resp.

9voto

Anon Points 11025

Pour maintenir l'ordre des chaînes de caractères demandées dans la question, vous pouvez utiliser ces deux modifications des deux méthodes :

Changer l'ordre des vecteurs et les combiner en ordre inverse

apply(expand.grid(vis, vars), 1, function(x) paste(x[2], x[1], sep=".")) 
[1] "SR.1" "SR.2" "SR.3" "PL.1" "PL.2" "PL.3"

ou transposer la matrice avant de la convertir en vecteur :

as.vector(t(outer(vars, vis, paste, sep="."))) 
[1] "SR.1" "SR.2" "SR.3" "PL.1" "PL.2" "PL.3"

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