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ías plyr 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)
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\:
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.
Hola Raúl. ¿qué tal?
Muy interesante, a ver si lo pruebo esta tarde o mañana. ¿Puedes poner cómo quedaría la tabla? y ya de paso, ¿qué css has utilizado?
Un saludo
Hola JL, este mensaje está dedicado precisamente a ti. Lo tenía como borrador debido a los problemas con el código HTML en wordpress. He puesto el resultado en un link para que puedas verlo. Pondré el código completo porque los problemas con el HTML persisten.
jeje. Muchas gracias.Ahora a darle caña a esto del R2HTML y también a Sweave que para eso estuvimos en el estupendo taller de Gregorio.
Por alusiones, gracias a los dos, tengo pendiente colgarlo en mi blog. Creo que estas guías soy muy útiles, así que ánimo para las partes que faltan.
Un saludo
Pingback: Automatización de informes con R, Sweave y LaTeX » G. R. Serrano
Ya instale la versión de prueba y fue de gran utilidad, mi duda es que si ya realice un archivo y gracias a Begraphic le inserte velocímetros, estos podrán ser abiertos y modificar su valor en una computadora que no tenga el programa???
Favor de responder mi duda rápido, me urge…
Saludosnn1