IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

R Discussion :

Créer une data.frame à partir de plusieurs listes


Sujet :

R

  1. #1
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 16
    Points : 18
    Points
    18
    Par défaut Créer une data.frame à partir de plusieurs listes
    Bonjour,

    Je reviens encore vers vous pour un problème de traitement de données que j'ai extraites du web.
    J'ai extrait le contenu de petites annonces dont une partie se présentait sous forme de table. Voici les codes de mon extraction, mais ce ne sont pas eux qui posent problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    doc<-htmlParse("http://www.leboncoin.fr/_loisirs_/offres/ile_de_france/?f=a&th=1")
     
    lien<-xpathSApply (doc,
                       "//div[contains(@class,'list-lbc')]/a",
                       xmlGetAttr,name = "href")
    v<-NA
    for (i in 1:length(lien)) {
      v[i]<- readHTMLTable(lien[i], head=2) }
    Mon extraction m'a donné l'objet "v" qui est un ensemble de listes qui se présentent sous cette forme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [[1]]
                 V1            V2
    1         Prix:          102       Ville : Saint-Maurice
    3 Code postal :         94410
     
    [[2]]
                 V1      V2
    1         Prix:    122       Ville : Thomery
    3 Code postal :   77810
    En réalité, je souhaiterais transformer ces résultats brut pour obtenir un seul data.frame qui se présenterait comme ça :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	Prix	   Ville	               Code
    1	10 €	  Saint Maurice	     94410
    2      12 €    Thomery               77810
    J'ai réussi à arriver à cette transformation pour une table en écrivant les codes suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    u<-htmlParse("http://www.leboncoin.fr/livres/394455341.htm?ca=12_s")
    b<- readHTMLTable(u, head = 2)
     
    vt<-as.data.frame(b)
    vtbis<-as.data.frame(vt[c(2)])
    prix<-vtbis[1,]
    ville<-vtbis[2,]
    code<-vtbis[3,]
     
    Table<-data.frame(prix,ville,code)
    Mais mon problème est toujours le même, je n'arrive pas à réaliser cette opération sur l'ensemble de mes listes en une seule fois...
    J'ai essayé des boucles FOR, des fonctions sapply, mais ça n'a pas fonctionné..

    Je ne sais pas si c'est parce que je ne sais pas les écrire car je suis débutante en R, ou bien si je dois essayer d'autres pistes. Est-il possible de sélectionner sur toutes mes listes la seconde colonne et de la transformer en un seul data.frame ?

    Je vous remercie d'avance si vous avez des idées sur ce problème.

  2. #2
    Inactif  
    Profil pro
    " "
    Inscrit en
    Janvier 2008
    Messages
    330
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : " "

    Informations forums :
    Inscription : Janvier 2008
    Messages : 330
    Points : 254
    Points
    254
    Par défaut
    Bonjour,

    Une petite idée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    MyTable <- data.frame()
    u <- htmlParse("http://www.leboncoin.fr/livres/394455341.htm?ca=12_s")
    b <- readHTMLTable(u, head = 2)
    for (i in 1:length(b)){
      val <- as.character(b[[i]]$V2)
      for (j in 1:3){
        MyTable[i,j] <- val[j]
      }
    }
     
    names(MyTable) <- c("Prix", "Ville", "CodePostal")
    BC

  3. #3
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 16
    Points : 18
    Points
    18
    Par défaut
    ohh merci beaucoup c'est génial!! C'est donc une double boucle, je ne savais pas comment faire. Merci mille fois.

    Malheureusement, je me retrouve face à un autre souci. Je ne voudrais pas abuser de votre gentillesse...

    En fait dans mes données obtenues à partir de ce code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    doc<-htmlParse("http://www.leboncoin.fr/_loisirs_/offres/ile_de_france/?f=a&th=1")
     
    lien<-xpathSApply (doc,
                       "//div[contains(@class,'list-lbc')]/a",
                       xmlGetAttr,name = "href")
     
    v<-NA
    for (i in 1:length(lien)) {
      v[i]<- readHTMLTable(lien[i], head=2) }
    J'obtiens mon objet v, mais malheureusement les tables du site leboncoin ne sont pas toutes de la même taille, car le prix ou la ville n'est pas toujours renseigné … du coup lors de mon export, j'ai des tables à 3 lignes et des tables à 2 lignes.

    Ce qui donne le fait qu'après avoir appliqué votre code (merci encore) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    MyTable <- data.frame()
     
    for (i in 1:length(v)){
      val <- as.character(v[[i]]$V2)
      for (j in 1:3){
        MyTable[i,j] <- val[j]
      }
    }
     
    names(MyTable) <- c("Prix", "Ville", "CodePostal")
    J'obtiens le résultat suivant, où mes tables à 2 lignes se retrouvent décalées sur la gauche avec une valeur NA pour le code postal... Et chose encore plus compliquée : dès fois il manque la ville, et des fois il manque le prix...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     	Prix	Ville	CodePostal
    1	100 €	Eaubonne	95600
    2	3 €	Paris	75017
    3	50 €	Andrésy	78570
    4	15 €	Eaubonne	95600
    5	500 €	Paris	75001
    6	13 €	Saclas	91690
    7	750 €	Argenteuil	95100
    8	50077000	NA
    9	3 €	Sucy-en-Brie	94370
    10	Bondy	93140	NA
    11	5 €	Meulan	78250

    J'ai donc pensé qu'il fallait modifier mon vecteur 'v' avant de le transformer en table en créant de nouvelles lignes à la place des manquantes et en décalant mes données, pour celles qui posent problème, par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    [[20]]
                 V1    V2
    1       Ville : Paris
    2 Code postal : 75020
     
    [[8]]
                 V1    V2
    1         Prix: 5002 Code postal : 77000

    J'ai essayé une fonction if/else, pour tenter de décaler mes lignes, mais elle ne fonctionne pas...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for (l in 1 :length(v)) {
      if (v[1,i]="Ville") {(v[1,i]=v[2,i] (v[2,i] =(v[3,i] ) )}
    else if {((v[2,i])="Code postal") (v[2,i])=v[3,i])}
    }
    R me renvoie les erreurs suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Erreur : '=' inattendu(e) dans :
    "for (l in 1 :length(v)) {
      if (v[1,i]="
    Erreur : 'else' inattendu(e) dans "else"
    Erreur : '}' inattendu(e) dans "}"
    Je ne sais pas si la fonction if accepte plusieurs résultats à une condition ? Je ne comprends pas pourquoi il n'accepte pas mon "=". Est-ce que mes conditions vont permettre de créer pour ces tables sélectionnées une nouvelle ligne ?

    Je vous remercie déjà pour tout, j'ai réussi grâce à vous à quasiment terminer ce programme, cela fait 15 jours que je suis dessus... Je vous remercie mille fois si vous avez encore une solution à ce énième problème de script...

  4. #4
    Inactif  
    Profil pro
    " "
    Inscrit en
    Janvier 2008
    Messages
    330
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : " "

    Informations forums :
    Inscription : Janvier 2008
    Messages : 330
    Points : 254
    Points
    254
    Par défaut
    Bonjour,
    Pour ce genre de données, je pense qu'il serait judicieux d'utiliser les expression regulieres et en particulier la fonctionC'est une fonction permet entre autre de l'indice d'un motif. Par exemple si le mot prix est au debut, à la fin, ...
    Voila ce quoi à j'ai pensé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    doc <- htmlParse("http://www.leboncoin.fr/_loisirs_/offres/ile_de_france/?f=a&th=1")
    lien <- xpathSApply (doc,"//div[contains(@class,'list-lbc')]/a",xmlGetAttr,name = "href")
     
    MyTable <- data.frame()
    v <- NULL
    for (i in 1:length(lien)) {
      v[i] <- readHTMLTable(lien[i], head=2)
      val <- as.character(v[[i]]$V2)
      # un prix, c'est toute valeur commençant par des chiffres et se terminant par €
      prix <- grep('^[0-9].*[^a-zA-Z0-9]$', val2, perl=T)
      if (length(prix)!=0) { MyTable[i,1] <- val[prix] } else  {MyTable[i,1] <- NA } 
      # une ville, c'est tout ce qui commence par des lettres et ne contenant pas de chiffres
      # on suppose que les noms des villes depassent au moins 4 carateres, c'est à corriger bien sûr. Mais le souci vient de v[[13]]
      vil <- grep('^[a-zA-Z].{4,1000}$', val, perl=T)
      if (length(vil)!=0) { MyTable[i,2] <- val[vil] } else  {MyTable[i,2] <- NA } 
      # une code postale: c'est exactement 5 chiffre, sans le signe € et sans lettre alphabetiques
      cp <- grep('^[0-9]{5}$', val, perl=T) 
      if (length(cp)!=0) { MyTable[i,3] <- val[cp] } else  {MyTable[i,3] <- NA }  
    }
     
    names(MyTable) <- c("Prix", "Ville", "CodePostale")
    N’hésite à faire un retour des bugs.
    Bon courage

  5. #5
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 16
    Points : 18
    Points
    18
    Par défaut
    Bonjour,

    Une réponse bien tardive, mais je vous dit un grand merci pour votre aide, le programme fonctionne !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 14/03/2014, 23h20
  2. Je veux créer une date ISO à partir de plusieurs ints
    Par magnus2229 dans le forum Langage
    Réponses: 7
    Dernier message: 20/07/2011, 13h46
  3. Réponses: 1
    Dernier message: 04/05/2005, 11h43
  4. [SUM] récuperer une quantite a partir de plusieurs table
    Par Snowballz dans le forum PostgreSQL
    Réponses: 9
    Dernier message: 14/09/2004, 18h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo