Réseaux en Méta-analyse

en langage R

L'essentiel de cette page

Cette page explique comment analyser automatiquement des notions pour les racorder sous la forme d'un réseau de relations.


Consulter la page générale d'aide aux méta-analyses sous R.

1- Charger (et installer si nécessaire) toutes les librairies nécessaires

install.packages("readtext")

install.packages("quanteda")

install.packages("quanteda.textmodels")

install.packages("quanteda.textstats")

install.packages("quanteda.textplots")

library("readtext") # Ouverture de plusieurs documents  de tous les types

library(quanteda) # textmining

quanteda_options(language_stemmer = "french")

library(quanteda.textmodels) # A installer si nécessaire.

library("quanteda.textstats")

library("quanteda.textplots")

library(igraph)

2- Ouvrir toutes les publications collectées dans un dossier

On peut télécharger un grand nombre de publications scientifiques au format pdf à partir de google scholar ou de pubmed. Le mieux est d'avoir un abonnement, plutôt que d'utiliser des cites légaux comme Scihub en s'y connectant avec VPN !

# A remplacer par l'adresse deson dossier

setwd("G:/statistiques/Textuel/Platanus/publi") 

P <- readtext("*",encoding ="UTF-8") 

P$text

mon_corpus <- corpus(P$text)

3- Transformer l'ensemble en corpus

Chaque publication doit être coupée phrase par phrase afin qu'on analyse les mots qui se retrouvent dans la même phrase :

mon_corpus <- corpus_segment(mon_corpus, "\\.\\s[A-Z]", extract_pattern = FALSE)

4- Nettoyer le corpus

library(textclean)

corpus<- replace_symbol(mon_corpus)

corpus<- replace_non_ascii(corpus,replacement="") 

corpus<- strip(corpus, char.keep = "~~", digit.remove = TRUE, apostrophe.remove = F)

mes_caracteres <- table(unlist(strsplit (corpus,""))) 

print(mes_caracteres)

uniq_car <- names(mes_caracteres) # pour afficher tous les types de caracteres

print(uniq_car)

library("stringr")

corpus <- str_replace_all(corpus,uniq_car[1], " ")

5- Tokeniser (découper les  phrases mots par mots)

toks_news <- tokens(corpus,remove_punct=T,remove_numbers=F) %>%

tokens_remove(., pattern = stopwords('fr'), valuetype = 'fixed') %>% tokens_tolower(., keep_acronyms = FALSE) 

6- Ouvrir un dictionnaire de correspondance pour  lister les synonymes d'un termes

library("openxlsx")

dico_perso <- read.xlsx(file.choose())

#dico_perso<- data.frame(lapply(dico_perso, function(x) {gsub(" ", "", x)}))

# Initialisation d'une liste vide

liste <- list()

# Construction de la liste avec les termes du 

for(i in 1:nrow(dico_perso)){

# data.fr[i,1] = item; #str_split decompose la seconde col.

#model <- str_replace_all(dico_perso[i,2]," ","")

model <- dico_perso[i,2]

liste[dico_perso[i,1]] <- str_split(model, pattern=',')

}

liste

dic <- dictionary(liste)

Ce dictionnaire collecte tous les gènes, protéines et termes en lien avec le sujet du chancre coloré qui extermine le platane oriental (et occidental).

Une colonne pour le nom principal et une colonne Synonyme.

En bonus, on peut demander à chatgpt implémanté dans R de scanner l'ensemble des publications pour enrichir lui-même le dictionnaire (à sauvegarder à la fin avec write.xlsx() de {openxlsx}.

commande_de_base <- "J'ai un dictionnaire R (object dic)  dont voici le contenu. Il contient des noms et d'éventuels synonymes (tenant compte aussi des variants liés aux pluriels ou accents). Lis le texte qui suit et produit un code R qui permettrait de mettre à jour mon dictionnaire dic en y ajoutant le vocabulaire qui te semble représentatif de ce sujet scientifique (ou en mettant éventuellement à jour les synonymes de l'ensemble des mots de dic). Attention, donne une réponse la plus simple possible, uniquement un seul bloc de code R entre des bornes ```"


library(chatgpt) # Attention, il faut aller chercher la commande exec_chatgpt_code et charger son API

tokens <- 5000

for (i in 1:length(corpus)) {

print(i)

taille <- nchar(corpus[i])

# Si mon corpus est trop grand, il va falloir le traiter par paquets

if (taille>tokens ) {

print("Traitement par paquets, trop de tokens")

diviseur <- nchar(corpus[i])%/%5000+1

for (j in 1:diviseur) {

#consigne <- paste(commande_de_base,paste(capture.output(print(dic)),collapse="  "))

                       consigne <-paste(commande_de_base,paste(capture.output(print(data.frame(t(unlist(dic))))),collapse=" "))

consigne <- paste(consigne," et un morceau de la publication à traiter :")

                        consigne <- paste(consigne, substr(corpus[i], j*tokens -(tokens -1), j*tokens ))

               generated_text <- ask_chatgpt(consigne)

               exec_chatgpt_code(generated_text) # Mise à jour du dictionnaire - commande à télécharger

                      reset_chat_session(system_role = "You are a R coder.") 

}

} else {

consigne <-paste(commande_de_base,paste(capture.output(print(data.frame(t(unlist(dic))))),collapse=" "))

consigne <- paste(consigne," et un morceau de la publication à traiter :")

consigne <- paste(consigne, corpus[i])

               generated_text <- ask_chatgpt(consigne)

                 exec_chatgpt_code(generated_text)

               reset_chat_session(system_role = "You are a R coder.") 

}

}

dic <- dictionary(dic)

7- Nettoyer le token pour remplacer les synonymes par le terme de base

toks_news <- tokens_lookup(toks_news, dic, exclusive=T, levels=1:2, nomatch = "_UNMATCHED")

8- Mise du token en DFM (Matrice d'occurences)

my_dfm<- dfm(toks_news)

9- Générer une matrice de cooccurrences

mywd <- dico_perso[,1] ; nperso <- length(mywd)

mymat <- fcm(toks_news, context = "window", count = "weighted", window = 12,

            , ordered = TRUE, tri = FALSE)

positionr <- na.omit(match(mywd,rownames(mymat))) 

positionc <- na.omit(match(mywd,colnames(mymat))) 

matx <- mymat[positionr, positionc]

nrow(matx) ; matx

10- Afficher le réseau correspondant  au sujet

Le code ci-dessous permet de construire le réseau suivant et de comprendre quels groupes de gènes sont liés dans la mise en place de la maladie du chancre colorée par Ceratocystis platani chez le platane.

net <- graph_from_adjacency_matrix(matx, weighted=T)

net <- simplify(net, remove.multiple = T, remove.loops = TRUE) # élaguer les liens redondants

E(net)$arrow.size <- 0 # Exemple de sauvegarde d'un paramètre qu'on aurait plus ainsi à mettre dans comme paramètre de plot comme c'est le cas ci-dessous...

E(net)$edge.color <- "black"

# Afficher le tout en tenant compte avec betweenness du poids relatifs d'un mot pour lui donner une taille

plot(net ,vertex.size=sqrt(betweenness(net))+10,vertex.color="green",

edge.arrow.size =0,arrow.mode=0,edge.color="black")

#

clp <- cluster_optimal(net)

class(clp)

#

l <- layout_with_fr(net)

plot(clp, net, layout = l, vertex.size=sqrt(betweenness(net))+15)