2. Un cas pratique et pragmatique
• Contexte de l’étude
• Utilisation de R : pourquoi et comment ?
• Utilisation de la BDD : utilisation
détournée de R
• Mise en forme des données : plyr
• Modèles de mélange : flexmix
• Quelques suites/améliorations à donner
12/06/2013 Utiliser R au quotidien 2
4. 12/06/2013 Utiliser R au quotidien 4
Prélèvements
Laboratoire +
BDD
Analyses + rapports
Contexte de l’étude
~ 4 mois14 mois 12 mois
5. peut tout faire !!
• S’interfacer avec MySQL
• Import/export de données
• Mise en forme des données
• Traitement statistique
• Sorties graphiques
12/06/2013 Utiliser R au quotidien 5
Les besoins ?
6. • Rappel : avant tout un logiciel de stats
• Générer du temps ?
– Compromis efficacité/délais
• Optimisation des pratiques selon l’utilisation
• Ne peut pas pallier à toutes les contraintes
• Outil riche (> 4500 packages)
• On se fait sa propre boîte
12/06/2013 Utiliser R au quotidien 6
…ou presque
7. • 120 000 individus (3 mesures)
• 8000 points GPS + ~20 variables
12/06/2013 Utiliser R au quotidien 7
Base de données
• Server MySQL (externe) couplé à
phpmyadmin
• Interface php de saisie
• RODBC
• ROracle
• RJDBC
RMySQL
8. 12/06/2013 Utiliser R au quotidien 8
Base de données
- saisie -
• Interface php lente et peu optimisable (durée d’étude courte 2 ans ½)
• Impossibilité d’import de tableaux complets
• Approche pragmatique
- Saisie sous excel (plus rapide)
- Utilisation « détournée » de R
• R sait écrire !
• Fonction paste()
• -> on peut « écrire » du code de n’importe quel langage
• Combinaison avec apply()
10. 10
write.csv(
data.frame(
sql=apply(bddtot,1,
function(x) x <-
paste("INSERT INTO bp_poisson (id_point, cespece, taille,saisie,
taillefixee,taillestandard,taille_saisie,St_larvaire,
taillestandard_saisie,taillefixee_saisie,zoom)",
" VALUES(",x[1],",'",x[2],"',","0.00,-1,",x[9],
",",x[10],",0.00,",x[5],",",x[4],",",x[3],",'",x[6],"');",
"UPDATE bp_poisson SET saisie =
WHERE saisie = -1;",sep="")
)
)
,file="requeteSQL_ss_ech.csv",quote=FALSE,row.names=FALSE)
Base de données
- saisie -
sql
INSERT INTO bp_poisson (id_point, cespece, taille,saisie,taillefixee,taillestandard,taille_saisie,St_larvaire,taillestandard_saisie,taillefixee_saisie,zoom) VALUES(1021,'HOT',0.00,-1,14.22,12.00,0.00,2, 81.0, 96.0,'0.7')
INSERT INTO bp_poisson (id_point, cespece, taille,saisie,taillefixee,taillestandard,taille_saisie,St_larvaire,taillestandard_saisie,taillefixee_saisie,zoom) VALUES(1021,'HOT',0.00,-1,14.07,12.89,0.00,2, 87.0, 95.0,'0.7')
INSERT INTO bp_poisson (id_point, cespece, taille,saisie,taillefixee,taillestandard,taille_saisie,St_larvaire,taillestandard_saisie,taillefixee_saisie,zoom) VALUES(1021,'HOT',0.00,-1,13.63,12.59,0.00,2, 85.0, 92.0,'0.7')
INSERT INTO bp_poisson (id_point, cespece, taille,saisie,taillefixee,taillestandard,taille_saisie,St_larvaire,taillestandard_saisie,taillefixee_saisie,zoom) VALUES(1021,'HOT',0.00,-1,12.74,11.85,0.00,2, 80.0, 86.0,'0.7')
INSERT INTO bp_poisson (id_point, cespece, taille,saisie,taillefixee,taillestandard,taille_saisie,St_larvaire,taillestandard_saisie,taillefixee_saisie,zoom) VALUES(1021,'HOT',0.00,-1,14.07,13.04,0.00,2, 88.0, 95.0,'0.7')
INSERT INTO bp_poisson (id_point, cespece, taille,saisie,taillefixee,taillestandard,taille_saisie,St_larvaire,taillestandard_saisie,taillefixee_saisie,zoom) VALUES(1021,'HOT',0.00,-1,14.07,12.89,0.00,2, 87.0, 95.0,'0.7')
INSERT INTO bp_poisson (id_point, cespece, taille,saisie,taillefixee,taillestandard,taille_saisie,St_larvaire,taillestandard_saisie,taillefixee_saisie,zoom) VALUES(1021,'HOT',0.00,-1,14.67,13.63,0.00,2, 92.0, 99.0,'0.7')
INSERT INTO bp_poisson (id_point, cespece, taille,saisie,taillefixee,taillestandard,taille_saisie,St_larvaire,taillestandard_saisie,taillefixee_saisie,zoom) VALUES(1021,'HOT',0.00,-1,14.37,13.33,0.00,2, 90.0, 97.0,'0.7')
INSERT INTO bp_poisson (id_point, cespece, taille,saisie,taillefixee,taillestandard,taille_saisie,St_larvaire,taillestandard_saisie,taillefixee_saisie,zoom) VALUES(1021,'HOT',0.00,-1,14.67,13.33,0.00,2, 90.0, 99.0,'0.7')
• 60 000 requêtes unitaires
générées en un script
• Insertion dans la BDD via
phpmyadmin
11. 12/06/2013 Utiliser R au quotidien 11
Base de données
- interfacer R et MySQL -
library(RMySQL)
Connexion <-
dbConnect(MySQL(),dbname="rhonejuv",user="root",password= "MdP"
,host="localhost")
dbGetQuery(connexion,"select * from bp_poisson")->bp_poisson
dbGetQuery(connexion,"select * from bp_point")->bp_point db
GetQuery(connexion,"select * from bp_peche")->bp_peche
dbGetQuery(connexion,"select * from bp_station")->bp_station
RMySQL est un enfer à paramétrer !!!
Différence entre machine pour un même OS
Approche pragmatique
- dump de la base et travail en local (ex : Wampserver)
- Export des tables en .csv via SQL (phpmyadmin)
- Import des données sous R
12. 12/06/2013 Utiliser R au quotidien 12
Mise en forme des données
- package plyr -require(plyr)
for (m in 1:nlevels(edfjuvtaille_4sp$id_secteur)){
site <-
subset(edfjuvtaille_4sp,id_secteur==levels(edfjuvtaille_4sp$id_secteur)[m]
& typeStation=="RCC")
nomsite <- levels(edfjuvtaille_4sp$id_secteur)[m]
for (k in 1:nlevels(edfjuvtaille_4sp$id_campagne)){
camp <- subset(site,id_campagne==levels(site$id_campagne)[k])
nomcamp <- levels(edfjuvtaille_4sp$id_campagne)[k]
for (i in 1:nlevels(camp$cespece)){
sp <- subset(camp,cespece==levels(camp$cespece)[i] & LS<110)
nomsp <- levels(camp$cespece)[i]
sp$LS[sp$LS>=40] <- ((sp$LS[sp$LS>=40]-40)/3)+40
hist_global <- hist(sp$LS,breaks=clas1,plot=F,warn.unused =
FALSE,freq=T)
hist_global$counts <- sqrt(hist_global$counts) #échelle rac. carrée
bmp(paste("1histo",nomsp,"_",nomsite,nomcamp,"RCC.bmp",sep=""),width=1100)
par(las=1,lwd=1,mar=c(5,5,3,1),cex.axis=1.5,cex.lab=1.5,bty='n',mgp=c(2.5,1
,0))
if(nrow(sp)!=0){
plot(1,type='n',xlim=c(0,70),ylim=c(0,round_any(max(hist_global$counts),5,c
eiling)),xlab="Taille (mm)",ylab="nb. (sqrt scale)",yaxt='n',xaxt='n')
a <- (seq(50,120,by=10)-40)/3+40
axis(1,pos=c(0,0),at=c(seq(0,40,by=5),a),labels=c(seq(0,40,by=5),seq(50,120
,by=10)))
axis(2,pos=c(0,0),at=seq(0,round_any(max(hist_global$counts),5,ceiling),by=
5),labels=seq(0,round_any(max(hist_global$counts),5,ceiling),by=5)^2)
text(35,round_any(max(hist_global$counts),5,ceiling),labels=paste("C",k,":
",datep_peage$PRCC1[k,2],sep=""),cex=2,font=2)
legend(x=1,y=round_any(max(hist_global$counts),5,ceiling),pch=22,col=colSt,
legend=paste("St",0:5),pt.bg=colSt,pt.cex = 3,xpd=TRUE,cex=1.5)
for(j in 1:nlevels(sp$St_larvaire)){
options(warn=-1)
stade <- subset(sp,St_larvaire==levels(sp$St_larvaire)[j])
hist_st <- hist(stade$LS,breaks=clas1,freq=T,plot=F)
hist_st$counts <- sqrt(hist_st$counts)
lines(hist_st,col=rgb(t(col2rgb(colSt[j],alpha=T)),maxColorValue =
255,alpha=127),freq=T)
options(warn=0)
}
}
else{
a <- (seq(50,120,by=10)-40)/3+40
plot(1,type='n',xlim=c(0,70),ylim=c(0,10),xlab="Taille
(mm)",ylab="nb.",yaxt='n',xaxt='n')
axis(1,pos=c(0,0),at=c(seq(0,40,by=5),a),labels=c(seq(0,40,by=5),seq(50,120
,by=10)))
axis(2,pos=c(0,0),at=seq(0,10,by=5),labels=seq(0,10,5))
Distribution de taille
Objectif : obtenir les distributions de
taille par espèce à chaque site et à
chaque date.
« mise en forme » est sous-jacente
(nécessaire à l’objectif)
13. 12/06/2013 Utiliser R au quotidien 13
require(plyr)
for (m in 1:nlevels(edfjuvtaille_4sp$id_secteur)){
site <-
subset(edfjuvtaille_4sp,id_secteur==levels(edfjuvtaille_4sp$id_secteur)[m]
& typeStation=="RCC")
nomsite <- levels(edfjuvtaille_4sp$id_secteur)[m]
for (k in 1:nlevels(edfjuvtaille_4sp$id_campagne)){
camp <- subset(site,id_campagne==levels(site$id_campagne)[k])
nomcamp <- levels(edfjuvtaille_4sp$id_campagne)[k]
for (i in 1:nlevels(camp$cespece)){
sp <- subset(camp,cespece==levels(camp$cespece)[i] & LS<110)
nomsp <- levels(camp$cespece)[i]
sp$LS[sp$LS>=40] <- ((sp$LS[sp$LS>=40]-40)/3)+40
hist_global <- hist(sp$LS,breaks=clas1,plot=F,warn.unused =
FALSE,freq=T)
hist_global$counts <- sqrt(hist_global$counts) #échelle rac. carrée
bmp(paste("1histo",nomsp,"_",nomsite,nomcamp,"RCC.bmp",sep=""),width=1100)
par(las=1,lwd=1,mar=c(5,5,3,1),cex.axis=1.5,cex.lab=1.5,bty='n',mgp=c(2.5,1
,0))
if(nrow(sp)!=0){
plot(1,type='n',xlim=c(0,70),ylim=c(0,round_any(max(hist_global$counts),5,c
eiling)),xlab="Taille (mm)",ylab="nb. (sqrt scale)",yaxt='n',xaxt='n')
a <- (seq(50,120,by=10)-40)/3+40
axis(1,pos=c(0,0),at=c(seq(0,40,by=5),a),labels=c(seq(0,40,by=5),seq(50,120
,by=10)))
axis(2,pos=c(0,0),at=seq(0,round_any(max(hist_global$counts),5,ceiling),by=
5),labels=seq(0,round_any(max(hist_global$counts),5,ceiling),by=5)^2)
text(35,round_any(max(hist_global$counts),5,ceiling),labels=paste("C",k,":
",datep_peage$PRCC1[k,2],sep=""),cex=2,font=2)
legend(x=1,y=round_any(max(hist_global$counts),5,ceiling),pch=22,col=colSt,
legend=paste("St",0:5),pt.bg=colSt,pt.cex = 3,xpd=TRUE,cex=1.5)
for(j in 1:nlevels(sp$St_larvaire)){
options(warn=-1)
stade <- subset(sp,St_larvaire==levels(sp$St_larvaire)[j])
hist_st <- hist(stade$LS,breaks=clas1,freq=T,plot=F)
hist_st$counts <- sqrt(hist_st$counts)
lines(hist_st,col=rgb(t(col2rgb(colSt[j],alpha=T)),maxColorValue =
255,alpha=127),freq=T)
options(warn=0)
}
}
else{
a <- (seq(50,120,by=10)-40)/3+40
plot(1,type='n',xlim=c(0,70),ylim=c(0,10),xlab="Taille
(mm)",ylab="nb.",yaxt='n',xaxt='n')
axis(1,pos=c(0,0),at=c(seq(0,40,by=5),a),labels=c(seq(0,40,by=5),seq(50,120
,by=10)))
axis(2,pos=c(0,0),at=seq(0,10,by=5),labels=seq(0,10,5))
Mise en forme des données
- package plyr -
ddply(subset(edfjuvtaille_4sp,typeStation=="RCC"),~id_secteur+id_campagne+c
espece,
Allègement sensible
data
site
espèce
• Conserve le format global
• Ajout de colonne
• Synthèse (moyenne…)
• Toute sortie possible
• Il suffit de définir la fonction
• Plyr ≠ optimisation de temps de calcul
• Calcul parallèle possible (.parallel) avec les
packages foreach et doParallel
Mise en forme du
graphique
14. 12/06/2013 Utiliser R au quotidien 14
Mise en forme des données
- package plyr -
Au final :
~300 graphiques générés dans un format commun
Phase suivante :
Les analyses stats
lines(hist_st,col=rgb(t(col2rgb(colSt[j],alpha=
T)),maxColorValue = 255,alpha=127),freq=T)
Transparence des couleurs : dépend du périphérique choisi
NB : pour les graphiques, toujours avoir un exemplaire de :
« Les paramètre graphiques ». Fiche tdr75 du pbil écrite par J. Lobry
15. 12/06/2013 Utiliser R au quotidien 15
Modèles de mélange
- package flexmix -
ApparitiondeA
ApparitiondeB
chronique <- vector("list",4)
names(chronique) <- tps
chronique[[1]] <- rnorm(300,taillemu[1],taillesd[1])
chronique[[2]] <- rnorm(250,taillemu[2],taillesd[2])
chronique[[3]] <- rnorm(200,taillemu[3],taillesd[3])
chronique[[4]] <- rnorm(150,taillemu[4],taillesd[4])
chronique_hist <- lapply(chronique,
function(x) hist(x,plot=F,breaks=seq(0,55,by=1)))
N <- length(chronique_hist)
for(j in 2:N) {
HIST <- chronique_hist[[j]]
n <- length(HIST$counts)
for(i in 1:n){
y <- rep(tps[j],4)
x <- rep(HIST$breaks[c(i,i+1)],each=2)
z <- rep(c(0,HIST$counts[i]),2)
coord <- data.frame(x,y,z)
segments3d(coord,col='black')
y <- rep(tps[j],2)
x <- HIST$breaks[c(i,i+1)]
z <- rep(HIST$counts[i],2)
coord <- data.frame(x,y,z)
segments3d(coord)
}
}
rgl.postscript("test.eps")
Couleurs via logiciel graphique
- Possibilité via polygon()
On peut faire de la 3D sous R : exemple avec le package rgl
Théorie
16. 12/06/2013 Utiliser R au quotidien 16
Modèles de mélange
- package flexmix -
stepflexmix(LS~1,data=ABLbaix2011[[i]][[2]],control=list(iter.max=1000,
classify="SEM"),concomitant=FLXPmultinom(~C(factor(St_larvaire,levels=1:6),
poly,1)),k=1:4)
• Mélange de différentes lois
• Chaque composante à un poids
• Prédicteurs pour
Les paramètres de chaque
composante
Le poids de chaque
composante
• Processus itératif pour tester 1
à k composantes
• Algorithme EM
• Sélection par AIC, BIC…
17. 12/06/2013 Utiliser R au quotidien 17
Modèles de mélange
- package flexmix -
Sortie du modèle : proba d’appartenance à
une composante k
Hypothèse:
Mélange de k gaussienne
au sein de la distribution de
taille
18. 12/06/2013 Utiliser R au quotidien 18
Quelques suites/améliorations
Optimisation du code
- Boucle/apply : retour d’expérience pas si évident que ça
- Eviter les stockages en mémoire
- Vectorisation (calcul matriciel)
- Limiter l’usage des listes surtout dans les étapes intermédiaires
Reporting (construction automatique du rapport final)
- Sweave
- Knitr
- Très pratique dans les études avec des rapports intermédiaires
19. 12/06/2013 Utiliser R au quotidien 19
Conclusion
• très pratique, très puissant
• Sans limite ?
• Finalement il ne faut qu’une chose :
du temps !