extraction d'elements communs

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

francois guilhaumon
Messages : 14
Enregistré le : 27 Mar 2007, 08:51
Contact :

extraction d'elements communs

Messagepar francois guilhaumon » 31 Aoû 2007, 11:26

Bonjour,

J'ai un problème algorithmique et je voudrais savoir si il existe une fonction dédiée.

J'ai 3 vecteurs de chaînes de caractères et je souhaite extraire de chacun de ces vecteurs les éléments qui sont communs aux 3 vecteurs.

Je vois une manière non élégante de résoudre le problème mais je souhaiterai savoir si il existe une fonction dédiée a cette tache.

Merci d'avance pour vos réponses.

francois.

Nicolas Péru
Messages : 1408
Enregistré le : 07 Aoû 2006, 08:13

Messagepar Nicolas Péru » 31 Aoû 2007, 11:46

juste quelques pistes qui me viennent comme ça...peut être avec les fonctions intersect ou match...à fouiller ;)

Désolé de ne pouvoir vous donner plus d'éléments pour le moment.

Nicolas

francois guilhaumon
Messages : 14
Enregistré le : 27 Mar 2007, 08:51
Contact :

Messagepar francois guilhaumon » 31 Aoû 2007, 11:57

merci pour les pistes.

Effectivement je pense jouer avec des match ou des %in% mais je vais devoir prevoir des aller retour et je ne trouve pas cela tres elegant (voir efficace) ...

Renaud Lancelot
Messages : 2484
Enregistré le : 16 Déc 2004, 08:01
Contact :

Messagepar Renaud Lancelot » 31 Aoû 2007, 12:39

Un petite exemple serait utile pour mieux cerner ce que vous cherchez à faire.

Renaud

Nicolas Péru
Messages : 1408
Enregistré le : 07 Aoû 2006, 08:13

Messagepar Nicolas Péru » 31 Aoû 2007, 13:11

je ne comprends pas à quoi vous faites allusion par "aller-retour". S'il s'agit bien de prendre l'intersection des trois ensembles (a,b,c) alors vous pouvez bien d'abord faire l'intersection des deux premiers (a et b par exemple) facteurs ce qui vous donne un facteur ab, puis faire l'intersection ab, c et cous aurez les valeurs commmunes au trois ensembles., non ?. Une fois, ce facteur de "référence" en main il faut extraire de chaque ensemble ces valeurs avec leurs doublons (si j'ai bien compris le but de la manoeuvre), là dessus peut être que la librairie RODBC peut être utile...je ne la connais pas bien.

Nicolas

francois guilhaumon
Messages : 14
Enregistré le : 27 Mar 2007, 08:51
Contact :

Messagepar francois guilhaumon » 31 Aoû 2007, 13:24

une reformalisation du problème avec un exemple :

J'ai 3 (ou plus) vecteurs de chaînes de caractères représentant des classement croissant, par exemple le rang de pays dans un classement sportif pour trois disciplines:

dis1 = c("france","hongrie","maroc","angleterre","espagne","italie","tunisie")
dis2 = c("hongrie","angleterre","france","espagne","tunisie","belgique")
dis3 = c("espagne","angleterre","france","monaco","allemagne","belgique","turquie","portugal","grece")

Mon but est de créer trois nouveaux vecteurs (un par discipline) contenant uniquement les éléments en commun aux trois classements, le tout en conservant l'ordre dans les classements. Autrement dit, mon but est d'obtenir les vecteurs suivants:

newDis1 = c("france","angleterre","espagne")
newDis2 = c("angleterre","france","espagne")
newDis3 = c("espagne","angleterre","france")

Voila. Je cherche une méthode me permettant d'automatiser cette procedure. Je pense jouer avec des intersect() mais j'aimerai créer une fonction fonctionnant pour tout nombre de vecteurs.

Renaud Lancelot
Messages : 2484
Enregistré le : 16 Déc 2004, 08:01
Contact :

Messagepar Renaud Lancelot » 31 Aoû 2007, 15:31

Par exemple:

Code : Tout sélectionner

> dis1 <- c("france","hongrie","maroc","angleterre","espagne","italie","tunisie")
> dis2 <- c("hongrie","angleterre","france","espagne","tunisie","belgique")
> dis3 <- c("espagne","angleterre","france","monaco","allemagne","belgique","turquie","portugal","grece")
>
> common <- function(x, ...){
+   if(length(list(...))){
+     x <- list(x, ...)
+     v <- x[[1]]
+     for(i in 2:length(x))
+       v <- intersect(v, x[[i]])
+     lapply(x, function(x) x[is.element(x, v)])
+     }
+   else x
+   }
>
> common(dis1)
[1] "france"     "hongrie"    "maroc"      "angleterre" "espagne"    "italie"     "tunisie"   
> common(dis1, dis2)
[[1]]
[1] "france"     "hongrie"    "angleterre" "espagne"    "tunisie"   

[[2]]
[1] "hongrie"    "angleterre" "france"     "espagne"    "tunisie"   

> common(dis2, dis3)
[[1]]
[1] "angleterre" "france"     "espagne"    "belgique" 

[[2]]
[1] "espagne"    "angleterre" "france"     "belgique" 

> common(dis1, dis2, dis3)
[[1]]
[1] "france"     "angleterre" "espagne"   

[[2]]
[1] "angleterre" "france"     "espagne"   

[[3]]
[1] "espagne"    "angleterre" "france"   



La version ci-dessous est un peu plus sophistiquée: elle nomme les éléments de la liste retournée avec le nom des vecteurs correspondants.

Code : Tout sélectionner

common <- function(x, ...){
    # récupère les noms de vecteurs
    if(length(list(...))){
        mCall <- match.call(expand.dots = TRUE)
        dots <- list(...)
        vects <- c(list(x, dots))
        nam <- sapply(as.list(mCall)[-1], as.character)
    # cherche les éléments communs
        x <- list(x, ...)
        v <- x[[1]]
        for(i in 2:length(x))
            v <- intersect(v, x[[i]])
    # sélectionne les éléments communs
        res <- lapply(x, function(x) x[is.element(x, v)])
    # nomme les éléments de la liste
        names(res) <- nam
        res
        }
  else x
  }


Renaud

francois guilhaumon
Messages : 14
Enregistré le : 27 Mar 2007, 08:51
Contact :

Messagepar francois guilhaumon » 03 Sep 2007, 07:33

merci infiniment pour cette fonction.

J'en apprend bcp sur le jeu avec les parametres suplémentaires. La creation de la liste pour ensuite utiliser lapply est assez elegante il faut dire.

A bientot.


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité