Informes con R en HTML. Comienzo con R2HTML (I)

En las III jornadas de R tuve el placer de asistir al taller de Gregorio Serrano sobre informes con R. Me abrió los ojos. Siempre he pensado que R no es una herramienta que sirva para hacer informes [modo consultor = ON] R no servía para realizar reporting [modo consultor = OFF]. Pero R tiene un poderoso motor gráfico y dispone del paquete R2HTML para poder realizar tablas en HTML y si trabajamos con libros CSS de estilos podemos obtener resultados muy atractivos. Así que la otra tarde me puse manos a la obra y creo que puede salir una trilogía interesante. Bueno, depende del interés que despierte esta entrada del blog haré más entregas, pero de momento tengo en mente llegar a 3.

Seguimos con el sistema habitual. Simulo unos datos de ejemplo que podéis copiar y pegar en vuestra consola de R:

clientes=20000

saldo_vista=abs(rnorm(clientes,0,1)*10000+5000)

saldo_ppi=(runif(clientes,0.1,0.6)*rpois(clientes,2))*60000

saldo_fondos=abs(rnorm(clientes,0,1)*100000+3000)*(runif(clientes)>=0.6)

edad=rpois(clientes,60)

datos_ini<-data.frame(cbind(saldo_vista,saldo_ppi,saldo_fondos,edad))

datos_inisaldo_ppi=(edad<65)*datos_inisaldo_ppi

#Creamos la variable objetivo a partir de un potencial

datos_inipotencial= runif(clientes,0,1)

datos_inipotencial= datos_inipotencial +

log(edad)/2 +

runif(1,0,0.03)*(saldo_vista>20000)+

runif(1,0,0.09)*(saldo_fondos>30000)+

runif(1,0,0.07)*(saldo_ppi>10000)

datos_inipvi=(datos_inipotencial>=quantile(datos_inipotencial,

0.85))*1

#Eliminamos la columna que genera nuestra variable dependiente

datos_ini = subset(datos_ini, select = -c(potencial))

Datos simulados de una entidad bancaria donde tenemos edad, saldos en distintos productos de pasivo e identificamos a aquellos clientes que tienen contratada una pensión vitalicia. Nos solicitan realizar un informe con los datos de contratación por edad y por pasivo. Cuando realizamos informes es muy habitual tramificar variables continuas. Para crear los tramos de edad y de pasivo vamos a emplear la función recode de la librería memisc :

#Con memisc recodifico los factores

library(memisc)

datos_inirango_edad <- recode(datos_iniedad,

"1 Menos de 45 años" <- range(min,45),

"2 Entre 46 y 55 años" <- 46:55,

"3 Entre 56 y 65 años" <- 56:65,

"4 Más de 65 años" <- range(66,max))
datos_inirango_vista <- recode(datos_inisaldo_vista,

"1 Menos de 5.000 €" <- range(min,5000),

"2 Entre 5.000 y 15.000 €" <- range(5000,15000),

"3 Entre 15.000 y 25.000 €" <- range(15000,25000),

"4 Más de 25.000 €" <- range(25000,max))

Los intervalos creados son cerrados por la derecha. En el blog se ha tratado en otra ocasión la recodificación de los factores y no se trabajó con memisc. Bajo mi punto de vista recode+memisc es la mejor opción. Ya tenemos nuestras variables recodificadas y ahora tenemos que sumarizar y graficar el número de clientes frente a las tasas de contratación. A la hora de realizar informes los formatos son muy importantes. Por defecto en R estamos acostumbrados a trabajar con formatos americanos, comas para separar decimales y puntos para separar miles. Esto a mi no me gusta, prefiero el formato americano. Por ello lo primero que hacemos es crearnos unas funciones que nos den formatos europeos y formatos en porcentaje:

#Función para dar formatos a los datos

#Separador de miles europeo

sep.miles <- function(x){

format(x,big.mark=".")}

#Creación de formatos de decimales

fmt.porcen <- function(x){

paste(format(round(x,2),decimal.mark = ","),'%')}

Estas funciones nos servirán para dar formatos a los números de nuestras tablas. ¿Cómo vamos a hacer las tablas? Con ddply por supuesto. Ahora las libreríasplyr y ggplot2 son las que nos ayudarán a crear el informe:

library(plyr)

library(ggplot2)
#Realizamos la tabla de sumarización

resum1 <- ddply(datos_ini,"rango_edad",summarise,

clientes=length(rango_edad),

contrata=sum(pvi))

resum1tasa=fmt.porcen(resum1contrata*100/resum1clientes)

resum1clientes=sep.miles(resum1clientes)

resum1contrata=sep.miles(resum1$contrata)
#Pintamos un diagrama de barras

png(file="C:\\temp\\informes\\resum1.png",width=600, height=450)

a <- ggplot(datos_ini, aes(rango_edad,fill=factor(pvi)))

a + geom_bar()

dev.off()
resum2 <- ddply(datos_ini,"rango_vista",summarise,

clientes=length(rango_edad),

contrata=sum(pvi))

resum2tasa=fmt.porcen(resum2contrata*100/resum2clientes)

resum2clientes=sep.miles(resum2clientes)

resum2contrata=sep.miles(resum2$contrata)
```r
png(file="C:\\temp\\informes\\resum2.png",width=600, height=450)

a <- ggplot(datos_ini, aes(rango_vista,fill=factor(pvi)))

a + geom_bar()

dev.off()
```

Mucho código. Los objetos _resumx_ son las tablas que hemos de representar, son sumarizaciones del total de clientes y de los clientes que contratan el producto. Calculamos una tasa y aplicamos los correspondientes formatos. Al formatear los datos los números pasan a ser texto, en ese sentido R no es como otras herramientas, no provoca muchos problemas. El último paso es realizar el informe. Todo quedará almacenado en nuestro disco, en este caso trabajamos con Windows y guardamos el informe en C:\Temp\informes\:

```r
library(R2HTML)

salida  = HTMLInitFile( "C:\\temp\\informes",filename="salida",

CSSFile="C:\\TEMP\\informes\\table_design.css")

HTML("<div align=center>")

HTML("<p align=center>Estudio por edad</p>" ,file=salida)

HTML(resum1, file=salida)

HTML("<p align=center>Clientes por rango de edad</p>")

HTML("<img src='c:\\temp\\informes\\resum1.png'></img>")

HTML("<p align=center>Estudio por saldo a la vista</p>" ,file=salida)

HTML(resum2, file=salida)

HTML("<p align=center>Clientes por saldo a la vista</p>")

HTML("<img src='c:\\temp\\informes\\resum2.png'></img>")

HTML("</div>")

HTMLEndFile()
```
 

El objeto _salida_ es una página estática HTML que llama a una hoja de estilos, con esto podemos realizar tablas más bonitas y espectaculares. Esta página se crea con la función **HTMLInitFile** , con la función HTML ya introducimos código HTML a _salida_ hasta que encontramos **HTMLEndFile.** Yo no soy ningún experto en HTML, creo que sería mejor decir que no tengo ni idea pero con Google y R2HTML vamos a crear informes [tan bonitos como este](/images/2011/11/informes/salida.html).