7.3 proustr

7.3.1 Import into Global Environment

Adding data from the first book into the Global environment

data(ducotedechezswann)
#data(alombredesjeunesfillesenfleurs)
#data(lecotedeguermantes)
#data(sodomeetgomorrhe)
#data(laprisonniere)
#data(albertinedisparue)
#data(letempretrouve)

7.3.2 Look into data

And we can get the top 60 rows from the first one

ducotedechezswann %>%
  head(n = 60)
## # A tibble: 60 × 4
##    text                                                       book  volume  year
##    <chr>                                                      <chr> <chr>  <dbl>
##  1 "Longtemps, je me suis couché de bonne heure. Parfois, à … Du c… Premi…  1913
##  2 "J'appuyais tendrement mes joues contre les belles joues … Du c… Premi…  1913
##  3 "Je me rendormais, et parfois je n'avais plus que de cour… Du c… Premi…  1913
##  4 "Quelquefois, comme Ève naquit d'une côte d'Adam, une fem… Du c… Premi…  1913
##  5 "Un homme qui dort tient en cercle autour de lui le fil d… Du c… Premi…  1913
##  6 "Peut-être l'immobilité des choses autour de nous leur es… Du c… Premi…  1913
##  7 "Puis renaissait le souvenir d'une nouvelle attitude ; le… Du c… Premi…  1913
##  8 "Ces évocations tournoyantes et confuses ne duraient jama… Du c… Premi…  1913
##  9 "Certes, j'étais bien éveillé maintenant : mon corps avai… Du c… Premi…  1913
## 10 "À Combray, tous les jours dès la fin de l'après-midi, lo… Du c… Premi…  1913
## # ℹ 50 more rows

7.3.3 Create a corpus

ducotedechezswann_corpus <- corpus(ducotedechezswann, text_field = "text")
print(ducotedechezswann_corpus)
## Corpus consisting of 1,004 documents and 3 docvars.
## text1 :
## "Longtemps, je me suis couché de bonne heure. Parfois, à pein..."
## 
## text2 :
## "J'appuyais tendrement mes joues contre les belles joues de l..."
## 
## text3 :
## "Je me rendormais, et parfois je n'avais plus que de courts r..."
## 
## text4 :
## "Quelquefois, comme Ève naquit d'une côte d'Adam, une femme n..."
## 
## text5 :
## "Un homme qui dort tient en cercle autour de lui le fil des h..."
## 
## text6 :
## "Peut-être l'immobilité des choses autour de nous leur est-el..."
## 
## [ reached max_ndoc ... 998 more documents ]

7.3.3.1 Summary

summary(ducotedechezswann_corpus, 10)
## Corpus consisting of 1004 documents, showing 10 documents:
## 
##    Text Types Tokens Sentences                  book                    volume
##   text1   200    359         6 Du côté de chez Swann Première partie : Combray
##   text2   110    166        11 Du côté de chez Swann Première partie : Combray
##   text3   120    172         3 Du côté de chez Swann Première partie : Combray
##   text4   116    175         6 Du côté de chez Swann Première partie : Combray
##   text5   202    370         5 Du côté de chez Swann Première partie : Combray
##   text6   212    409         6 Du côté de chez Swann Première partie : Combray
##   text7   120    191         6 Du côté de chez Swann Première partie : Combray
##   text8   347    658         4 Du côté de chez Swann Première partie : Combray
##   text9   114    179         2 Du côté de chez Swann Première partie : Combray
##  text10   130    204         4 Du côté de chez Swann Première partie : Combray
##  year
##  1913
##  1913
##  1913
##  1913
##  1913
##  1913
##  1913
##  1913
##  1913
##  1913

7.3.3.2 Accessing parts of corpus

ducotedechezswann_corpus[[1]]
## [1] "Longtemps, je me suis couché de bonne heure. Parfois, à peine ma bougie éteinte, mes yeux se fermaient si vite que je n'avais pas le temps de me dire : \" Je m'endors. \" Et, une demi-heure après, la pensée qu'il était temps de chercher le sommeil m'éveillait ; je voulais poser le volume que je croyais avoir encore dans les mains et souffler ma lumière ; je n'avais pas cessé en dormant de faire des réflexions sur ce que je venais de lire, mais ces réflexions avaient pris un tour un peu particulier ; il me semblait que j'étais moi-même ce dont parlait l'ouvrage : une église, un quatuor, la rivalité de François Ier et de Charles-Quint. Cette croyance survivait pendant quelques secondes à mon réveil ; elle ne choquait pas ma raison, mais pesait comme des écailles sur mes yeux et les empêchait de se rendre compte que le bougeoir n'était pas allumé. Puis elle commençait à me devenir inintelligible, comme après la métempsycose les pensées d'une existence antérieure ; le sujet du livre se détachait de moi, j'étais libre de m'y appliquer ou non ; aussitôt je recouvrais la vue et j'étais bien étonné de trouver autour de moi une obscurité, douce et reposante pour mes yeux, mais peut-être plus encore pour mon esprit, à qui elle apparaissait comme une chose sans cause, incompréhensible, comme une chose vraiment obscure. Je me demandais quelle heure il pouvait être ; j'entendais le sifflement des trains qui, plus ou moins éloigné, comme le chant d'un oiseau dans une forêt, relevant les distances, me décrivait l'étendue de la campagne déserte où le voyageur se hâte vers la station prochaine ; et le petit chemin qu'il suit va être gravé dans son souvenir par l'excitation qu'il doit à des lieux nouveaux, à des actes inaccoutumés, à la causerie récente et aux adieux sous la lampe étrangère qui le suivent encore dans le silence de la nuit, à la douceur prochaine du retour."

7.3.3.3 Document-level information

head(docvars(ducotedechezswann_corpus))
##                    book                    volume year
## 1 Du côté de chez Swann Première partie : Combray 1913
## 2 Du côté de chez Swann Première partie : Combray 1913
## 3 Du côté de chez Swann Première partie : Combray 1913
## 4 Du côté de chez Swann Première partie : Combray 1913
## 5 Du côté de chez Swann Première partie : Combray 1913
## 6 Du côté de chez Swann Première partie : Combray 1913

7.3.3.4 Unique variable names (for volume)

unique(docvars(ducotedechezswann_corpus, field = "volume"))
## [1] "Première partie : Combray"              
## [2] "Deuxième partie — Un amour de Swan"     
## [3] "Troisième partie : Nom de pays : le nom"

7.3.4 Advanced manipulations

7.3.4.1 Tokens

tokens() segments texts in a corpus into tokens (words or sentences) by word boundaries. We can remove punctuations or not

7.3.4.1.1 With punctuations
ducotedechezswann_corpus_tok <- tokens(ducotedechezswann_corpus)
ducotedechezswann_corpus_tok
## Tokens consisting of 1,004 documents and 3 docvars.
## text1 :
##  [1] "Longtemps" ","         "je"        "me"        "suis"      "couché"   
##  [7] "de"        "bonne"     "heure"     "."         "Parfois"   ","        
## [ ... and 347 more ]
## 
## text2 :
##  [1] "J'appuyais" "tendrement" "mes"        "joues"      "contre"    
##  [6] "les"        "belles"     "joues"      "de"         "l'oreiller"
## [11] "qui"        ","         
## [ ... and 154 more ]
## 
## text3 :
##  [1] "Je"         "me"         "rendormais" ","          "et"        
##  [6] "parfois"    "je"         "n'avais"    "plus"       "que"       
## [11] "de"         "courts"    
## [ ... and 160 more ]
## 
## text4 :
##  [1] "Quelquefois" ","           "comme"       "Ève"         "naquit"     
##  [6] "d'une"       "côte"        "d'Adam"      ","           "une"        
## [11] "femme"       "naissait"   
## [ ... and 163 more ]
## 
## text5 :
##  [1] "Un"     "homme"  "qui"    "dort"   "tient"  "en"     "cercle" "autour"
##  [9] "de"     "lui"    "le"     "fil"   
## [ ... and 358 more ]
## 
## text6 :
##  [1] "Peut-être"    "l'immobilité" "des"          "choses"       "autour"      
##  [6] "de"           "nous"         "leur"         "est-elle"     "imposée"     
## [11] "par"          "notre"       
## [ ... and 397 more ]
## 
## [ reached max_ndoc ... 998 more documents ]
7.3.4.1.2 Without punctuations
ducotedechezswann_corpus_tok_no_punct <- tokens(ducotedechezswann_corpus, remove_punct = TRUE)
ducotedechezswann_corpus_tok_no_punct
## Tokens consisting of 1,004 documents and 3 docvars.
## text1 :
##  [1] "Longtemps" "je"        "me"        "suis"      "couché"    "de"       
##  [7] "bonne"     "heure"     "Parfois"   "à"         "peine"     "ma"       
## [ ... and 306 more ]
## 
## text2 :
##  [1] "J'appuyais" "tendrement" "mes"        "joues"      "contre"    
##  [6] "les"        "belles"     "joues"      "de"         "l'oreiller"
## [11] "qui"        "pleines"   
## [ ... and 133 more ]
## 
## text3 :
##  [1] "Je"         "me"         "rendormais" "et"         "parfois"   
##  [6] "je"         "n'avais"    "plus"       "que"        "de"        
## [11] "courts"     "réveils"   
## [ ... and 146 more ]
## 
## text4 :
##  [1] "Quelquefois" "comme"       "Ève"         "naquit"      "d'une"      
##  [6] "côte"        "d'Adam"      "une"         "femme"       "naissait"   
## [11] "pendant"     "mon"        
## [ ... and 144 more ]
## 
## text5 :
##  [1] "Un"     "homme"  "qui"    "dort"   "tient"  "en"     "cercle" "autour"
##  [9] "de"     "lui"    "le"     "fil"   
## [ ... and 320 more ]
## 
## text6 :
##  [1] "Peut-être"    "l'immobilité" "des"          "choses"       "autour"      
##  [6] "de"           "nous"         "leur"         "est-elle"     "imposée"     
## [11] "par"          "notre"       
## [ ... and 336 more ]
## 
## [ reached max_ndoc ... 998 more documents ]

7.3.4.2 Compound words

7.3.4.2.1 kwic Phrase
ducotedechezswann_corpus_tok_no_punct_phrase <- kwic(ducotedechezswann_corpus_tok_no_punct, pattern =  phrase("un homme"), window = 6)
head(ducotedechezswann_corpus_tok_no_punct_phrase, 10)
## Keyword-in-context with 10 matches.                                                                         
##        [text5, 1:2]                                          | Un homme |
##   [text82, 216:217] nous avions rencontré près du Pont-Vieux | un homme |
##   [text82, 224:225]    que mon grand-père ne connaissait pas | Un homme |
##   [text82, 268:269]   rencontré près du Pont-Vieux mon oncle | un homme |
##   [text82, 316:317]       me disait que vous aviez rencontré | un homme |
##  [text198, 465:466]       les femmes qui prétendent ne juger | un homme |
##   [text224, 99:100]              votre mort on fasse de vous | un homme |
##  [text298, 175:176]          de raisons pour aimer Mais pour | un homme |
##  [text431, 108:109]         eut besoin d'elle il était comme | un homme |
##    [text449, 15:16]      cela serait assez triste mais enfin | un homme |
##                                               
##  qui dort tient en cercle autour              
##  que mon grand-père ne connaissait pas        
##  que grand-père ne connaissait point s'écriait
##  que vous ne connaissiez point Mais           
##  que vous ne connaissiez point Et             
##  que sur son physique voient en               
##  Monsieur le Curé a toujours le               
##  comme M Vinteuil il devait entrer            
##  dans la vie de qui une                       
##  de génie peut être le cousin
7.3.4.2.2 Compounds
ducotedechezswann_corpus_tok_no_punct_comp <- tokens_compound(ducotedechezswann_corpus_tok_no_punct, pattern = phrase("un homme"))
ducotedechezswann_corpus_tok_no_punct_comp_kwic <- kwic(ducotedechezswann_corpus_tok_no_punct_comp, pattern = phrase("un_homme"))
head(ducotedechezswann_corpus_tok_no_punct_comp_kwic, 10)
## Keyword-in-context with 10 matches.                                                                
##      [text5, 1]                                     | Un_homme |
##   [text82, 216] avions rencontré près du Pont-Vieux | un_homme |
##   [text82, 223]   mon grand-père ne connaissait pas | Un_homme |
##   [text82, 266]        près du Pont-Vieux mon oncle | un_homme |
##   [text82, 313]     disait que vous aviez rencontré | un_homme |
##  [text198, 465]      femmes qui prétendent ne juger | un_homme |
##   [text224, 99]               mort on fasse de vous | un_homme |
##  [text298, 175]        raisons pour aimer Mais pour | un_homme |
##  [text431, 108]        besoin d'elle il était comme | un_homme |
##   [text449, 15]      serait assez triste mais enfin | un_homme |
##                                     
##  qui dort tient en cercle           
##  que mon grand-père ne connaissait  
##  que grand-père ne connaissait point
##  que vous ne connaissiez point      
##  que vous ne connaissiez point      
##  que sur son physique voient        
##  Monsieur le Curé a toujours        
##  comme M Vinteuil il devait         
##  dans la vie de qui                 
##  de génie peut être le

7.3.4.3 N-grams

N-grams are a subfamily of compound words. They can be named as “bi-grams”, “tri-grams”, etc. N-grams yield a sequence of tokens from already tokenised text object.

7.3.4.3.1 Multi-grams

The code below allows to obtain the sequences of consecutive compound words, with 2, 3 or 4 compound words.

ducotedechezswann_corpus_tok_no_punct_ngram <- tokens_ngrams(ducotedechezswann_corpus_tok_no_punct, n = 2:4) %>% 
  unlist() %>%
  tolower() %>%
  table()
## Top 10 rows
head(ducotedechezswann_corpus_tok_no_punct_ngram, 10)
## .
##               il_est          il_est_très     il_est_très_tenu 
##                    1                    1                    1 
##            ─_comment      ─_comment_c'est ─_comment_c'est_cela 
##                    1                    1                    1 
##                 ─_et              ─_et_la         ─_et_la_joie 
##                    1                    1                    1 
##               ─_mais 
##                    3
## Last 10 rows
tail(ducotedechezswann_corpus_tok_no_punct_ngram, 10)
## .
## zoologiques_où_l'on_voit                 zut_mais              zut_mais_en 
##                        1                        1                        1 
##         zut_mais_en_même                  zut_zut             zut_zut_mais 
##                        1                        3                        1 
##          zut_zut_mais_en              zut_zut_zut         zut_zut_zut_mais 
##                        1                        2                        1 
##          zut_zut_zut_zut 
##                        1
7.3.4.3.2 Skip-grams

Skip-grams allow to obtain non consecutive n-grams

ducotedechezswann_corpus_tok_no_punct_ngram_skip <- tokens_ngrams(ducotedechezswann_corpus_tok_no_punct, n = 2:4, skip = 1:2) %>% 
  unlist() %>%
  tolower() %>%
  table()
## Top 10 rows
head(ducotedechezswann_corpus_tok_no_punct_ngram_skip, 10)
## .
##                 il_tenu               il_tenu_a         il_tenu_a_femme 
##                       1                       1                       1 
##           il_tenu_a_une               il_tenu_y  il_tenu_y_certainement 
##                       1                       1                       1 
##           il_tenu_y_une                 il_très              il_très_il 
##                       1                       1                       1 
##            il_très_il_a 
##                       1
## Last 10 rows
tail(ducotedechezswann_corpus_tok_no_punct_ngram_skip, 10)
## .
##             zut_zut          zut_zut_en       zut_zut_en_je    zut_zut_en_temps 
##                   3                   3                   3                   3 
##        zut_zut_mais   zut_zut_mais_même  zut_zut_mais_temps        zut_zut_même 
##                   1                   1                   1                   2 
##     zut_zut_même_je zut_zut_même_sentis 
##                   2                   2

7.3.4.4 Dictionary

If you have a dictionary with various words that fall within a generic word (e.g., variants of pronunciation of a word), then you can look these up. Here, we will create a dictionary that we populate ourselves and we show how to use it to search for items

7.3.4.4.1 Create dictionary
dict_ducotedechezswann <- dictionary(list(famille = c("grand-père", "femme", "homme", "oncle"),
                        dormir = c("rendormais", "dors", "dort")))
print(dict_ducotedechezswann)
## Dictionary object with 2 key entries.
## - [famille]:
##   - grand-père, femme, homme, oncle
## - [dormir]:
##   - rendormais, dors, dort
7.3.4.4.2 Token lookup
ducotedechezswann_corpus_tok_no_punct_dict_toks <- tokens_lookup(ducotedechezswann_corpus_tok_no_punct, dictionary = dict_ducotedechezswann)
print(ducotedechezswann_corpus_tok_no_punct_dict_toks)
## Tokens consisting of 1,004 documents and 3 docvars.
## text1 :
## character(0)
## 
## text2 :
## character(0)
## 
## text3 :
## [1] "dormir"
## 
## text4 :
## [1] "famille" "famille" "famille"
## 
## text5 :
## [1] "famille" "dormir"  "dormir" 
## 
## text6 :
## [1] "famille"
## 
## [ reached max_ndoc ... 998 more documents ]
7.3.4.4.3 DFM
dfm(ducotedechezswann_corpus_tok_no_punct_dict_toks)
## Document-feature matrix of: 1,004 documents, 2 features (91.33% sparse) and 3 docvars.
##        features
## docs    famille dormir
##   text1       0      0
##   text2       0      0
##   text3       0      1
##   text4       3      0
##   text5       1      2
##   text6       1      0
## [ reached max_ndoc ... 998 more documents ]

7.3.4.5 Part of Speech tagging

Part-of-Speech tagging (or PoS-Tagging) is used to distinguish different part of speech, e.g., the sentence: “Jane likes the girl” can be tagged as “Jane/NNP likes/VBZ the/DT girl/NN”, where NNP = proper noun (singular), VBZ = 3rd person singular present tense verb, DT = determiner, and NN = noun (singular or mass). We will use the udpipe package

7.3.4.5.1 Download and load language model

Before using the PoS-tagger, we need to download a language model. As you can see from typing ?udpipe_download_model, there are 65 languages trained on 101 treebanks from here

file_to_check <- "models/french-partut-ud-2.5-191206.udpipe"

if (file.exists(file = file_to_check)){
  m_french <- udpipe_load_model(file = "models/french-partut-ud-2.5-191206.udpipe")
}else{
  m_french <- udpipe_download_model(model_dir = "models/", language = "french-partut")
  m_french <- udpipe_load_model(file = "models/french-partut-ud-2.5-191206.udpipe")
}
7.3.4.5.2 Tokenise, tag, dependency parsing

We use the already tokenised text, with no punctuations.

ducotedechezswann_anndf <- udpipe_annotate(m_french, x = ducotedechezswann_corpus_tok_no_punct[[1]]) %>%
  as.data.frame() 
## inspect
head(ducotedechezswann_anndf, 10)
##    doc_id paragraph_id sentence_id  sentence token_id     token    lemma upos
## 1    doc1            1           1 Longtemps        1 Longtemps Longtemp NOUN
## 2    doc2            1           1        je        1        je       je PRON
## 3    doc3            1           1        me        1        me       me PRON
## 4    doc4            1           1      suis        1      suis     être  AUX
## 5    doc5            1           1    couché        1    couché   couché VERB
## 6    doc6            1           1        de        1        de       de  ADP
## 7    doc7            1           1     bonne        1     bonne      bon  ADJ
## 8    doc8            1           1     heure        1     heure    heure VERB
## 9    doc9            1           1   Parfois        1   Parfois  parfois  ADV
## 10  doc10            1           1         à        1         à        à  ADP
##    xpos                                                 feats head_token_id
## 1     S                                           Gender=Masc             0
## 2    PE                     Number=Sing|Person=1|PronType=Prs             0
## 3     P                                 Person=1|PronType=Prs             0
## 4     V Mood=Ind|Number=Sing|Person=1|Tense=Pres|VerbForm=Fin             0
## 5     V      Gender=Masc|Number=Sing|Tense=Past|VerbForm=Part             0
## 6     E                                                  <NA>             0
## 7     A                                Gender=Fem|Number=Sing             0
## 8     V                                          VerbForm=Inf             0
## 9     B                                                  <NA>             0
## 10    E                                                  <NA>             0
##    dep_rel deps            misc
## 1     root <NA> SpacesAfter=\\n
## 2     root <NA> SpacesAfter=\\n
## 3     root <NA> SpacesAfter=\\n
## 4     root <NA> SpacesAfter=\\n
## 5     root <NA> SpacesAfter=\\n
## 6     root <NA> SpacesAfter=\\n
## 7     root <NA> SpacesAfter=\\n
## 8     root <NA> SpacesAfter=\\n
## 9     root <NA> SpacesAfter=\\n
## 10    root <NA> SpacesAfter=\\n
7.3.4.5.3 Dependency parsing
## parse text
ducotedechezswann_corpus_sent <- udpipe_annotate(m_french, x = ducotedechezswann_corpus[[1]]) %>%
  as.data.frame()
## inspect
head(ducotedechezswann_corpus_sent)
##   doc_id paragraph_id sentence_id                                     sentence
## 1   doc1            1           1 Longtemps, je me suis couché de bonne heure.
## 2   doc1            1           1 Longtemps, je me suis couché de bonne heure.
## 3   doc1            1           1 Longtemps, je me suis couché de bonne heure.
## 4   doc1            1           1 Longtemps, je me suis couché de bonne heure.
## 5   doc1            1           1 Longtemps, je me suis couché de bonne heure.
## 6   doc1            1           1 Longtemps, je me suis couché de bonne heure.
##   token_id     token    lemma  upos xpos
## 1        1 Longtemps Longtemp  NOUN    S
## 2        2         ,        , PUNCT   FF
## 3        3        je       je  PRON   PE
## 4        4        me       me  PRON    P
## 5        5      suis     être   AUX    V
## 6        6    couché  coucher  VERB    V
##                                                   feats head_token_id dep_rel
## 1                               Gender=Masc|Number=Plur             6     obl
## 2                                                  <NA>             1   punct
## 3                     Number=Sing|Person=1|PronType=Prs             6   nsubj
## 4                                 Person=1|PronType=Prs             6    expl
## 5 Mood=Ind|Number=Sing|Person=1|Tense=Pres|VerbForm=Fin             6     aux
## 6      Gender=Masc|Number=Sing|Tense=Past|VerbForm=Part             0    root
##   deps          misc
## 1 <NA> SpaceAfter=No
## 2 <NA>          <NA>
## 3 <NA>          <NA>
## 4 <NA>          <NA>
## 5 <NA>          <NA>
## 6 <NA>          <NA>
ducotedechezswann_corpus_sent_dplot <- textplot_dependencyparser(ducotedechezswann_corpus_sent, size = 3) 
## show plot
ducotedechezswann_corpus_sent_dplot

7.3.4.6 Feature co-occurrence matrix (FCM)

Feature co-occurrence matrix (FCM) records the number of co-occurrences of tokens

7.3.4.6.1 Computing number of co-occurrences
ducotedechezswann_corpus_dfmat <- dfm(ducotedechezswann_corpus_tok_no_punct)
ducotedechezswann_corpus_dfmat_trim <- dfm_trim(ducotedechezswann_corpus_dfmat, min_termfreq = 500)

topfeatures_ducotedechezswann_corpus <- topfeatures(ducotedechezswann_corpus_dfmat_trim)
topfeatures_ducotedechezswann_corpus
##   de   la   et    à  que   le  les  qui   il  pas 
## 7780 3935 3894 3686 3137 3033 2330 2150 1998 1850
nfeat(ducotedechezswann_corpus_dfmat_trim)
## [1] 49
7.3.4.6.2 Features co-occurrences
ducotedechezswann_corpus_fcmat <- fcm(ducotedechezswann_corpus_dfmat_trim)
ducotedechezswann_corpus_fcmat
## Feature co-occurrence matrix of: 49 by 49 features.
##         features
## features   je   me    de     à    ma    se    si   que   pas    le
##      je  5576 5509 31908 15322  3528  3201  3707 16146  7601 12009
##      me     0 1429 15601  7505  1894  1390  1753  7838  3461  5552
##      de     0    0 94644 89769 13593 24452 20964 73030 38139 68045
##      à      0    0     0 22220  6645 12505 10230 35120 18360 32286
##      ma     0    0     0     0  1084  1466  1461  6514  2903  4655
##      se     0    0     0     0     0  1941  2946  8978  5404  9415
##      si     0    0     0     0     0     0  1355  8396  4749  7750
##      que    0    0     0     0     0     0     0 15519 15987 26398
##      pas    0    0     0     0     0     0     0     0  4662 13926
##      le     0    0     0     0     0     0     0     0     0 12745
## [ reached max_nfeat ... 39 more features, reached max_nfeat ... 39 more features ]