19
Nicolas PERU 12/06/2013

Meetup juin2013

  • Upload
    nperu

  • View
    242

  • Download
    2

Embed Size (px)

Citation preview

Page 1: Meetup juin2013

Nicolas PERU 12/06/2013

Page 2: Meetup juin2013

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

Page 3: Meetup juin2013

Contexte de l’étude

12/06/2013 Utiliser R au quotidien 3

Photos G. Carrel/N. Stolzenberg

Page 4: Meetup juin2013

12/06/2013 Utiliser R au quotidien 4

Prélèvements Laboratoire + BDD Analyses + rapports

Contexte de l’étude

~ 4 mois 14 mois 12 mois

Page 5: Meetup juin2013

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 ?

Page 6: Meetup juin2013

• 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

Page 7: Meetup juin2013

• 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

Page 8: Meetup juin2013

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()

Page 9: Meetup juin2013

9

head(bddtot) id_point cespece taillefixee_saisie taillestandard_saisie St_larvaire zoom eff convzoom 1295 337 GAR 88 84 1 1.25 5099 0.08081 1296 337 GAR 77 73 1 1.25 5099 0.08081 1297 337 GAR 94 90 1 1.60 5099 0.06316 1298 337 GAR 83 79 1 1.25 5099 0.08081 1299 337 GAR 90 86 1 1.25 5099 0.08081 1300 337 GAR 89 84 1 1.25 5099 0.08081 taillefixee taillestandard 1295 7.11 6.79 1296 6.22 5.90 1297 5.94 5.68 1298 6.71 6.38 1299 7.27 6.95 1300 7.19 6.79

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 -

Sais

ie e

xcel

Page 10: Meetup juin2013

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 -

sqlINSERT 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

Page 11: Meetup juin2013

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

Page 12: Meetup juin2013

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,ceiling)),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)

Page 13: Meetup juin2013

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,ceiling)),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+cespece,

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

Page 14: Meetup juin2013

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

Page 15: Meetup juin2013

12/06/2013 Utiliser R au quotidien 15

Modèles de mélange - package flexmix -

App

ariti

on d

e A

App

ariti

on d

e B

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

Page 16: Meetup juin2013

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…

Page 17: Meetup juin2013

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

Page 18: Meetup juin2013

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

Page 19: Meetup juin2013

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 !