A few years ago, I did publish a post to visualize and empirical claims frequency in a portfolio. I wanted to update the code.
Here is a code to get a dataset,
sinistre <- read.table("http://freakonometrics.free.fr/sinistreACT2040.txt",header=TRUE,sep=";") sinistres=sinistre[sinistre$garantie=="1RC",] contrat <- read.table("http://freakonometrics.free.fr/contractACT2040.txt",header=TRUE,sep=";") T=table(sinistres$nocontrat) T1=as.numeric(names(T)) T2=as.numeric(T) nombre1 = data.frame(nocontrat=T1,nbre=T2) I = contrat$nocontrat%in%T1 T1= contrat$nocontrat[I==FALSE] nombre2 = data.frame(nocontrat=T1,nbre=0) nombre=rbind(nombre1,nombre2) basenb = merge(contrat,nombre) head(basenb) basesin=merge(sinistres,contrat) basesin=basesin[basesin$cout>0,]
and here to get the graphs (thanks Andre for your help to pick the colors, and the style of the graph)
graph_freq=function(var="ageconducteur", levels=c(17,24,34,44,64,110), continuous=TRUE,type=1){ if(continuous==TRUE){X=cut(basenb[,var],levels)} if(continuous==FALSE){X=as.factor(basenb[,var])} E=basenb$exposition Y=basenb$nbre FREQ=levels(X) moyenne=variance=n=rep(NA,length(FREQ)) for(k in 1:length(FREQ)){ moyenne[k] =weighted.mean(Y[X==FREQ[k]]/E[X==FREQ[k]], E[X==FREQ[k]]) variance[k]=weighted.mean((Y[X==FREQ[k]]/E[X==FREQ[k]]- moyenne[k])^2,E[X==FREQ[k]]) n[k]=sum(E[X==FREQ[k]]) } w=barplot(n,names.arg=FREQ,col="yellow",axes=FALSE, xlim=c(0,1.2*length(FREQ)+.5),ylim=c(0,2.5*max(n))) mid=w[,1] axis(4,) par(new=TRUE) IC1=moyenne+1.96/sqrt(n)*sqrt(variance) IC2=moyenne-1.96/sqrt(n)*sqrt(variance) moyenneglobale=sum(Y)/sum(E) if(type==1){ plot(mid,moyenne,ylim=c(min(c(IC1,IC2)- diff(range(c(IC1,IC2)))/4),max(c(IC1,IC2))),type="l", col="#FF00FF",axes=FALSE,xlab="",ylab="", xlim=c(0,1.2*length(FREQ)+.5)) for(i in (-10):20) segments(min(mid)-.8,i/40,max(mid)+.8,i/40,lty=2,col="grey") segments(mid,IC1,mid,IC2,col="darkorchid4") segments(mid-.1,IC1,mid+.1,IC1,col="darkorchid4") segments(mid-.1,IC2,mid+.1,IC2,col="darkorchid4") points(mid,moyenne,pch=15,col="#FF00FF") axis(2,at=seq(0,.3,by=.05)) abline(h=moyenneglobale,lty=2,col="darkorchid3")} if(type==2){ cic=c(100*(IC1/moyenneglobale),100*(IC2/moyenneglobale)) YL=c(min(cic)-diff(range(cic))/4,max(cic)) plot(mid,(moyenne/moyenneglobale)*100,ylim=YL, type="l",col="#FF00FF",axes=FALSE,xlab="",ylab="", xlim=c(0,1.2*length(FREQ)+.5)) for(i in (-10):20) segments(min(mid)-.8,i*25,max(mid)+.8,i*25,lty=2,col="grey") segments(mid,100*(IC1/moyenneglobale),mid, (IC2/moyenneglobale)*100,col="darkorchid4") segments(mid-.1,100*(IC1/moyenneglobale),mid+.1, (IC1/moyenneglobale)*100,col="darkorchid4") segments(mid-.1,100*(IC2/moyenneglobale),mid+.1, (IC2/moyenneglobale)*100,col="darkorchid4") points(mid,100*(moyenne/moyenneglobale),pch=15,col="#FF00FF") axis(2,at=seq(0,300,by=50)) abline(h=100,lty=2,col="darkorchid3")} mtext("Exposure", 4, line=-2, cex=.8) if(type==1){mtext("Annualized Frequency", 2, line=+2, cex=.8)} if(type==2){mtext("Annualized Frequency (multiplier, %)", 2, line=+2, cex=.8)} }
For instance, if we consider the age, with the annualized frequency (see on the left axis)
graph_freq(type=1)
or the multiplier (on a 100 basis)
graph_freq(type=2)
OpenEdition suggests that you cite this post as follows:
Arthur Charpentier (July 28, 2015). Visualising Claims Frequency. Freakonometrics. Retrieved October 3, 2024 from https://doi.org/10.58079/ov05
Excelent ¡¡