Archivo de la categoría: R

Ejecutar un código al iniciar la sesión de R

A raíz de una conversación en Twitter os traigo un pequeño truco de R para aquellos que tenéis funciones predefinidas y que tenéis que cargarlas al iniciar las sesiones de R, es como ejecutar el código nada más abrir R. En mi caso el código que quiero ejecutar son una serie de utilidades que tengo guardadas en C:\carpeta, con source(“C:/carpeta/Utils.R”, encoding=”UTF-8″) R cargaría todo el código R alojado en ese script de R y necesito que se ejecute el script al inicial la sesión de R, no quiero poner esa línea al principio de cada programa. Lo primero que tenemos que hacer es buscar donde tenemos instalado R, una vez hallamos accedido a la correspondiente carpeta vamos a la subcarpeta /etc y tenemos un archivo llamado Rprofile.site lo abrimos con un editor de texto:

# Things you might want to change

# options(papersize="a4")
# options(editor="notepad")
# options(pager="internal")

# set the default help type
# options(help_type="text")
  options(help_type="html")

# set a site library
# .Library.site <- file.path(chartr("\\", "/", R.home()), "site-library")

# set a CRAN mirror
# local({r <- getOption("repos")
#       r["CRAN"] <- "http://my.local.cran"
#       options(repos=r)})

# Give a fortune cookie, but only to interactive sessions
# (This would need the fortunes package to be installed.)
#  if (interactive()) 
#    fortunes::fortune()

source("C:/carpeta/Utils.R", encoding="UTF-8")

Pues en ese archivo ponemos source("C:/carpeta/Utils.R", encoding="UTF-8") y cada vez que abramos nuestro R, desde RStudio por ejemplo, se ejecutará el script con nuestras utilidades.

Inteligencia Arficial frente a un juego de niños. La partícula tonta de Nicolás

Pablo Picasso decía que en aprender a pintar como los pintores del renacimiento tardó unos años pero pintar como los niños le llevó toda la vida y en ocasiones creo que hacemos las cosas difíciles porque nos creemos que hacemos cosas difíciles y entonces llega un niño de nueve años y dice “Papá un punto que primero vaya a la izquierda y luego a la derecha no es tan difícil”.
Os pongo en antecedentes, el pasado 7 de mayo fui al AWS Summit de Madrid porque Sergio Caballero iba a contar uno de los casos de uso. Los de AWS no se deben ni imaginar de las maravillas que ha hecho Sergio en el Ayuntamiento de Alcobendas porque sólo dejaron que hablara 10 minutos, muy torpes ellos, su trabajo es mejor escaparate que el planteado por Mai-Lan Tomsen, un error en el planteamiento de la jornada. El caso es que había una “competición” de vehículos que circulaban por un circuito guiados por complicados algoritmos de inteligencia artificial. Vimos algún “bucanero serio” de alguno de los participantes, ya sabemos reinforcement learning, pero reinforcement reinforcement. Otros participantes más o menos honrosos, en fin, distraído. Viendo la competición me entraron ganas de participar y al llegar a casa me siento a preparar un algoritmo que recorriera el circuito del Jarama de Madrid, no un circuito cualquiera un circuito donde yo he visto ganar carreras a Jorge Martínez Aspar.

Portátil y R, empiezo mi trabajo con imager, busco en la Wikipedia el circuito, lo cargo, genero un data frame, selecciono puntos y comienzo a diseñar mi propia estrategia de reinforcement learning combinadas con técnicas de machine learning, algo como “SVM direccionables” se acerca por detrás mi hijo y me suelta “Papá un punto que primero vaya a la izquierda y luego a la derecha no es tan difícil”. Bueno, pues en 20 minutos sale esto:

De momento no funciona pero no me digáis que no es genial la idea, lo que hace con pocas líneas de código y una consulta en sql. En el repositorio de analisisydecision tenéis el código en R que realiza esta maravilla, he llamado al código partícula tonta y tiene aspectos interesantes en cuanto al uso de la librería imager de R para el tratamiento de imágenes y como transformo una imagen en un data frame de coordenadas y por supuesto la genial idea de Nicolás.

Por cierto, al ver el resultado Nicolás dijo que no sólo derecha e izquierda, también era necesario un arriba y abajo. Tengo abandonado el proyecto, como muchos, pero la anécdota me ayudó en mi trabajo.

Gráfico de correlaciones entre factores. Gráfico de la V de Cramer

Un gráfico muy habitual a la hora de construir modelos de riesgo para el cálculo de tarifas es el gráfico de correlaciones de la V de Cramer que nos sirve para medir la correlación entre factores, entre variables cuantitativas hace muchos años ya escribí sobre el tema. Hoy os traigo la creación de un corrplot con R aplicado a la V de Cramer y además os descubro una función muy elegante para realizar este análisis de correlaciones entre factores, esta función está sacada de stackoverflow (como no) y añado un análisis gráfico que nos permite conocer algunas opciones de corrplot.

 library(vcd)
library(corrplot)
library(tidyverse)

data(mtcars)

#Partimos de una matriz vacía con las dimensiones apropiadas
empty_m <- matrix(ncol = length(correlaciones),
                  nrow = length(correlaciones),
                  dimnames = list(names(correlaciones),
                                  names(correlaciones)))

#Calculamos el estadístico y vamos rellenando la matriz
calculate_cramer <- function(m, df) {
  for (r in seq(nrow(m))){
    for (c in seq(ncol(m))){
      m[[r, c]] <- assocstats(table(df[[r]], df[[c]]))$cramer
    }
  }
  return(m)
}

Lo que hace la brillante función es, partiendo de una matriz cuadrada con los factores, ir rellenando con el correspondiente cálculo de la V de Cramer. El resultado final será igual que una matriz de correlaciones por lo que podremos realizar el gráfico.

predictoras <- c("cyl","vs","am","gear","carb")
correlaciones <- select(mtcars,predictoras)

cor_matrix <- calculate_cramer(empty_m ,correlaciones)
#Ya podemos graficarlo
corrplot(cor_matrix, method="number", is.corr=F,type="upper", diag=F, cl.lim=c(0,1))

remove(correlaciones)

El resultado:

Aspectos interesantes con la función corrplot, con method = "number" sale el valor, no me gustan las bolas, aunque podéis probar con pie, mejor poned is.corr = F con type="upper" sale la parte superior de la matriz, quitamos la diagonal que es 1 con diag=F y la V de Cramer es un valor que va entre 0 y 1 con cl.lim establecemos los límites de la leyenda en el gráfico de correlaciones. A partir de aquí cada uno que establezca un umbral para determinar que dos factores están correlados, yo por ejemplo lo establezco en 0.33, saludos.

¿Qué nos pasa con R? (de nuevo)

Hace años ya sorprendió R situándose muy arriba en la lista tiobe de lenguajes de programación subió en los años siguientes y ahora nos encontramos con una sorprendente bajada en el índice:

¿Volvemos a tener complejo por usar R? A veces tengo la sensación de que no eres un “pro” si no usas Python. Debe ser que determinados framework funcionan mejor en otros lenguajes, o no, pero nos da vergüenza usar R (de nuevo).

Longitud de las frases del Quijote con #rstats

Siempre he querido hacer cosas con Rstats y el Quijote y ayer se me ocurrió medir la longitud de las frases del Quijote y crear un histograma que describa esta longitud. Aunque confieso que no me lo he leído, me he quedado en el capítulo 7 u 8 (no recuerdo) el caso es que me pareció hipnótico con sus ritmos, es musical. Además tengo muchas ganas de meter mano al proyecto Gutemberg porque esos ritmos, esa musicalidad, el uso de palabras esdrújulas,… me llama la atención.
Bueno, al lío, todo el código está subido al repositorio por si lo queréis, pero hay algunas funciones y algunas ideas que me parecen interesantes.

library(dplyr)
library(ggplot2)
library(plotly)

#Leemos el fichero desde proyecto Gutemberg
ubicacion <- "https://www.gutenberg.org/cache/epub/2000/pg2000.txt"
quijote <- read.table (ubicacion,sep="\r", encoding="UTF-8")
quijote <- data.frame(quijote)
names(quijote) <- 'linea'

#Transformaciones e identificar el inicio del libro.
quijote <- quijote %>%
  mutate(linea = toupper(linea),
         inicio = grepl("EN UN LUGAR DE LA MANCHA",linea)>0)

Leemos directamente un txt desde Gutemberg y prefiero transformarlo en data frame para usar dplyr. Todas las palabras las pongo en mayúsculas e identifico donde empieza el Quijote, para evitar prólogos y demás. Ya tengo unos datos con los que poder trabajar:

#Marcamos lo que vamos a leer
desde <- which(quijote$inicio)
hasta <- nrow(quijote)

#Texto de trabajo
texto <- quijote[desde:hasta,1]

#El texto lo transformamos en una lista separada por espacios
texto_split = strsplit(texto, split=" ")

#Deshacemos esa lista y tenemos el data.frame
texto_col = as.character(unlist(texto_split))
texto_col = data.frame(texto_col)
names(texto_col) = 'palabra'

En este caso los datos los quiero de tal forma que disponga de un data frame con una sola variable que sea cada palabra del Quijote. Ahora voy a medir las frases identificando donde hay puntos en esas palabras:

#Identificamos donde tenemos puntos y un autonumérico del registro
texto_col <- texto_col %>% filter(!is.na(palabra)) %>%
  mutate(punto = ifelse(grepl('.',palabra,fixed=T),"FIN","NO"),
         posicion = row_number())

¿Qué se me ha ocurrido? Trabajar con autonuméricos, tengo identificados los puntos, ahora tengo que fijar una posición inicial y una posición final:

#Si unimos las posiciones con puntos con lag podemos calcular la longitud
pos_puntos1 <- filter(texto_col,punto=="FIN") %>% 
  select(posicion) %>% mutate(id = row_number())

pos_puntos2 <- pos_puntos1 %>% mutate(id = id + 1) %>%
  rename(posicion_final = posicion)

pos_puntos <- left_join(pos_puntos1,pos_puntos2) %>%
  mutate(longitud = ifelse(is.na(posicion_final), posicion, posicion - posicion_final))

Como no soy un tipo muy brillante opto por una opción sencilla de cruzar una tabla consigo misma, como me ponen los productos cartesianos “con talento”. La idea es seleccionar solo los registros que marcan el final de la frase, un autonumérico me marca cual es cada frase, ahora si hago una left join por el id de la frase y el id + 1 de la frase creo una especie de lag. La longitud de la frase será donde está el punto menos donde estaba el final de la anterior frase. Creo que me he explicado de pena, pero si veis el data frame final lo entenderéis mejor. Ahora ya pinto un histograma:

#GRaficamos la longitud
plot_ly(data = pos_puntos, x = ~longitud, type = "histogram") %>%
  layout(title = "Longitud de las frases del Quijote",
         xaxis = list(title = "Longitud"), yaxis = list(title = ""))

Y queda una gamma perfecta, yo diría que hasta bonita. Ahora quedaría identificar los parámetros de esta gamma y compararlos con otros libros, e incluso comparar lenguas. Pero esas tareas se las dejo a los “buenos”.

Gráfico con eje secundario en ggplot2

Los gráficos con eje secundario o con dos ejes son un tema que ya he puesto en el blog en varias ocasiones, hay un ejemplo con R que tenía sus problemas y hay un ejemplo con Python y matplotlib que particularmente me gusta por elegancia y sencillez. En esta entrada vamos a repetir el ejercicio y vamos a realizar un gráfico de columnas y líneas con 2 ejes, primario y secundario pero con ggplot2. Este tipo de gráficos son muy utilizados por los actuarios para representar frecuencias o siniestralidades y exposición. Para ilustrar el ejercicio vamos a emplear los mismos datos que usamos en el ejemplo con matplotlib pero vemos paso a paso como realizaríamos el gráfico Seguir leyendo Gráfico con eje secundario en ggplot2

Trucos simples para #rstats

En mi cuenta de twitter suelo poner algunos trucos sencillos de R, cosas que me surgen cuando estoy trabajando y que no me cuesta compartir en 2 minutos, por si puedo ayudar a alguien. Me acabo de dar cuenta que de verdad son útiles y que tenerlos en twitter desperdigados es un problema, así que he pensado en recopilarlos en una entrada del blog para que sea más sencillo buscarlos (incluso para mi). Aquí van algunos de esos trucos Seguir leyendo Trucos simples para #rstats

Porque no vamos a cobrar pensiones. Animación con R y pirámides de población

Estoy creando material para un módulo de un máster que voy a impartir y escribiendo sobre seguros de ahorro he llegado a crear esta animación:

Se trata de una animación con las pirámides de población de España desde 1975 hasta 2018 de 5 en 5 años. El sistema de pensiones español se basa en 5 principios:
1. principio de proporcionalidad
2. principio de universalidad
3. principio de gestión pública
4. principio de suficiencia
5. principio de reparto

La animación va directa contra el principio de reparto. En el sistema español nadie ha cotizado para garantizarse su pensión, los actuales trabajadores pagan las prestaciones de aquellos trabajadores jubilados. Si tras leer estas dos frases y mirar la animación sigues recelando de la migración de personas a España espero que tengas un buen plan de ahorro privado.

Esta animación está hecha con R, los datos están descargados del INE pero están ligeramente cocinados (no al estilo Tezanos). En https://github.com/analisisydecision/wordpress tenéis este Excel con el formato adecuado, el código empleado para realizar la animación está en https://github.com/analisisydecision/wordpress/blob/master/Piramide_poblacional.R Es un buen ejemplo de uso de plotrix y pyramid.plot espero que el código no tenga algún gazapo…

Data management con dplyr

Dos años con pandas y sckitlearn y ahora vuelvo a R. Y en mi regreso me propuse comenzar a trabajar con dplyr y mi productividad se está incrementando exponencialmente, creo que dplyr es LA HERRAMIENTA para el manejo de data frame con R, ni me imagino como puede funcionar sparlyr… Para aquellos que estéis iniciando vuestra andadura con R o para los que no estéis acostumbrados a dplyr he hecho una recopilación de las tareas más habituales que hago con esta librería. Se pueden resumir:

• Seleccionar columnas
• Seleccionar registros
• Crear nuevas variables
• Sumarizar datos
• Ordenar datos
• Uniones de datos

Como es habitual trabajamos con ejemplos data(iris); library(dplyr):

Seleccionar columnas select():

two.columns <- iris %>%
select(Sepal.Length,Sepal.Width)

columns = c(“Sepal.Length”,”Sepal.Width”)
two.columns <- iris %>%
select(columns)

Seleccionar registros filter():

setosa <- iris %>%
filter(Species==”setosa”)

species_to_select = c(“setosa”,”virginica”)
species <- iris %>%
filter(Species %in% species_to_select)
table(species$Species)

Crear nuevas variables mutate():

iris2 <- iris %>%
mutate(Sepal.Length.6 = ifelse(Sepal.Length >=6, “GE 6”, “LT 6”)) %>%
mutate(Sepal.Length.rela = Sepal.Length/mean(Sepal.Length))

Sumarizar group_by() summarize():

iris %>% group_by(Species) %>%
summarize(mean.Sepal.Length = mean(Sepal.Length),
sd.Sepal.Length = sd(Sepal.Length),
rows = n())

Ordenar datos arrange():

order1 <- iris %>%
arrange(Sepal.Length)

order2 <- iris %>%
arrange(desc(Sepal.Length))

iris %>% group_by(Species) %>%
summarize(mean.Sepal.Length = mean(Sepal.Length),
sd.Sepal.Length = sd(Sepal.Length),
rows = n()) %>%
arrange(mean.Sepal.Length)

Uniones de datos:

Inner_join():

iris2 <- iris %>%
mutate(id = row_number())

iris3 <- iris2 %>%
filter(Species==”setosa”) %>%
mutate(Sepal.Length.6 = ifelse(Sepal.Length >=6, “GE 6”, “LT 6”)) %>%
mutate(Sepal.Length.rela = Sepal.Length/mean(Sepal.Length)) %>%
select(id,Sepal.Length.6,Sepal.Length.rela)

iris4 <- iris2 %>% inner_join(iris3, by=c(“id”))

Left_join():

iris5 <- iris2 %>% left_join(iris3, by=c(“id”))

anti_join():

iris6 <- iris2 %>% anti_join(iris3)

Aquí tenéis una muestra de las posibilidades de dplyr y como se pueden combinar entre ellas. Creo que la sintaxis es bastante sencilla y se aprende con facilidad, si a mi no me esta costando mucho…