Un tout petit billet pour compléter sur les cartes... j’ai découver la fonction match.map() de library(maps), qui assigne automatiquement un code R pour un département français à un nom que l’on connaît...
> library(maps)
> france<-map(database="france")
> france$names
> dpt=c("Calvados","Nord","Ille-et-Vilaine","Bouches-du-Rhone")
> couleur=c(2,3,4,6)
> match=match.map(france,dpt)
> color=couleur[match]
> map(database="france", fill=TRUE, col=color)
Ceci répondre à quelques questions posées très récemment
Informatique / R
vendredi 6 novembre 2009
Cartes avec R (partie 4)
Par Arthur Charpentier le vendredi 6 novembre 2009, 00:14
mercredi 28 octobre 2009
La base des graphiques avec R
Par Arthur Charpentier le mercredi 28 octobre 2009, 13:52
Dans les cours d’économétrie, j’apprends à utiliser R, mais je dois avouer que je ne passe pas beaucoup de temps sur la paramétrisation des graphiques... A la demande générale, je vais écrire trois lignes pour expliquer ce que j’ai pu comprendre de la manière de générer des graphiques sous R.
- La fonction plot()
- Quelques paramtères de la fonction plot()
> plot(cars)
> plot(cars,axes=FALSE); axis(1)

> plot(cars,axes=FALSE,xlab="")
> axis(1,col="red",col.axis="blue",font.axis=3)
> axis(2)
> title(xlab="vitesse de la voiture",font.lab=2,col.lab="green",cex.lab=1)
ou encore
> plot(cars,axes=FALSE,ylab="")
> axis(1)
> axis(2,col="red",col.axis="blue",font.axis=2,las=2)
> title(ylab="distance de freinage",font.lab=1,col.lab="red",cex.lab=1.2)

> par(bg = "thistle")
> plot(cars)
ou bien
> library(pixmap)
> bck <- read.pnm("D:\\fond.pnm")
> plot(bck)
> axis(1)
> axis(2)
Dans ce dernier cas, la taille des axes est liée à la résolution de l’image... on utilise plutôt ça pour des cartes,

> plot(cars,pch=c(1:25,1:25))
> plot(cars,pch=1,cex=seq(0.25,2,length=50))

- Les fonctions abline(), lines() et points()
> plot(cars)
> abline(lm(dist~speed,cars),col="red")
> abline(a=-17.579,b=3.932,col="blue",lwd=2)

> reg=lm(dist~I(speed^2),cars)
> x=seq(5,25,by=0.5)
> y=predict(reg,newdata=data.frame(speed=x))
> plot(cars)
> lines(x,y,lwd=2,col="green")
> reg=lm(dist~speed+I(speed^2)+I(speed^3)+I(speed^4),cars)
> x=seq(5,25,by=0.5)
> y=predict(reg,newdata=data.frame(speed=x))
> plot(cars)
> lines(x,y,lty=2,col="purple")
Cette fonction peut être utilisée, par exemple, pour rajouter une estimation de densité sur un histogramme. Par exemple
> hist(residus,proba=TRUE,col="light green")
> lines(density(residus),col="red",lwd=2)
> x=seq(min(residus),max(residus),lenght=100)
> y=dnorm(x,,mean=0,sd=sd(residus))
> lines(x,y,col="blue",lty=2)
> points(residus,rep(0.037,50))
La fonction points() ici permet de tracer des points, sans les relier. Sinon on peut aussi s’amuser à colorier des régions avec la fonction polygon(),
> densite=density(residus)
> X=densite$x
> Y1=densite$y
> Y2=dnorm(X,,mean=0,sd=sd(residus))
> plot(X,Y1,axes=FALSE,type="l")
> axis(1); axis(2)
> polygon(c(X,rev(X)),c(Y1,rev(Y2)),col="light pink",border = 0)
> lines(X,Y2,col="blue",lty=2)
> lines(X,Y1,col="red",lwd=2)

- Tracer une série temporelle
> gnp <- ts(cumsum(1 + round(rnorm(100), 2)),
+ start = c(1954, 7), frequency = 12)
> plot(gnp) # using ’plot.ts’ for time-series plot
Mais on peut aussi tenter de visualiser des données irrégulièrement espacées dans le temps. Et là c’est un peu plus vicieux.
> dates <- c("02/27/92", "02/27/92", "01/14/92", "02/28/92", "02/01/92")
> z=as.Date(dates, "%m/%d/%y")
> zs=sort(z)
> plot(zs,y,type="p")
> plot(zs,y,type="b",col="blue")
La fonction as.Date() permet de convertir une chaîne de caractère sous un format date.

> require(gplots)
> series <- arima.sim(list(ar=0.9),n=250)
> model=arima(series[1:200],c(1,0,0))
> forecast=predict(model,80)
> ylim <- c( min(series[1:200],forecast$pred - 1.96 * forecast$se),
+ max(series[1:200],forecast$pred + 1.96 * forecast$se))
> opar <- par(mar=c(4,4,2,2),las=1)
> plot(series,ylim=ylim,type="n",xlim=c(1,250))
> usr <- par("usr")
> rect(usr[1],usr[3],201 ,usr[4],border=NA,col="light blue")
> rect(201 ,usr[3],usr[2],usr[4],border=NA,col="lavender")
> abline(h= (-3:3)*2 , col ="gray" , lty =3)
> polygon( c(201:280,280:201),
+ c(forecast$pred - 1.96*forecast$se,rev(forecast$pred + 1.96*forecast$se)),
+ col = "light pink",
+ lty=2,border=NA)
> lines( 201:280 , forecast$pred - 1.96*forecast$se , lty=2)
> lines( 201:280 , forecast$pred + 1.96*forecast$se , lty=2)
> lines( series , lwd=2 )
> lines(201:280 , forecast$pred , lwd=2 , col ="white")

- Tracer des figures avec deux axes (indépendants)
> x=seq(-4,4,length=200)
> y1 = sin(x); y2 = 5*cos(x)
> plot(x, y1, col="blue", type="l",ylim=c(-5,5),axes=FALSE)
> axis(1); axis(2)
> lines(x, y2,col="red")
On peut essayer de faire les deux courbes l’une après l’autre. Pour cela, il vaut juste commencer à utiliser la fonction par() qui gère les fenêtre graphiques,
> ylim <- c(-1.1, 1.1)
> plot(x, y1, col="blue", type="l", ylim=ylim,axes=FALSE, ylab="")
> axis(1);
> ylim <- c(-5.5, 5.5)
> axis(2, col="blue")
> par(new=TRUE)
> plot(x, y2, col="red", type="l", ylim=ylim,axes=FALSE, ylab="")
> axis(4, col="red")
> mtext("Axe du premier graphique", 2, line=2, col="blue", cex=1.2)
> mtext("Axe du second graphique", 4, line=2, col="red", cex=1.2)

plot.new()
par(fig=c(0.1, 0.6, 0.1, 0.6))
plot(cars,type="p",col="red",lwd=2)
par(new=TRUE)
par(fig=c(0.4, 0.9, 0.4, 0.95))
plot(cars[,2:1],type="p",col="green",lwd=2)
ou on peut insérer un petit graphique dans un plus grand
> plot.new()
> plot(cars,type="p",col="red",lwd=2)
> par(new=TRUE)
> par(fig=c(0.1, 0.7, 0.55, 0.98))
> plot(cars,type="p",col="green",lwd=2)

- Tracer des jolis graphiques, last but not least
> library(evd); data(lossalae)
> plot(lossalae)
permet de visualiser les données brutes, mais on peut faire plus joli,
> x <- lossalae$Loss; y <- lossalae$ALAE
> xhist <- hist(log(x), plot=FALSE)
> yhist <- hist(log(y), plot=FALSE)
> top <- max(c(xhist$counts, yhist$counts))
> nf <- layout(matrix(c(2,0,1,3),2,2,byrow=TRUE), c(3,1), c(1,3), TRUE)
> par(mar=c(3,3,1,1))
> plot(x, y, xlab="", ylab="",log="xy",col="red")
> par(mar=c(0,3,1,1))
> barplot(xhist$counts, axes=FALSE, ylim=c(0, top), space=0,col="light green")
> par(mar=c(3,0,1,1))
> barplot(yhist$counts, axes=FALSE, xlim=c(0, top), space=0, horiz=TRUE,col="light blue")

lundi 28 septembre 2009
Créer des images LaTex
Par Arthur Charpentier le lundi 28 septembre 2009, 09:18
Comme l’insertion de LaTeX n’est plus disponible sur le blog, la solution la plus simple est d’insérer des images (contenant les formules). C’est un peu plus lourd, mais ça marche... Bref, Google a développé un petit widget pour faire ça simplement, je vais donc le mettre ici parce que je passe mon temps à en chercher (il y en existe d’autres ici ou là)
lundi 24 août 2009
Une autre façon de faire du R, sans en avoir l'air
Par Arthur Charpentier le lundi 24 août 2009, 11:26
R commander (dans son nom français) permet faire du R sans coder, en cliquant sur la souris, pour ceux qui
auraient peur (du code, pas de la souris)... En pratique, il faut
installer le package de R Commander (library(Rcmdr)) lors de la première installation,
i.e. avant l’installation de tous les autres packages. On a alors à
disposition une interface pour utiliser les fonctions R.
John Fox a publié une introduction à Rcmdr (ici), et on notera que cet outil est très proche, par exemple, de l’intégration de R dans excel (ici ou là sur la toile - parmi tant d’autres - ou encore ici ou là
sur ce blog). Dans le cas de l’analyse des données, le package FactoMineR (développé à l’agro) propose une interface via R Commander.

Proposer des interphaces simples de R pour des utilisateurs ne souhaitant pas programmer a été au coeur de la dernière conférence UseR!, donc je pense que beaucoup de choses arriveront prochainement sur le sujet ! à suivre donc.....
jeudi 2 juillet 2009
UseR, tutoriels: gnm et big(g)glm (1)
Par Arthur Charpentier le jeudi 2 juillet 2009, 12:33
N’ayant pas encore de don d’ubiquité, je ne pourrais suivre que deux tutoriels mardi à la conférence useR! (le programme est toujours ici). Le matin, c’est l’économétrie sur les très grosses bases de données, avec un exposé de Thomas Lumley sur les library(biglm) et library(bigglm).
L’après midi, Heather Turner viendra présenter library(gnm) d’économétrie nonlinéaire (très utilie pour les modèles un peu poussés de mortalité par exemple). Les slides sont en ligne ici. Pour un petit exemple sur le modèle de Lee-Carter, en mortalité, c’est assez facile.
> Ex = read.table("http://perso.univ-rennes1.fr/arthur.charpentier/FR-Exposures_1x1.txt",header=TRUE)
> Death = read.table("http://perso.univ-rennes1.fr/arthur.charpentier/FR-Deaths_1x1.txt",header=TRUE)
> Ex1 = Ex[Ex$Age!="110+",]
> Ex1$AgeI = as.integer(as.character(Ex1$Age))
> Death1 = Death[Death$Age!="110+",]
> Death1$AgeI = as.integer(as.character(Death1$Age))
> Ex = subset(Ex1,select=
+ c("Year","AgeI","Female","Male","Total"))
> names(Ex) = c("Y","A","EF","EM","ET")
> Death = data.frame(Y=Death1$Year,A=Death1$AgeI,
+ DF=Death1$Female,DM=Death1$Male,DT=Death1$Total)
> Base=merge(Ex,Death)
> SBase=Base
> SBase=Base[(Base$A>(-1))&(Base$A<95)==TRUE,]
Pour la suite, il convient d’être un peu patient, l’optimisation se faisant en (très) grande dimension, avec presque 300 paramètres.
> SBase$A=as.factor(SBase$A)
> SBase$Y=as.factor(SBase$Y)
> SBase$Age=as.numeric(as.character(SBase$A))
> SBase$Year=as.numeric(as.character(SBase$Y))
> library(gnm)
> REG = gnm(DT ~ A + Mult(Exp(A),Y),offset=log(ET),
+ family="quasipoisson",data=SBase)
Initialising
Running start-up iterations..
Running main iterations....................
Done


Et
voilà, ensuite il suffit de tracer les coefficients de la régression.
C’est d’ailleurs ce package qui a permis de faire les graphiques de
fond des Journées d’Economiet et d’Econométrie de l’Assurance (ici). Le
code suivant permet de récupérer les résidus en fonction de la variable
âge, par exemple,> AGE=unique(SBase$Age)
> res <- residuals(REG, type = "pearson")
> COULEUR=SBase$Year-1898
> CH.COL=heat.colors(max(COULEUR)*1.25)
> COUL=CH.COL[COULEUR]
> plot(SBase$Age, res, xlab="",ylab="",
+ main = "",col=COUL,cex=0.7,xlim=c(0,95),axes=FALSE)
> axis(1)
Ou sinon en fonction de l’année,> YEAR=unique(SBase$Year)
> res <- residuals(REG, type = "pearson")
> COULEUR=SBase$Age
> CH.COL=heat.colors(max(COULEUR)*1.25)
> COUL=CH.COL[COULEUR]
> plot(SBase$Year, res, xlab="", ylab="",
+ main = "",col=COUL,cex=0.7,xlim=c(1899,2005),axes=FALSE)
> axis(1)

mercredi 1 juillet 2009
Censure (et statistiques)
Par Arthur Charpentier le mercredi 1 juillet 2009, 22:24
Je vais faire un petit billet pour répondre à une question de Sonia, sur la "censure à gauche" (dans un cadre statistique !). Il existe plusieurs types de censure en statistique, sur les modèles de durée. Soit Y la variable (positive) d’intérêt,
- si au lieu d’observer Y on observe C, et si on sait que Y>C, on parle de censure à droite,
- si au lieu d’observer Y on observe C, et si on sait que Y<C, on parle de censure à gauche,
- si C est une variable aléatoire, on parle de censure aléatoire.
Le censure droite peut être visualisée ci-dessous. On observe la durée rouge, mais les observations sont parfois censurées (la durée non-observée est en bleu). Notons que la censure peut dépendre des observations, ou peut même être aléatoire. De plus, les variables Y et C ne sont pas forcément indépendantes. Un exemple classique est l’étude de la stérilité des couples, où passé un certain temps, les couples peuvent se lassser..
Example:
En assurance, les coûts de sinistres sont parfois censuré à droite: un
cambriolage d’appartement est remboursé mais avec un plafond
correspondant à la valeur de biens assurés. Le coût d’un sinistre peut
être de 13000 euros, mais si l’assuré n’es couvert que jusqu’à 8000
euros, la base de donnée n’indique que le montant maximal. Les données
sont alors censurées à droite. Un exemple connu est celui dit loss-alae
(avec les indemnités de sinistres, qui sont plafonnés, et les frais
associés), ici.On essaye de déterminer l’âge à partir duquel des enfants savent accomplir une tâche. Au début de l’expérience (ou de la période d’observation) certains savent l’accomplir, et à la fin, certain ne savent toujours pas l’accomplir. Dans ce cas, les observations sont censurées soit à droite, soit à gauche, on parle éventuellement de censure par intervalle.
Le dessin ci-dessous montre la censure à gauche, avec également la censure par intervalle.
Remarque:
malgré la symétrie qu’il semble y avoir entre les deux types de
censure, ce n’est pas forcément le cas. On cherche à estimer la loi
d’une durée (aléatoire), par exemple une durée de chômage, caractérisée par une date (aléatoire) de début, notée A, et une date
de fin (elle aussi aléatoire) notée B.La censure à droite correspond à une non-observation de B, et pareil pour A. Sauf que B peut éventuellement ne jamais survenir. C’est en particulier le cas si A correspond à l’apparition de symptômes d’une maladie, et B correspond à la survenance de la maladie.
On peut raffiner un peu la terminologie, en particulier en introduisant une notion de troncature,
- on dit qu’il y a troncature à gauche si Y n’est pas observable lorsqu’elle est inférieure à un seuil C>0 (fixé)
- on dit qu’il y a troncature à droite si Y n’est pas observable lorsqu’elle est supérieure à un seuil C>0 (fixé)
Pour aller un peu plus loin sur la pratique, R possède la library(survival) qui permet de modéliser la loi d’une durée avec une censure à droite. Il existe alors une classe d’objets crées à l’aide de la fonction Surv(). Parmi les options, il y a un paramètre type,
typecharacter string specifying the type of censoring. Possible values
are "right", "left", "counting",
"interval", or "interval2". The default is
"right" or "counting" depending on whether the
time2 argument is absent or present, respectively.
En effet, il y a un peu plus de censure que les cas que j’ai évoqué, par exemple le fait que l’on observe que tous les ans (et donc on n’a qu’une information partielle). Générons 20 données censurées, avec censure aléatoire,
> n=20; T=rexp(n); C=rep(2,n)
> X=apply(data.frame(T,C),1,min)
> censor= (T==X)*1
> T
[1] 0.2410449437 2.3516699834 0.3005893449 0.2301904927 0.6113286791
[6] 0.5029715366 0.6311333952 0.8279694889 0.6825748561 0.4645671406
[11] 0.3115108991 0.0001663509 0.4970689723 0.9466705741 0.3820180311
[16] 1.5033942144 0.0530316979 4.0514764393 0.2316851578 0.4973463849
> X
[1] 0.2410449437 2.0000000000 0.3005893449 0.2301904927 0.6113286791
[6] 0.5029715366 0.6311333952 0.8279694889 0.6825748561 0.4645671406
[11] 0.3115108991 0.0001663509 0.4970689723 0.9466705741 0.3820180311
[16] 1.5033942144 0.0530316979 2.0000000000 0.2316851578 0.4973463849
> censor
[1] 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
> SX=Surv(X,censor)
> SX
[1] 0.2410449437 2.0000000000+ 0.3005893449 0.2301904927 0.6113286791
[6] 0.5029715366 0.6311333952 0.8279694889 0.6825748561 0.4645671406
[11] 0.3115108991 0.0001663509 0.4970689723 0.9466705741 0.3820180311
[16] 1.5033942144 0.0530316979 2.0000000000+ 0.2316851578 0.4973463849
> plot(survfit(SX))
Il s’agit de l’estimateur de Kaplan-Meier. Mais je ferais un billet par la suite, si je trouve le temps... En attendant, je peux renvoyer vers quelques références ici, là ou encore là en français.

Si on travaille avec une censure par intervalle, c’est un peu plus complet. Par exemple, avec library(survival)
> n=100
> X1=rep(NA,n)
> X2=C1=C2=Cens1=Cens2=Y1=Y2=TYPE=Duree=X1
> for(i in 1:n){
+ X=rnorm(15)
+ X1[i]=mean(X)-qt(.975,15)*sqrt(var(X))
+ X2[i]=mean(X)+qt(.975,15)*sqrt(var(X))
+ C1[i]=-1.96
+ C2[i]=1.96
+ Cens1[i]=(X1[i]<C1[i])
+ Cens2[i]=(X2[i]>C2[i])
+ Y1[i]=max(X1[i],C1[i])
+ Y2[i]=min(X2[i],C2[i])
+ TYPE[i]=1
+ if(Cens1[i]==1){TYPE[i]=2}
+ if(Cens2[i]==1){TYPE[i]=0}
+ if(((Cens1[i]==1)&(Cens2[i]==1))==TRUE){TYPE[i]=3}
+ Duree[i]=Y2[i]-Y1[i]
+ }
> S=Surv(time=Y1,time2=Y2,event=TYPE,type="interval")
> S
[1] -1.737262 [-1.960000, 1.96] [-1.960000, 1.96] [-1.960000, 1.96]
[5] -1.960000- -1.332074 -1.817311+ [-1.960000, 1.96]
[9] -1.960000- [-1.960000, 1.96] [-1.960000, 1.96] [-1.960000, 1.96]
[13] [-1.960000, 1.96] [-1.960000, 1.96] -1.887473+ -1.790832
[17] [-1.960000, 1.96] [-1.960000, 1.96] -1.862076+ [-1.960000, 1.96]
[21] [-1.960000, 1.96] [-1.960000, 1.96] [-1.960000, 1.96] -1.716272+
[25] -1.558675+ [-1.960000, 1.96] -1.960000- [-1.960000, 1.96]
[29] -1.932491+ -1.545382 -1.960000- -1.960000-
[33] [-1.960000, 1.96] -1.960000- -1.657818 [-1.960000, 1.96]
[37] -1.960000- [-1.960000, 1.96] -1.877989 -1.957118+
[41] [-1.960000, 1.96] [-1.960000, 1.96] [-1.960000, 1.96] -1.960000-
[45] -1.856793 -1.273652 [-1.960000, 1.96] [-1.960000, 1.96]
[49] [-1.960000, 1.96] [-1.960000, 1.96] -1.359959+ -1.634583+
[53] -1.212742 [-1.960000, 1.96] [-1.960000, 1.96] -1.647137+
[57] [-1.960000, 1.96] -1.880130+ -1.616234+ -1.831402
[61] [-1.960000, 1.96] -1.960000- [-1.960000, 1.96] [-1.960000, 1.96]
[65] [-1.960000, 1.96] [-1.960000, 1.96] -1.960000- -1.960000-
[69] [-1.960000, 1.96] -1.383674 [-1.960000, 1.96] [-1.960000, 1.96]
[73] -1.713565+ -1.567787+ -1.954177 [-1.960000, 1.96]
[77] -1.628864+ -1.809845 [-1.960000, 1.96] -1.416453
[81] -1.744155 -1.960000- -1.576735 [-1.960000, 1.96]
[85] [-1.960000, 1.96] -1.594431+ [-1.960000, 1.96] [-1.960000, 1.96]
[89] -1.960000- -1.960000- [-1.960000, 1.96] -1.664785
[93] -1.692345+ [-1.960000, 1.96] [-1.960000, 1.96] [-1.960000, 1.96]
[97] [-1.960000, 1.96] [-1.960000, 1.96] [-1.960000, 1.96] [-1.960000, 1.96]
Voici un petit schéma pour visualiser ces données censurées,
(les vraies durées sont en bleu, et on observe les durées rouge). Le hic est que l’estimation de Kaplan-Meier ne semble marcher que pour la censure à droite. Et plus généralement, comme noté ici, "note
that not all functions will accept all types of data. For example,
interval-censored data will not be accepted by the majority of the
functions in survival". Heureusement, il existe des dizaines d’autres packages pour les modèles de durée sous R (décrits ici). Mais les méthodes les plus développées semblent être des techniques Bayesiennes. Ceci est évoqué dans ce papier (ici). Je pense qu’il serait temps que je fasse des billets sur la statistique et l’économétrie bayesienne !Sinon si quelqu’un connait des codes pour estimer la distribution de la longueur de l’intervalle sur l’exemple précédant, je suis intéressé !
mardi 30 juin 2009
Cartes avec R (partie 3)
Par Arthur Charpentier le mardi 30 juin 2009, 15:39
J’avais parlé dans un précédant billet (ici)
des fonds de cartes avec R. Pour reprendre rapidement, on peut faire
des cartes simplement avec des commandes de la forme suivante,
> library(maps)
> map(database="world",regions="France")
Cette dernière commande permet de tracer une carte. Bon, le soucis
avec la France (d’un point de vue de la programmation sous R, je ne
veux me froisser avec personnes) ce sont ses territoires d’outre-mer.
> M1=map(database="world",regions="France",xlim=c(-5,10),ylim=c(40,52))
> str(M1)
’data.frame’: 27 obs. of 5 variables:
$ montant: num 1180374 10897008 6662276 9516513 2102222 ...
$ Y1 : num 2003 2003 2003 2003 2003 ...
$ Y2 : num 2004 2005 2006 2007 2008 ...
$ Z1 : num 1 1 1 1 1 1 2 2 2 2 ...
$ Z2 : num 1 2 3 4 5 6 1 2 3 4 ...
Pour faire quelquechose d’un peu plus joli, on peut utiliser une autre carte.
> M1=map("france")
Remarque: il faut juste faire
attention, sur les cartes un peu grandes sur le style de projection
utilisé, qui peut donner des résultats plus ou moins
curieux.... Mais c’est un sujet un peu compliqué, et hors sujet
(pour l’instant, on verra si je trouve le temps un jour).
J’avais déjà abordé (ici) l’utilisation des départements français avec R. voici une autre méthode, basé sur le
fichier dept.rda comprenant la liste des 95 départements français (nom et
code). Il est disponible ici. En reprenant le code donné sur la page là, on obtient
> my.cols <- c(rgb(231/255,240/255,251/255),rgb(180/255,210/255,244/255),
rgb(129/255,180/255,237/255),rgb(0/255,78/255,162/255))
> load("D:\\dept.rda")
> set.seed(1234)
> xx <- data.frame(names=dept[sample(1:95,15),1],n=round(seq(5,300,length=15)))
> xx$grp <- cut(xx$n,breaks=c(0,50,100,250,1000),labels=FALSE)
> map(’france’)
> map(’france’,regions=xx$names,col=my.cols[xx$grp],fill=TRUE,add=TRUE)
- Utilisation de fichiers shp
Par contre on peut toujours bricoler puisqu’on a les coordonnées de toutes les communes....
> B=read.table("http://perso.univ-rennes1.fr/arthur.charpentier/gc_2008b.csv",sep=";", header=TRUE)
> plot(B$XLAMB2,B$YLAMB2,col="red",cex=.2,pch=19)
> plot(B$XLAMB93,B$YLAMB93,col="green",cex=.1,pch=19)
> plot(B$LONGI_GRD,B$LATI_GRD,col="purple",cex=.1,pch=19)
> plot(B$LONGI_DMS,B$LATI_DMS,col="blue",cex=.1,pch=19)
On peut alors directement utiliser un fichier d’élections, par
exemple le pourcentage de votes
exprimés lors de
l’élection présidentielle de 2002 (ce qui n’a aucun sens,
je sais bien,
un ville de 200 électeurs étant représentée
comme une ville de 200 000). Les points rouges correspondent aux communes où le taux de votes exprimés était inférieur à 70%, et en vert,
les communes où il était supérieur à 90%.
L’exercice n’avait a priori aucun intérêt, pourtant on
voit clairement se détacher des régions sur cette carte.On peut aussi regarder les communes qui ont été déclarées victimes d’une catastrophe naturelle, par exemple les inondations. Une étude par mois donne la carte dynamique suivante
(on retrouve l’absence de corrélation et la forte
corrélation spatiale sur ces cartes). Il existe aussi des bases locales, par exemple les réserves naturelles Bretonnes, ici, ou les zones phytogéographiques, là. Bon, promis, après j’arrête, on peut aussi trouver des données sur les routes ici (sur toute l’Europe). Voici quelques exemples de mise en oeuvre, avec tout d’abord des fonds de région et de départements,
> library(maptools)
> SHP="http://perso.univ-rennes1.fr/arthur.charpentier/fr.shp"
> M3=readShapePoly(SHP))
> plot(M3)
et
> SHP="http://perso.univ-rennes1.fr/arthur.charpentier/fra.shp"
> M4=readShapePoly(SHP))
> plot(M4)
Notons qu’on peut importer autre chose que des régions (i.e. des polygones): on peut lire des lignes ou des points. Par exemple
> SHP="http://perso.univ-rennes1.fr/arthur.charpentier/railways.shp"
> M5=readShapeLines(SHP)
> plot(M5)
> map("france")
> lines(M5 ,col="red")
ou encore> SHP="http://perso.univ-rennes1.fr/arthur.charpentier/waterways.shp"
> M6=readShapeLines(SHP)
> plot(M6)
> map("france")
> lines(M6 ,col="blue")

Côté routes, je me contente de faire un dessin sur la Bretagne, le fichier est suffisement lourd comme ça
- Les autres formats de fond de carte
Sinon il est aussi possible d’utiliser des fichiers de type .ai. C’est
un peu plus vicieux, mais on peut les ouvrir via Adobe Image, et
ensuite les sauver... Par exemple, j’ai récupéré
le
fichier des circonscriptions électorales. On peut alors
l’utiliser pour visualiser la couleur politique du député (bon, c’est un peu
facile je sais, mais je n’ai pas d’autres idées). A suivre...Il existe aussi les fichiers dcw (Digital Chart of the World), qui se trouvent un peu partout sur internet, ici par exemple.
Beaucoup de choses se développent en ce moment sur ce sujet, par exemple ici, ou encore ici, ou là (ou même là pour des choses un peu plus techniques). A suivre donc...
PS et promis, la prochaine fois, je parle de lissage spatial...
jeudi 4 juin 2009
Aide mémoire, les couleurs avec R
Par Arthur Charpentier le jeudi 4 juin 2009, 16:30
Ayant toujours du mal à me souvenir du nom des couleurs avec R, je me permets de faire un petit billet. On peut trouver beaucoup d’information ici.
> SetTextContrastColor <- function(color)
{ ifelse( mean(col2rgb(color)) > 127, "black", "white") }
> TextContrastColor <- unlist( lapply(colors(), SetTextContrastColor) )
> colCount <- 25
> rowCount <- 27
> plot( c(1,colCount), c(0,rowCount), type="n", ylab="", xlab="",
+ axes=FALSE, ylim=c(rowCount,0))
> for (j in 0:(rowCount-1)) {
+ base <- j*colCount
+ remaining <- length(colors()) - base
+ RowSize <- ifelse(remaining < colCount, remaining, colCount)
+ rect((1:RowSize)-0.5,j-0.5, (1:RowSize)+0.5,j+0.5,
+ border="black",
+ col=colors()[base + (1:RowSize)])
+ text((1:RowSize), j, paste(base + (1:RowSize)), cex=0.7,
+ col=TextContrastColor[base + (1:RowSize)]) }
Avec ce code assez simple, on peut récupérer le graphique suivant qui présente toutes les couleurs avec leur code
mardi 2 juin 2009
UseR! à Rennes, en juillet prochain
Par Arthur Charpentier le mardi 2 juin 2009, 09:23
Les journées UseR!, de la conférence annuelle des
utilisateurs de R se tiendront à l’Agrocampus à Rennes
(ici) les 8, 9 et 10 juillet prochain.
La date pour la soumission est dépassée depuis
longtemps, mais les inscriptions sont toujours ouvertes, en particulier
pour les tutorials (ici). Le programme pour les trois jours est
également en ligne (ici). Rendez-vous ensuite pour plusieurs billets sur les nouveaux outils incroyables que j’aurais découvert durant ces trois jours !mardi 26 mai 2009
Cartes avec R (partie 3)
Par Arthur Charpentier le mardi 26 mai 2009, 15:36
Je continue un peu les cartes avec R puisqu’un collègue faisant du panel spatial m’a posé la question. Oui, on peut facilement faire des cartes permettant de visualiser la valeur moyenne les résidus par département. La principale difficulté est que R identifie mal les départements, il donc il faut bricoler un peu.. Pour reprendre quelques code évoqués dans un billet précédant
> library(maps);
> CP.CP<-read.table("http://perso.univ-rennes1.fr/arthur.charpentier/code-departement-CP.txt")$V1
> CP.R <-read.table("http://perso.univ-rennes1.fr/arthur.charpentier/code-departement-R.txt")$V1
> nom.dt.r <- function(k) { CP.R[(CP.CP==k)] };
> library(nlme)
> BASE=read.table("http://perso.univ-rennes1.fr/arthur.charpentier/txchom.csv",sep=";",header=TRUE)
> MOY.DPT=gsummary(BASE, groups = BASE$num_dep,FUN=mean)
> Z1=MOY.DPT$txchom; R1=range(Z1)
> Z2=(Z1-R1[1])/(R1[2]-R1[1]+1)*100+1
> couleur = rev(heat.colors(100))
> couleur2= rep(0,150)
> for(j in 1:95){
+ if(sum( MOY.DPT$dpt==j)>0){ couleur2[nom.dt.r(j)]=couleur[Z2[MOY.DPT$num_dep==j]]}}
> map("france", fill = TRUE, col = couleur2)
Le code ci-dessus permet de représenter le taux de chômage moyen (sur l’ensemble des années) dans le département. Mais on peut aussi visualiser, ci-dessous, l’évolution du taux de chômage. Il va de soi que tout cela peut être fairt avec des résidus de panel au lieu de faire le taux de chômage...
jeudi 7 mai 2009
Animation avec R
Par Arthur Charpentier le jeudi 7 mai 2009, 12:07
Par exemple, pour expliquer la notion d’intervalle de confiance, j’ai l’habitude de présenter un graphique que l’on peut aussi présenter sous forme animée. Pour s’en convaincre, il suffit d’éxécuter le code suivant sous R
library(animation)
ani.options(ani.height = 400, ani.width = 600, outdir = getwd(), nmax = 100,
interval = 0.15, title = "Demonstration of Confidence Intervals",
description = "This animation shows the concept of the confidence
interval which depends on the observations: if the samples change,
the interval changes too. At last we can see that the coverage rate
will be approximate to the confidence level.")
ani.start()
par(mar = c(3, 3, 1, 0.5), mgp = c(1.5, 0.5, 0), tcl = -0.3)
conf.int()
ani.stop()
On obtient alors quelque chose qui ressemble à ça
(même si cette fonction génère une page html incluant une animation - et non un fichier gif animé comme ici). Sinon, pour comprendre la construction d’une moyenne mobile, on peut faireoopt = ani.options(ani.height = 400, ani.width = 400, outdir = getwd(), nmax = 50,
title = "Demonstration of Moving Window Auto-Regression",
description = "Compute the AR(1) coefficient for the data in the
window and plot the confidence intervals. Repeat this step as the
window moves.")
ani.start()
par(mar = c(2, 3, 1, 0.5), mgp = c(1.5, 0.5, 0))
mwar.ani(lty.rect = 3, pch = 21, col = "red", bg = "yellow",type=’o’)
ani.stop()
ani.options(oopt)
On obtient alors quelque chose qui ressemble à ça....
Pour plus d’exemples, on peut trouver plein de choses sur le blog de Yihui Xie (ici).Remarque: sinon l’outil idéal pour apprendre à générer des (beaux) graphiques est la même que pour apprendre à programmer: reprendre les exemples qui marchent. Et pour celà, il existe l’incroyable site de Romain François, ici.
Cartes avec R (partie 2)
Par Arthur Charpentier le jeudi 7 mai 2009, 09:56
Un très court complément sur les cartes. Comme je le disais ici, on
peut rajouter ce qu’on veut sur un fond de carte. Par exemple, on peut
tracer la trajectoire d’un ouragan avec des points indiquant
l’intensité.
> FLOYD=read.table("http://perso.univ-rennes1.fr/arthur.charpentier/Floyd.txt")
> couleur = rev(heat.colors(100))
> map("world",xlim=c(-90,-55),ylim=c(20,50),fill=TRUE,col="light green")
> h=2
> for(i in 1:length(FLOYD$x)){
+ points(FLOYD$x[i],FLOYD$y[i],col=couleur[FLOYD$z[i]/3],cex=1,pch=19)
+ text (FLOYD$x[i]+h, FLOYD$y[i] , labels=FLOYD$z[i],cex=0.6) }

Cartes avec R (partie 1)
Par Arthur Charpentier le jeudi 7 mai 2009, 09:37
J’ai déjà parlé un peu de cartographie avec R (ici). En fait, de manière un peu schématique, il convient de noter que les cartes sont composées de deux types d’éléments,
- un fond de carte,
- la description de certains éléments
> library(pixmap)
> bck <- read.pnm("D:\\fond.pnm")
> plot(bck)
par définition, le coin en bas à gauche de l’image est le point (0,0). L’a résolution de l’image étant 1600x902, on obtient les coordonnées du coin en haut à droite. Pour s’en convaincre il suffit de rajouter
> abline(v=0,lwd=5)
> abline(v=1600,lwd=5)
> abline(h=0,lwd=5)
> abline(h=902,lwd=5)
Mais sinon, on peut rajouter à peu près n’importe quoi, comme un histogramme, ou une densité lissée
>plot(bck)
>X=rnorm(250)
>xdens=density(X)
>lines((xdens$x+4)*200,xdens$y*1200+200,col="red",lwd=5)

Mais côté carte, il y a souvent beaucoup plus d’information, comme la localisation des départements (comme ici) ou des pays. Par exemple, on peut récupérer sur internet des fichiers comme celui ci
>library(maptools)
>load(url("http://spatial.nhh.no/R/etc/TM_WORLD_BORDERS_SIMPL-0.2.RData"))
où les pays sont localisés par leur nom. Avec le code ci-dessous, je colorie la France et le Brésil avec des couleurs prise de manière aléatoire,
> country2 = c("France","Brazil")
> country.all = wrld_simpl$NAME
> n.all = length(country.all)
> col.map = numeric(n.all)
> for (i in 1:length(country2)){col.map[grep(country2[i],country.all)] = runif(1)}
> c2=col.map!=0
> col.map2=col.map
> col.map2[!c2]=rgb(.95,.96,.97)
> col.map2[c2]= rgb(patramp(col.map[c2])/255)
> plot(wrld_simpl,col=col.map2,axes=T)

Je pense que je continuerais un de ces jours ce billet, si j’arrive à mettre la main sur des fonds de carte détaillés pour la France ou l’Europe (si quelqu’un a ces fichiers sous la main, je suis intéressé).
Scatterplot et histogrammes avec R
Par Arthur Charpentier le jeudi 7 mai 2009, 08:42
Chose promise, chose due, un exemple de graphique avec R,
>
library(evd); data(lossalae)
> x <- lossalae$Loss; y <- lossalae$ALAE
> xhist <- hist(log(x), plot=FALSE)
; yhist <- hist(log(y), plot=FALSE)
> top <- max(c(xhist$counts, yhist$counts))
> nf <- layout(matrix(c(2,0,1,3),2,2,byrow=TRUE), c(3,1), c(1,3), TRUE)
> par(mar=c(3,3,1,1))
; plot(x, y, xlab="", ylab="",log="xy",col="red")
> par(mar=c(0,3,1,1));
barplot(xhist$counts, axes=FALSE, ylim=c(0, top), space=0,col="light green")
> par(mar=c(3,0,1,1));
barplot(yhist$counts, axes=FALSE, xlim=c(0, top), space=0, horiz=TRUE,col="light blue")

mercredi 6 mai 2009
Effets individuels avec R
Par Arthur Charpentier le mercredi 6 mai 2009, 13:54
Toujours pour répondre à une question
d’élève, je vais parler un peu des modèles sur
variables qualitatives (lorsque la variable à expliquer est
binomiale). Par exemple, pour poursuivre un peu des exemples
traités dans des billets récents (ici ou là), je
vais définir une variable décrivant un "prestige élevé" pour une profession.
> prestige<-read.table("http://perso.univ-rennes1.fr/arthur.charpentier/Prestige.txt",header=TRUE)
> seuil= 50; prestige$PE =as.factor (prestige$prestige > seuil)
Les modèles classiques en économétrie des variables
qualitatives (probit ou logit) sont des cas particuliers des
modèles linéaires généralisés, avec
comme loi une loi binomiale. La fonction de lien canonique est la
fonction de répartition de la loi logistique (ce qui donne un
modèle logit), mais on peut prendre une fonction de
répartition de la loi normale centrée réduite (ce
qui donone un modèle probit)
> REG=glm(Y~X1+X2,data=base,family=binomial(link = "logit"))
> REG=glm(Y~X1+X2,data=base,family=binomial(link = "probit"))
Formellement, on suppose que
où F est une fonction
de répartition, soit d’une loi normale dans le cas probit, soit
d’une loi logistique dans le cas logit. L’utilisation de R peut
s’avérer compliqué au premier abord car ces
méthodes sont vues comme de simples
cas particuliers de modèles beaucoup plus généraux,
où la loi de Y appartient à la famille exponentielle
(comme la loi normale, la loi binomiale ou la loi de Poisson, pour les
plus connues). Le principal avantage est que la syntaxe et l’analyse
des sorties est très proche de la régression classique
(la plupart des outils de la fonction lm() se retrouvent sur la fonction glm())
Remarque: Pour construire un modèle où Y est binomiale,
on change de famille de modèle (on passe de lm à glm),
mais pour le cas où une des variables explicatives X est
binomiale (ou prenant plus de modalités, comme des classes
d’âge, ou des classes de revenu), il suffit de la définir "proprement",
c’est à dire en tant que facteur. Je renvoie à la
discussion sur les modèles GAM (ici) où la date de
survenance est prise en tant que facteur dans les modèles
GLM (via la commande as.factor()) mais en tant que valeur numérique dans les modèles GAM.
Voilà pour l’introduction. Mais la question portait plus précisément sur l’étude des effets individuels, oc’est à dire que l’on s’intéresse à
de manière générale dans un modèle
linéaire généralisé (par exemple probit).
La moyenne des effets marginaux s’estime alors en considérant
Sous R, on peut les récupérer facilement. Par exemple
pour un modèle probit, la fonction lien est la fonction de
réparition d’une loi normale centrée réduite, i.e.
dnorm(), aussi, on utilise
> REG=glm(PE~income+education,data=prestige,family=binomial(link = "logit"))
> mean(dnorm(predict(REG,type="link"))) * coef(REG)
(Intercept) income education
-1.247750e+00 4.685419e-05 8.488106e-02
On peut aussi faire sommairement une étude graphique,
> require(vcd)
> spine(PE~income, data = prestige, breaks = quantile(prestige$income)
Pour information, ce type de graphique est parfois appelé spinogram dans la littérature.
Si on veut étudier plus d’effets, John Fox a développé la library(effects) qui est dédiée à ce problème.
Sinon, pour aller plus loin, je renvoie à plusieurs livres, dont Micro-Econometrics for Policy, Program, and Treatment Effects de Myoung-Jae Lee, ou encore Modern Applied Statistics with S.
« billets précédents - page 1 de 3


