océrisation et reformatage des données

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

Wilfrid Car
Messages : 59
Enregistré le : 09 Avr 2015, 13:35

océrisation et reformatage des données

Messagepar Wilfrid Car » 24 Juin 2015, 14:13

Bonjour à tous,
Je travaille sur des listes d’œuvres exposées lors de salons parisiens de la première partie du XXe siècle dans le but d'une analyse quantitative.
Suite à une océrisation de catalogue j’obtiens ce type de liste:

Les exposants sont classés alphabétiquement et les œuvres exposées sont identifiées par un numéro (ou un numéro précédé d'un astérisque):

ALBERT (Adolphe).
28 Le quai du Petit Andely.
29 Le château Gaillard.
30 Printemps.

ALDER (Emile).
31 Les genêts.
32 Femmes du Valais (Suisse), étude.
33 Etude.

ALEXANDROVITOH (A.-J.).
*34 A. Faisant (peinture).
*35 (Docteur Sigot (pastel).
36 Emile Rousset (pastel).


Mon objectif serait d'aboutir à un tableau (un data.frame) présentant:
- en ligne: les individus (œuvres)
- en colonnes : deux caractères ( désignation / artiste).

J'ai préparé les données en remplaçant les marques de paragraphes par des séparateurs de champs et réalisé l'importation dans R mais à vrai dire je ne sais pas vraiment comment procéder et mes recherches sont restées infructueuses!

Code : Tout sélectionner

> salon<-read.table("ALBERT.txt",
+                     header = FALSE, sep=";")

                                    V1 V2
1                     ALBERT (Adolphe) NA
2           28 Le quai du Petit Andely NA
3               29 Le château Gaillard NA
4                         30 Printemps NA
5                       ALDER (Emile)  NA
6                        31 Les genêts NA
7  32 Femmes du Valais (Suisse), étude NA
8                             33 Etude NA
9               ALEXANDROVITOH (A.-J.) NA
10           *34 A. Faisant (peinture) NA
11         *35 (Docteur Sigot (pastel) NA
12           36 Emile Rousset (pastel) NA

> dput (salon)
structure(list(V1 = structure(c(10L, 3L, 4L, 5L, 11L, 6L, 7L,
8L, 12L, 1L, 2L, 9L), .Label = c("*34 A. Faisant (peinture)",
"*35 (Docteur Sigot (pastel)", "28 Le quai du Petit Andely",
"29 Le château Gaillard", "30 Printemps", "31 Les genêts", "32 Femmes du Valais (Suisse), étude",
"33 Etude", "36 Emile Rousset (pastel)", "ALBERT (Adolphe)",
"ALDER (Emile) ", "ALEXANDROVITOH (A.-J.)"), class = "factor"),
    V2 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)), .Names = c("V1",
"V2"), class = "data.frame", row.names = c(NA, -12L))


Gabriel Terraz
Messages : 591
Enregistré le : 26 Sep 2011, 15:11

Re: océrisation et reformatage des données

Messagepar Gabriel Terraz » 24 Juin 2015, 15:43

Salut,

Voici une proposition, en commençant par readLines() et non read.table()

Code : Tout sélectionner

rl <- readLines("clipboard" , encoding = "latin1")
oeuvre_id <- grepl("^[0-9*]" , rl)
RLE <- rle(oeuvre_id)

df <- data.frame(oeuvre = rl[oeuvre_id] , artiste = rep(rl[!oeuvre_id] , RLE$lengths[RLE$values]))
df$designation <- sub(" .+$" , "" , df$oeuvre)
df$oeuvre <- sub("^[0-9*]+" , "" , df$oeuvre)

> df
                              oeuvre                 artiste designation
1           Le quai du Petit Andely.       ALBERT (Adolphe).          28
2               Le château Gaillard.       ALBERT (Adolphe).          29
3                         Printemps.       ALBERT (Adolphe).          30
4                        Les genêts.          ALDER (Emile).          31
5  Femmes du Valais (Suisse), étude.          ALDER (Emile).          32
6                             Etude.          ALDER (Emile).          33
7             A. Faisant (peinture). ALEXANDROVITOH (A.-J.).         *34
8           (Docteur Sigot (pastel). ALEXANDROVITOH (A.-J.).         *35
9            Emile Rousset (pastel). ALEXANDROVITOH (A.-J.).          36


Wilfrid Car
Messages : 59
Enregistré le : 09 Avr 2015, 13:35

Re: océrisation et reformatage des données

Messagepar Wilfrid Car » 24 Juin 2015, 19:21

Cela fonctionne parfaitement! Je regarde cela avec plus d’attention pour en décoder le fonctionnement étape par étape (Autant, je comprend, le sens de la ligne utilisant la fonction grepl autant la suite m'apparait relativement obscure...)

Wilfrid

Gabriel Terraz
Messages : 591
Enregistré le : 26 Sep 2011, 15:11

Re: océrisation et reformatage des données

Messagepar Gabriel Terraz » 24 Juin 2015, 21:22

Effectivement je n'ai pas beaucoup détaillé,

La fonction rle permet de compter des suites d'éléments identiques, et dans notre cas, permet de compter combien d'oeuvre (ici TRUE) suivent un artiste (FALSE).
Le résultat est sous forme de liste avec la longueur de chaque répétition et la valeur associée dans le deuxième vecteur.

Code : Tout sélectionner

> RLE <- rle(oeuvre_id)
> RLE
Run Length Encoding
  lengths: int [1:6] 1 3 1 3 1 3
  values : logi [1:6] FALSE TRUE FALSE TRUE FALSE TRUE


Pour la ligne avec la création du dataframe :

Code : Tout sélectionner

oeuvre = rl[oeuvre_id]

Facile, on récupère les lignes qui correspondent aux oeuvres

Pour les artistes, on répète chaque ligne d'artiste

Code : Tout sélectionner

rl[!oeuvre_id]

chacune autant de fois qu'elle a d'oeuvre qui correspond (on récupère dans le vecteur RLE$lengths seulement les valeurs pour lesquelles RLE$values est VRAI (quand c'est une oeuvre)

Code : Tout sélectionner

artiste = rep(rl[!oeuvre_id] , RLE$lengths[RLE$values]))


Les deux dernière lignes sont des expressions rationelles pour récupérer l'identifiant des oeuvres, puis modifier les oeuvres pour qu'elles ne contiennent plus cet identifiant.

J'espère t'avoir éclairé,

Gabriel

Wilfrid Car
Messages : 59
Enregistré le : 09 Avr 2015, 13:35

Re: océrisation et reformatage des données

Messagepar Wilfrid Car » 25 Juin 2015, 07:52

Merci, cela est en effet beaucoup plus clair du point de vue de la méthode!
J'ai commencé à m'attaquer au traitement de l'ensemble des oeuvres (4476 pour l'année 1930)
L'océrisation génère pas mal de problèmes notamment le traitement des numeros de pages (ex: — 361 —) que je ne peux exclure en raison du défaut d’alignement des scans.
4327 Le Pharaon au nez cassé. — 2.000 fr.
• %
VERECQUE (Amédée) — 1920 — né à Montauban. — 76, rue de Rennes, 6®.
4328 Paysage d’hiver. — 1.100 fr.
4329 Le viatique. — 800 fr.
— 361 —
VÉRITÉ (Madeleine) — 1929 — née à Pau (Basses-Pyrénées). — 9, square Delambre, 14e.



4332 L,es tilleuls en hiver, Issoire (Puy-de-Dôme)
(aquarelle). — 400 fr.
0
VERNEROT (M"e Lise) — 1926 — née à Paris. — 265, rue Saint-Denis, 2e.


VIOTTE (Jacques) — 1929 — né à Remiremont (Vosges). — 92 rue de Varenne, 7e.
«
4376 La jetée. — 1.500 fr.
4377 La veste rouge. — 3.500 fr.
VLACHOPOULOS (Xénophon) — 1928 — né en Grèce — Grec ____________________
Chez M. Lefebvre-Foinet, 19, rue Vavin, 6e.

Aussi,un traitement préalable dans R des chaines de caractère doit s'avérer nécessaire. (le passage par un filtrage textuel dans Excel s'avère particulièrement long et source d'erreurs)
- Supprimer toutes les lignes qui ne commencent par deux maj (la casse étant bien traitée par l'ocr) OU par un nombre suivi d'une chaine de caractère.

J'ai identifié le package Stringr mais son usage depuis l'importation des données via read. table dépasse mais modestes compétences...

Gabriel Terraz
Messages : 591
Enregistré le : 26 Sep 2011, 15:11

Re: océrisation et reformatage des données

Messagepar Gabriel Terraz » 25 Juin 2015, 08:04

Salut,
Je n'ai pas bien compris si au final tu avais un souci, mais un simple

Code : Tout sélectionner

rl <- rl[grep("^[A-Z]{2,}|^[0-9*]" , rl)]


juste après la lecture de tes données devrait l'affaire pour parer tous les trucs bizarres que tu peux rencontrer

Wilfrid Car
Messages : 59
Enregistré le : 09 Avr 2015, 13:35

Re: océrisation et reformatage des données

Messagepar Wilfrid Car » 25 Juin 2015, 08:53

Grep a effectué un gros nettoyage des données!
Il reste quelques coquilles: de nombreuses mention de prix de vente (3.000)
[96] "AMBROSINI (Vincent) — 1922 — né à Constantine (Algérie). — 19, rue de Chartres, Neuilly-sur-Seine."
[97] "64 Les calanches de Piana (Corse) au clair de lune. —"
[98] "3.000\tfr."
[99] "65 'Côtes de Corse au clair de lune. — 1.500 fr."


mention d'exposition posthume suivant le nom d'un artiste
[283] "BARBEDIENNE (Bernard) — 1927 — né à Paris le 5 septembre 1909; décédé le 12 octobre 1929 à Gargan. — S’adresser à M. Barbedienne, 61, boulevard Edouard-Vaillant, Gargan (S.-et-O.)."
[284] "EXPOSITION POSTHUME"


et enfin la présence d'un astérisque, d'un zéro...

Je lance la suite et cela ne fonctionne pas...
Je tente donc de supprimer les exposions postumes...mais je suis un peu perdu dans la syntaxe...

Code : Tout sélectionner

salon2 <- rl[grep("^[A-Z]{2,}|^[0-9*]|^["EXPOSITION POSTHUME"])" , rl)]

Gabriel Terraz
Messages : 591
Enregistré le : 26 Sep 2011, 15:11

Re: océrisation et reformatage des données

Messagepar Gabriel Terraz » 25 Juin 2015, 09:05

Dans ta ligne de commande tu lui demandes de conserver les lignes commençant soit par deux lettres majuscules, un nombre ou astérisque, exposition posthume, donc tu mélanges ce que tu veux et ce que tu veux pas !

Une idée :

Code : Tout sélectionner

rl <- rl[grep("^[A-Z]{2,}|^\\*[0-9*]{2,} |^[0-9]{2,} " , rl)]


Donc 3 possibilités :
- Commence par au moins deux majuscules
- Commence par une astérisque et au moins deux chiffres suivi d'une espace
- Commence par au moins deux chiffres suivis d'une espace

Puis pour enlever exposition posthume

Code : Tout sélectionner

rl <- rl[ -grep("EXPOSITION POSTHUME"  , rl]


Le problème est que si tu as beaucoup de cas particuliers tu vas finir par prendre plus de temps que de le faire à la main...

Edit :
Une idée pour les lignes d'artistes, rajouter la présence de parenthèse (qui indique le prénom), à condition que le prénom soit toujours mentionné...
En tout cas cela évite d'avoir à enlever posthume par exemple

Code : Tout sélectionner

rl <- rl[grep("^[A-Z]{2,} \\(|^\\*[0-9*]{2,} |^[0-9]{2,} " , rl)]

Wilfrid Car
Messages : 59
Enregistré le : 09 Avr 2015, 13:35

Re: océrisation et reformatage des données

Messagepar Wilfrid Car » 25 Juin 2015, 10:05

merci pour ta réponse, je me suis un peu mélangé...je vais prendre le temps d'approfondir mon nettoyage de données.
Je peux aussi, effectivement, finir à la main en supprimant les dernières coquilles.

Wilfrid Car
Messages : 59
Enregistré le : 09 Avr 2015, 13:35

Re: océrisation et reformatage des données

Messagepar Wilfrid Car » 25 Juin 2015, 12:47

J'ai finalement opté pour un dernier nettoyage dans Excel...
Je ne suis pas pour autant avancé:
Je teste le programme sur une petite partie de ma liste:

ABADIE-LANDEL (Pierre) — 1920 — né à Paris. — 17, rue Campagne-Première, 14e.
1 La parade de lutte. — 3.000 fr.
2 Claudine. — Appartient à M. Landel.
ABOU (Albert) — 1930 — né à Marseille. — 41, rue de Seine, 6e.
3 Le Fort Saint-Jean, Marseille (marine). — 2.000 fr.
4 Fruits (nu). — 4.800 fr.
ABRAMOVITSCH (Simon) — 1930 — né au Havre. — 30, rue de Saint-Quentin, Le Havre (Seine-Inférieure).
5 Entrée du port du Havre. — 1.000 fr.
6 Le Bassin du Roi, Le Havre. —' 1.000 fr.
ABRANSKI (Cécile) — 1926 — Esthonienne. — 7, rue Lebouis, 14e.
7 Buste (terre cuite) (sculpture). — 3.000 fr.
8 Figure (plâtre) (sculpture). — 1.000 fr.
ACHILLE-FOULD (Mme Georges) — 1928 — née à Asnières. — 20, boulevard d>e Courcelles. 17e.
9 Peinture.
10 Peinture.
ACKEIN (Mme Marcelle) — 1910 — née à Alger, — 31, rue Jeanne, 15e.
11 La fenêtre jaune. — 3.000 fr.
12 Musique et mosaïque. — 4.000 fr.
ADAMSON-ERIC — 1928 — né à Ta-rtu (Esthonie) — Esthonien. — 172, rue de Vanves, 14e.
13 Portrait de l’artiste. — 5.000 fr.
14 Nature morte. — 4.000 fr.


Code : Tout sélectionner

rl2<- readLines("clipboard" , encoding = "latin1")


Code : Tout sélectionner

[1] "ABADIE-LANDEL (Pierre) — 1920 — né à Paris. — 17, rue Campagne-Première, 14e."                     
 [2] "1 La parade de lutte. — 3.000 fr."                                                                 
 [3] "2 Claudine. — Appartient à M. Landel."                                                             
 [4] "ABOU (Albert) — 1930 — né à Marseille. — 41, rue de Seine, 6e."                                     
 [5] "3 Le Fort Saint-Jean, Marseille (marine). — 2.000 fr."                                             
 [6] "4 Fruits (nu). — 4.800 fr."                                                                         
 [7] "ABRAMOVITSCH (Simon) — 1930 — né au Havre. — 30, rue de Saint-Quentin, Le Havre (Seine-Inférieure)."
 [8] "5 Entrée du port du Havre. — 1.000 fr."                                                             
 [9] "6 Le Bassin du Roi, Le Havre. —' 1.000 fr."                                                         
[10] "ABRANSKI (Cécile) — 1926 — Esthonienne. — 7, rue Lebouis, 14e."                                     
[11] "7 Buste (terre cuite) (sculpture). — 3.000 fr."                                           
[12] "8 Figure (plâtre) (sculpture). — 1.000 fr."                                                         
[13] "ACHILLE-FOULD (Mme Georges) — 1928 — née à Asnières. — 20, boulevard d>e Courcelles. 17e."         
[14] "9 Peinture."                                                                                       
[15] "10 Peinture."                                                                                       
[16] "ACKEIN (Mme Marcelle) — 1910 — née à Alger, — 31, rue Jeanne, 15e."                                 
[17] "11 La fenêtre jaune. — 3.000 fr."                                                                   
[18] "12 Musique et mosaïque. — 4.000 fr."                                                               
[19] "ADAMSON-ERIC — 1928 — né à Ta-rtu (Esthonie) — Esthonien. — 172, rue de Vanves, 14e."               
[20] "13 Portrait de l’artiste. — 5.000 fr."                                                             
[21] "14 Nature morte. — 4.000 fr."


Je lance la recherche des lignes commençant par un nombre situé dans un intervalle de 0 à 14

Code : Tout sélectionner

oeuvre_id <- grepl("^[0-14*]" , rl2)


La fonction Grepl me retourne un résultat logique inattendu:

Code : Tout sélectionner

[1] FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE  TRUE
[19] FALSE  TRUE  TRUE


J'attendais plutôt du FALSE TRUE TRUE FALSE TRUE TRUE FALSE TRUE TRUE...

Gabriel Terraz
Messages : 591
Enregistré le : 26 Sep 2011, 15:11

Re: océrisation et reformatage des données

Messagepar Gabriel Terraz » 25 Juin 2015, 13:00

C'est logique, la construction de l'expression régulière cherche des identifiants d'oeuvres qui commencent par au moins deux chiffres "[0-9*]{2,}", mais je n'avais pas pensé que la numérotation commence à 1 et non à 10...

Plutôt que :

Code : Tout sélectionner

rl[grep("^[A-Z]{2,} \\(|^\\*[0-9*]{2,} |^[0-9]{2,} " , rl)


Mettre :

Code : Tout sélectionner

rl[grep("^[A-Z]{2,} \\(|^\\*[0-9*]+ |^[0-9]+ " , rl)]


Les identifiants devant être 1 chiffre ou plus, c'est la signification du "+" après "[0-9]"

Wilfrid Car
Messages : 59
Enregistré le : 09 Avr 2015, 13:35

Re: océrisation et reformatage des données

Messagepar Wilfrid Car » 25 Juin 2015, 13:41

Le + a son importance!

J'ai laissé de côté les astérisques et rajouté le + à l'expression

Code : Tout sélectionner

rl2<- readLines("clipboard" , encoding = "latin1")
rl2
oeuvre_id2 <- grepl("^[0-9]+" , rl2)
oeuvre_id2


Tout se déroule pour le mieux jusquà la ligne 41 :

Code : Tout sélectionner

 [1] FALSE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE
[19] FALSE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE
[37]  TRUE  TRUE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE


Code : Tout sélectionner

[39] "AIRAULT (François) — 1926 — né à Chambon-sur-Vouèze (Creuse). — 9, rue Gambetta, Versailles (S.-et-O.)."
 [40] "27 Foch. — 800 fr."                                                                                     
 [41] "28 Clemenceau. — 800 fr."                                                                               
 [42] "ALATERRE (Louis) — 19-23 — né à Châteaudun (E.-et-L.). — 9, rue FaJguière, 15e."                       
 [43] "\"29 \tDans le parc. — 3.500 fr.\""                                                                     
 [44] "\"30 \tPaysage. — 1.500 fr.\""                                                                           
 [45] "ALBE (Maurioe) — 1925 — né à Sarlat. — Rue de la République, Sarlat (Dordogne)."                       
 [46] "\"31 \tPaysage du Périgord. — 1.500 fr.\""                                                               
 [47] "\"32 \tPaysage du Périgord. — 1.200 fr.\""                                                               
 [48] "ALBERT (Adolphe) — 1886 — né à Paris. — « Le Tilleul », Les Andelys (Eure)."                           
 [49] "33 La neige au Petit Andely. — 1.500 fr."                                                               
 [50] "34 Le pont suspendu. — 1.200 fr."                 


Et pour cause: alors me que mes lignes sont strictement identiques dans Excel, j'obtiens un dans R de manière intermitente partir de la ligne 43...

Gabriel Terraz
Messages : 591
Enregistré le : 26 Sep 2011, 15:11

Re: océrisation et reformatage des données

Messagepar Gabriel Terraz » 25 Juin 2015, 14:32

Pour les antislash qui se balladent je pense que tu as un problème de copier coller, puisque leur présence est du à des guillemets dans tes chaînes de caractère.

Tu dis :
"J'ai laissé de côté les astérisques et rajouté le + à l'expression"

Code : Tout sélectionner

oeuvre_id2 <- grepl("^[0-9]+" , rl2)


En faisant cela tu ne vas donc pas sélectionner les lignes qui commencent par des astérisques mais par contre tu vas sélectionner la ligne qui commence par 3.000f
C'est pour cela que j'ai rajouté une espace après les chiffres dans l'expression rationnelle.

Wilfrid Car
Messages : 59
Enregistré le : 09 Avr 2015, 13:35

Re: océrisation et reformatage des données

Messagepar Wilfrid Car » 25 Juin 2015, 15:50

C'est tout à fait ça. De manière étrange, lorsque je copie mes données Excel dans le bloc note, des guillemets apparaissent comme premier caractère de mes lignes récalcitrantes.

J'ai compris le problème en revenant au fichier texte issu du scan: l'ocr à généré des tabulations entre le n° et la désignation de certaines oeuvres.

Code : Tout sélectionner

[365] "203\tPeinture."       

Wilfrid Car
Messages : 59
Enregistré le : 09 Avr 2015, 13:35

Re: océrisation et reformatage des données

Messagepar Wilfrid Car » 26 Juin 2015, 07:03

Bonjour,
N'étant pas familier avec les regex, , je suis preneur d'un coup de pouce qui m'aiderait supprimer ces maudits backslachs correspondant à des tabulations dans mon fichier texte (et qui ne sont pas uniquement présents en début de ligne). Après cette étape. je pense pouvoir aboutir à mon data.frame....du moins, je l'espère.


Wilfrid


Retourner vers « Questions en cours »

Qui est en ligne

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