Nueva edición del Programa en Big Data y Data Science de la UNED

Ya está abierta la convocatoria para el Programa Modular en Big Data y Data Science aplicados a la Economía y a la Administración y Dirección de Empresas. Es un programa que se imparte 100% en línea y tiene el mejor balance entre la visión teórica y la visión práctica en ciencia de datos. Si escogéis el módulo de seguros allí nos veremos.

En el siguiente enlace podréis encontrar más información:

www.masterbigdataonline.com

Calcular porcentajes por grupos con dplyr

A la hora de sumarizar datos con dplyr podemos calcular porcentajes dentro de grupos o subgrupos con transmute. La sintaxis es sencilla pero tiene la peculiaridad que sólo obtendremos como salida lo que indiquemos en transmute. Mejor lo entendéis en un ejemplo:

Conjunto de datos aleatorio de ejemplo:

library(dplyr)
observaciones = 100
grupo_1 = rpois(observaciones, 0.5)
grupo_2 = rpois(observaciones, 1)

df = cbind.data.frame(grupo_1, grupo_2) %>% mutate(id_cliente=n()) 

Sumarizamos por grupos:

df %>% group_by(grupo_1, grupo_2) %>% summarise(clientes = n()) 

Contamos clientes y calculamos el porcentaje sobre el total:

df %>% group_by(grupo_1, grupo_2) %>% 
  summarise(clientes = n(),
            pct_total = n()/nrow(df)) 

Suelo usar nrow se aceptan sugencias. Calculamos el porcentaje para el subgrupo del grupo_1, primer ejemplo de uso de transmute:

df %>% group_by(grupo_1, grupo_2) %>% 
  summarise(clientes = n()) %>% 
  transmute(grupo_2, pct_grupo = clientes/sum(clientes))

Vemos que clientes ha desaparecido, sólo obtenemos grupo_1, grupo_2 y pct_grupo. Si queremos el porcentaje sobre el total:

df %>% group_by(grupo_1, grupo_2) %>% 
  summarise(clientes = n()) %>% 
  transmute(grupo_2, pct_grupo = clientes/sum(clientes),
            pct_total = clientes/nrow(df)) 

Aquí lo tengo todo recogido, para cuando no lo recuerde. Saludos.

Tablas elegantes en #rstats y formattable

Las salidas de la consola de R para muchos de nosotros son más que suficientes. Además en mi caso particular prefiero poner las cosas más elegantes en otras herramientas como Excel, Qlik Sense o Tableau. Pero me he dado cuenta que hay una librería que sí uso cuando directamente copio y pego salidas de R en correos, presentaciones o si empleo markdown (rara vez); esta librería es formattable, es posible que haya mejores librerías pero esta es la que yo uso desde hace un par de años.

Vamos a ilustrar algunos ejemplos de uso con un código ya conocido, extraemos la información de casos de COVID de Datadista y vamos a poner una tabla con la evolución de casos, UCI, altas y fallecimientos para el mes de octubre de 2020:

library(tidyverse)
library(formattable)
library(lubridate)

data <- read.csv("https://raw.githubusercontent.com/datadista/datasets/master/COVID%2019/nacional_covid19.csv",
         check.names=FALSE)

colnames(data)[1] = 'fecha'

data$Fecha <- as.Date(data$fecha, "%Y-%m-%d")
data$`Casos nuevos` <- c( NA, diff(data$casos_pcr))
data$`Altas nuevas`<- c( NA, diff(data$Altas))
data$`Fallecimientos nuevos` <- c( NA, diff(data$fallecimientos))
data$`UCI nuevas` <- c(NA, diff(data$ingresos_uci))

data_filtered <- data %>% filter(month(Fecha)==10 & `Casos nuevos`>0) %>% 
  select(Fecha, `Casos nuevos`, `Altas nuevas`,  `Fallecimientos nuevos`, `UCI nuevas`)

formattable(data_filtered)

Y si queremos el HTML:

format_table(data_filtered)
Fecha Casos nuevos Altas nuevas Fallecimientos nuevos UCI nuevas
2020-10-01 9419 NA 182 88
2020-10-02 11325 NA 113 59
2020-10-05 23480 NA 139 83
2020-10-06 11998 NA 261 71
2020-10-07 10491 NA 76 49
2020-10-08 12423 NA 126 102
2020-10-09 12788 NA 241 90
2020-10-12 27856 NA 195 85
2020-10-13 7118 NA 80 38
2020-10-14 11970 NA 209 80
2020-10-15 13318 NA 140 73
2020-10-16 15186 NA 222 86
2020-10-19 37889 NA 217 147

Copiando y pegando podemos incrustar en html. Seguir leyendo Tablas elegantes en #rstats y formattable

Evita problemas con Excel desde R. De tocar el dato a un proceso

En estos días hemos vivido una situación con Excel y los datos de COVID de UK peculiar. Hemos aparecido todos en las redes sociales para reírnos de Excel y de los que usan Excel. De nuevo partidarios de Matlab, R, Python,… ¡a la gresca! Mi opinión la podéis leer en Twitter y creo que sobre este tema puedo opinar. En mi vida profesional me he especializado en cambiar equipos de negocio, por ese motivo tanto ir y venir de compañía. Uno de esos cambios consiste en transformar super usuarios de Excel a usuarios de herramientas más apropiadas para la gestión de la información.

Mi carrera en el sector de la gestión de la información comenzó introduciendo SAS allí donde Business Objects  y Access ya eran insuficientes. Continué con SAS durante muchos años, siempre con guiños al software libre porque R me permitía llegar allá donde SAS n€c€sitaba otro$ módulo$. En los últimos años estoy alternando el uso de Python con R. Sin embargo, mis ponencias y mis presentaciones de servicios están incluyendo el siguiente gráfico:

Soy partidario de SAS, es la mejor herramienta, de SPSS no opino porque no he trabajado lo suficiente (¿sigue existiendo Clementine?) pero no son gratis, una PYME no puede permitirse un alto gasto en software.  Python con sus IDE y Pandas son muy duros para personas acostumbradas a las fórmulas de Excel. Ahí aparece R y sobre todo el universo tidyverse y RStudio, es la clave del cambio y lo que debe hacer que todos esos super usuarios de Excel miren hacía R. Por eso se me ocurrió ese dibujo y ahí estoy.

No usemos Excel como motor de BBDD, no toquemos manualmente los datos, empecemos a entender que la gestión de datos no es un buscar objetivo, la gestión de datos es un proceso que, además, puede ser usado por otro y se puede reproducir no es estático. Se trata de evitar fórmulas que solo entiende el autor, programas de Visual Basic que no entiende ni  el autor y yo sugiero crear un flujo de este modo: chimpún %>% chimpún %>% chimpún. No es difícil y no se trata de prescindir de Excel, porque a Excel ya irán tus datos preparados, nunca podrás tocar un dato previo ya que pasamos del dato en bruto guardado en una BBDD o repositorio al dato final que si usarás en Excel.

Si soy yo el que te ayuda ese proceso prefiero usar R:

  1. Es gratuito, te instalas R y RStudio y los paquetes que necesites.
  2. Es sencillo, unas instrucciones te permiten hacer con dplyr el 90% del trabajo que haces en Excel con cientos de fórmulas.

Un ejemplo práctico, pasando datos de R a Excel

Por último me gustaría ilustrar este trabajo con un ejemplo para poder evaluar la complejidad y como podrías plantear este trabajo, necesitamos leer diariamente los datos de COVID que publica Datadista para disponer de un Excel con esos datos y pintar nuestro seguimiento, también sería interesante obtener un pequeño resumen que nos permita localizar datos atípicos en la serie que se publica. Vamos a emplear la librería openxlsx para generar un Excel con este propósito. El primer paso será leer los datos de Datadista (incluyen los programas para facilitar la cosa) y crear nuestros objetos en R:

library(dplyr)
library(ggplot2)
library(gridExtra)
library(grid)

data <-
  read.csv("https://raw.githubusercontent.com/datadista/datasets/master/COVID%2019/nacional_covid19.csv",
           check.names=FALSE)

colnames(data)[1] = 'fecha'

data$fecha <- as.Date(data$fecha, "%Y-%m-%d")
data$Casos.nuevos <- c( NA, diff(data$casos_pcr))
data$Altas.nuevas <- c( NA, diff(data$Altas))
data$Fallecimientos.nuevos <- c( NA, diff(data$fallecimientos))
data$UCI.nuevos <- c(NA, diff(data$ingresos_uci))

Un ejemplo claro, por algún motivo en Windows el nombre de la variable fecha contiene algún carácter extraño, modifico el nombre con colnames, esta acción queda reflejada en un proceso. Si se producen cambios en los campos de la tabla quedan recogidos en un código que puede ser reproducible por cualquier persona de la organización, podemos (es conveniente) llevar un control de versiones del código por si se produjeran cambios. Las fórmulas empleadas no distan de las que usamos en Excel y si se desconoce que fórmula usar R tiene una comunidad de usuarios por detrás que estarán dispuestos a ayudar, eso no pasa con SAS (por ejemplo).

Continuamos y deseamos realizar un gráfico con los casos nuevos por día para buscar posibles anomalías:

p1 <- ggplot(data,aes(x=fecha,y=Casos.nuevos),na.rm = TRUE) +
  geom_line() +
  geom_smooth() + ggtitle("Casos nuevos") + theme_minimal()

p2 <- ggplot(data,aes(x=fecha,y=Fallecimientos.nuevos),na.rm = TRUE) +
  geom_line() + geom_smooth() + ggtitle("Fallecimientos nuevos") + theme_minimal()

p3 <- ggplot(data,aes(x=fecha,y=UCI.nuevos),na.rm = TRUE) + geom_line() +
  geom_smooth() + ggtitle("UCI nuevos") + theme_minimal()

p <- grid.arrange(p1, p2, p3, ncol=2)

Este paso puede ser más duro, hacer gráficos en R ya no es seleccionar datos y tipo de gráfico pero en dos líneas hemos hecho un gráfico, es el mismo para las tres variables que deseamos analizar y deseamos unir todos los gráficos de ggplot en uno lo hacemos con una función que se llama grid.arrange. Esto lo haces una vez, no lo repites siempre y si lo intentas hacer con Visual Basic lo conseguirás pero otro compañero no podrá abrir las macros, a otro no le funciona,… -¿esto quién lo hizo? -¡pero si ya está jubilado!

Ahora lo que hacemos es poner estos datos en un Excel para hacer nuestros resúmenes, nuestro cuadro de mando con tablas dinámicas,… lo que sea para lo que Excel si es una gran herramienta (si, he puesto cuadros de mando). Este código también es más complejo pero siempre es el mismo:

library(openxlsx)

excel <- createWorkbook()
addWorksheet(excel, sheetName = "DatosCOVID")

print(p)
writeDataTable(excel,sheet = "DatosCOVID", x=data)
insertPlot(excel, sheet = "DatosCOVID", startRow = 2, startCol = length(data) + 2, )

saveWorkbook(excel, "C:/temp/datos_covid.xlsx")
remove(excel)

Creamos un “entorno excel” con createWorkbook al que podemos añadir hojas con addWoksheet y en esas hojas añadimos elementos, una tabla con writeDataTable y un gráfico, que necesitamos imprimir previamente, con insertPlot. Vemos que los datos que publica el Ministerio sobre el Covid tienen anomalías, parece ser que un día concreto resucitaron 1.900 personas, podríamos ir al código y eliminarlo.

Para un usuario de Excel pueden parecer complicadas las fórmulas sin embargo podemos evitar problemas referenciando celdas, modificando celdas, borrando elementos,… Y no es más complejo que una fórmula de Excel.

Manejo de datos básico con Python datatable

Nueva entrada dedicada al data management con Python, esta vez con datatable. No voy a justificar el uso de datatable antes que pandas, en un vistazo rápido por la web encontráis numerosas ocasiones en las que datatable es más eficiente que pandas en el manejo de datos con Python. En cuanto a la complejidad en el uso de uno u otro mi opinión no es objetiva porque  me cuesta mucho trabajar con Pandas.

Asumo que habéis instalado datatable en vuestro entorno de Python (siempre por encima de la versión 3.5) y una vez está instalado os propongo obtener un conjunto de datos del repositorio de analisisydecision. Por supuesto la carga de este csv de ejemplo la realizamos con datatable y la función fread:

import datatable as dt
path = 'https://raw.githubusercontent.com/analisisydecision/intro_python_data_science/master/'
dt_df = dt.fread(path + 'index.csv')
dt_df.head()

dt_df.shape

Hemos creado un data frame con datatable, podremos pasarlo a lista o a data frame en pandas con .to_pandas(). En la línea de siempre las tareas que vamos a revisar con datatable en Python son:

  • Seleccionar columnas
  • Eliminar columnas
  • Seleccionar registros
  • Crear nuevas variables
  • Sumarizar datos
  • Renombrar variables
  • Ordenar datos

Seguir leyendo Manejo de datos básico con Python datatable

Transformaciones de variables cuantitativas en modelos binomiales

Para mejorar la capacidad predictiva de nuestros modelos binomiales es recomendable transformar las variables independientes. Existen técnicas que lo hacen de modo automático pero hoy os quería mostrar en un video un método “casero” para agrupar una variable cuantitativa con respecto a una variable respuesta, todo muy orientado a que la transformación tenga un sentido de negocio.

El código empleado para hacer el video es el siguiente:

from urllib import urlretrieve
link = 'https://raw.githubusercontent.com/yhat/demo-churn-pred/master/model/churn.csv'
urlretrieve(link, "churn.txt")

import pandas as pd
import numpy as np
df = pd.read_csv("churn.txt")
df.head(5)

import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt

pd.crosstab(df['Churn?'], columns='count').plot(kind='bar')
plt.show();

df['churn'] = np.where(df['Churn?'] == 'True.', 1, 0)

pd.crosstab(df['churn'], columns='count')

df['Day Mins'].isnull().sum()
df['Day Mins'].describe()
plt.hist(df['Day Mins'], bins=20); plt.show();

df['minutos'] = np.where(df['Day Mins'] >= 270, 270, (df['Day Mins']//10)*10)
df['minutos'] = np.where(df['minutos'] <= 70, 70, df['minutos'])

pd.crosstab(df['minutos'], columns='count')
plt.hist(df['minutos']); plt.show();

churn =  pd.DataFrame((df['churn']).groupby(df['minutos']).mean())
clientes = pd.DataFrame((df['churn']).groupby(df['minutos']).count())


fig = plt.figure()
ax = clientes['churn'].plot(kind='bar', grid=True)
ax2 = ax.twinx()
ax2.plot(churn['churn'].values, linestyle='-', linewidth=2.0,color='red')
plt.show();

Variables categóricas en cajas, treemap con R

La representación de variables categóricas en cajas es uno de los gráficos que más utilizo, empezaron a gustarme debido al uso de Qlik Sense y sus gráficos de cajas, me permitían comparar variables categóricas en un periodo frente a otro. En R podemos usar la librería treemap para realizar estos gráficos y comparar variables categóricas. En este caso interesa comparar una variable dentro de dos grupos.

Para ilustrar el ejemplo nos suministran un conjunto de datos con información de un seguro de responsabilidad civil de motocicletas de una compañía sueca. Este conjunto de datos está en la librería CASdatasets de R:

library(tidyverse)
library(CASdatasets)

data(swmotorcycle)

Nos piden evaluar la variable RiskClass, esta variable es categórica y viene definida como la relación de la potencia de la moto en KW x 100 entre el peso de la moto + 75 kg (peso medio del piloto). Esta relación se divide en 7 clases que son necesarias de evaluar.

Vamos a crear una variable binomial Tiene_siniestro si el importe del siniestro es mayor que 0 tomará “Tiene siniestro”, si el importe es <=0 tomará “No tiene siniestro”. Y mediante la librería de R treemap compararemos la exposición al riesgo de cada grupo Tiene_siniestro x RiskClass. Para llevar a cabo esta comparativa usaremos un gráfico de cajas Seguir leyendo Variables categóricas en cajas, treemap con R

Mapa España por Comunidades Autónomas con Google Studio

Continúo evaluando métodos para crear mapas con software que no sea de pago e intentando que la dificultad sea mínima. En este caso quería mostraros y poner a vuestra disposición un mapa de España por Comunidades Autónomas, además os dejo acceso libre a los datos que usa el mapa para que vosotros mismos podáis realizar el trabajo. Voy a pasaros 2 enlaces uno con los datos donde tenemos datos de pruebas PCR por 100.000 habitantes a nivel de Comunidad Autónoma (por representar algo) es ahí donde incluís los datos que deseáis representar gráficamente. Y el otro enlace es el dashboard simple hecho con Data Studio que véis al inicio de la entrada que contiene un mapa con el formato que en este momento necesito. Este trabajo es meramente experimental porque pongo a disposición de todos tanto mapa como Hoja de Google, veremos lo que tarda en dejar de funcionar.

El mapa se ha llevado a cabo según las instrucciones de este video:

Si necesitáis realizar el mismo proceso para México ahí lo tenéis muy bien explicado, en mi caso voy a pasar los link para generar el mapa y vosotros mismos cambiando los datos de la google sheet deberíais poder materializar el gráfico. Para no dejar abiertos al público vuestros mapas os pediría copiar o duplicar tanto la Google Sheet Seguir leyendo Mapa España por Comunidades Autónomas con Google Studio

Leer fichero de texto de ancho fijo con Python Pandas

Es muy habitual trabajar con archivos csv pero en ocasiones disponemos de ficheros de texto con determinado formato o con ancho fijo para las columnas. Hace tiempo ya escribí sobre la lectura de archivos csv con Python y Pandas pero en esta ocasión vamos a leer archivos que no tienen un separador. Evidentemente tienen que darnos el formato del archivo, en este caso, para ilustrar el ejemplo, vamos a pasar un código en R a un código en Python. Necesitamos leer unos datos usados en el libro Non-Life Insurance Pricing with GLM, con R teníamos el siguiente programa:

varib <- c(edad = 2L, sexo = 1L, zona = 1L, clase_moto = 1L, antveh = 2L,
           bonus = 1L, exposicion = 8L, nsin = 4L, impsin = 8L)

varib.classes <- c("integer", rep("factor", 3), "integer",
                   "factor", "numeric", rep("integer", 2))
con <- url("https://staff.math.su.se/esbj/GLMbook/mccase.txt")
moto <- read.fwf(con, widths = varib, header = FALSE,
                 col.names = names(varib),
                 colClasses = varib.classes,
                 na.strings = NULL, comment.char = "")

Necesitamos crear ese data frame moto con Python. Evidentemente una lectura a las bravas no tiene sentido:

import pandas as pd
data1 = pd.read_fwf("http://staff.math.su.se/esbj/GLMbook/mccase.txt")
data1.head(10)

El programa R ya nos define el formato del fichero y es necesario "traducirlo" a Pandas:

#Asignamos 
columnas = [(0, 2), (2,3), (3,4), (4,5), (5,7), (7,8), (8,16), (16,20), (20,28)]
data1 = pd.read_fwf("http://staff.math.su.se/esbj/GLMbook/mccase.txt", colspecs=columnas, header=None)
data1.head(10)

Vamos a crear una lista con el ancho de los campos que denominamos columnas, como siempre, en este caso empezamos en 0 no en el 1 y el final del anterior campo será el principio del siguiente, después sumamos a ese principio la longitud del campo que nos han definido. Ahora cuando usemos read_fwf que es la función necesaria para leer files-with-format, ficheros con formato, en colspecs pondremos la lista con las longitudes de los campos y en este caso no tenemos encabezados por lo que es necesario poner header = None. Ya tenemos un data frame al que solo falta asignar los nombres con los campos:

data1.columns = ['edad','sexo','zona','clase_moto', 'antveh', 'bonus', 'exposicion', 'nsin', 'impsin']
data1.head()

El ejemplo os sirve, pero se puede simplificar porque los campos son consecutivos usando widths = lista de longitudes:

data2 = pd.read_fwf("http://staff.math.su.se/esbj/GLMbook/mccase.txt", widths = [2,1,1,1,2,1,8,4,8], header=None)
data2.columns = ['edad','sexo','zona','clase_moto', 'antveh', 'bonus', 'exposicion', 'nsin', 'impsin']
data2.head()

Equivale a lo que hemos visto con anterioridad pero es preferible usar el primer método porque es más rápida la lectura. Saludos.

Leer una tabla en PDF con Excel (a través de R)

Hay situaciones en las que tenemos datos en pdf y los necesitamos exportar a Excel para graficar o cruzar esos datos. En ocasiones es mejor meter esos datos a mano, otras veces disponemos de un software de pago que nos permite realizar esa tarea y también hay páginas web que nos permiten cambiar el formato del pdf. En nuestro caso simplemente necesitamos una tabla que está en formato pdf para disponer de esos datos en Excel, más sencillo, copiar del pdf y pegar en Excel esa tabla. Si está en texto el pdf se puede complicar y si está en modo imagen más. Si empleas windows en tu esta entrada puede ser de utilidad ya que usando de R podrás hacer está tarea de copiar pdf y pegar Excel de un modo más rápido, te cuento paso por paso en video.

El primer paso será la instalación de R y RStudio:

Una vez hemos disponemos de R y Rstudio en nuestro equipo descarga este programa en R que te permitirá exportar una tabla a R con las instrucciones que resumo a continuación:

Esta entrada del blog quiero que sea dinámica, me gustaría mejorar el proceso porque tiene posibilidades de dar a conocer R a personas sin conocimientos de programación. Podemos crear desde una aplicación hasta leer url. Saludos.