data.tree: porque no todos los datos son tabulares

De acuerdo, casi todos los datos son tabulares. Digamos que el 90% de ellos. Pero muchos de ellos, no. Y data.tree es un paquete con muy buena pinta para manejar estructuras arborescentes de datos: véanse esta y esta viñeta. Como no podía ser de otra manera, tiene funciones para recorrer, filtrar y podar los árboles de datos. La aplicación gracias a la cual di con él es el paquete prof.tree, que es lo mismo que el Rprof de toda la vida… solo que mola más: ...

18 de diciembre de 2018 · Carlos J. Gil Bellosta

Siete años después, dejo la presidencia de la Comunidad R Hispano

Eso, que dejo la comunidad de la Comunidad R Hispano. Ocho años después, que ya son. La noticia, en todo caso, no es tanto que abandone la presidencia sino las circunstancias que me condujeron a ella. Noticias viejas, pero noticias al fin y al cabo, que sirven para entender por qué lo fui entonces y por qué dejo de serlo ahora. La Comunidad R Hispano (por qué se llama así y no, como habría sido natural, Asociación Española de Usuarios de R, es una larga historia que tal vez cuente algún día) se fundó en Madrid hace ocho años en el seno de las III Jornadas de Usuarios de R (a todo esto, esa página la hice yo en html puro y con vi como editor), cuando la comunidad (informal) de usuarios de R ya llevaba un tiempo desarrollando actividades. ...

11 de diciembre de 2018 · Carlos J. Gil Bellosta

Colinealidad y posterioris

En esta entrada voy a crear un conjunto de datos donde dos variables tienen una correlación muy alta, ajustar un modelo de regresión y obtener la siguiente representación de la distribución a posteriori de los coeficientes, donde se aprecia el efecto de la correlación entre x1 y x2. El código, library(mvtnorm) library(rstan) library(psych) n <- 100 corr_coef <- .9 x <- rmvnorm(n, c(0, 0), sigma = matrix(c(1, corr_coef, corr_coef, 1), 2, 2)) plot(x) x1 <- x[,1] x2 <- x[,2] x3 <- runif(n) - 0.5 y <- 1 + .4 * x1 - .2 * x2 + .1 * x3 + rnorm(n, 0, .1) summary(lm(y ~ x1 + x2 + x3)) stan_code <- " data { int N; vector[N] y; vector[N] x1; vector[N] x2; vector[N] x3; } parameters { real a; real a1; real a2; real a3; real sigma; } model { a ~ cauchy(0,10); a1 ~ cauchy(0,2.5); a2 ~ cauchy(0,2.5); a3 ~ cauchy(0,2.5); y ~ normal(a + a1 * x1 + a2 * x2 + a3 * x3, sigma); }" datos_stan <- list( N = n, y = y, x1 = x1, x2 = x2, x3 = x3 ) fit2 <- stan(model_code = stan_code, data = datos_stan, iter = 10000, warmup = 2000, chains = 2, thin = 4) res <- as.data.frame(fit2) pairs.panels(res[, c("a", "a1", "a2", "a3", "sigma")])

16 de noviembre de 2018 · Carlos J. Gil Bellosta

¿Siguen votando igual los diputados?

Hace seis años escribí esto. Hoy actualizo aquella entrada para crear Y, por supuesto, el código (que he tenido que reescribir en gran medida): library(xml2) library(reshape2) library(plyr) # descarga y manipulación de datos dia_votacion <- function(n.votacion){ dir.create("tmp") url <- paste("https://app.congreso.es/votacionesWeb/OpenData?sesion=", n.votacion, "&completa;=1&legislatura;=12", sep = "") download.file( url, destfile = "./tmp/votos.zip") try(unzip("./tmp/votos.zip", exdir = "./tmp"), TRUE) ficheros <- dir("./tmp", pattern = ".*xml", full.names = T) if (length(ficheros) == 0) return(NULL) res <- lapply(ficheros, function(fichero){ print(fichero) datos <- as_list(read_xml(fichero)) sesion <- datos$Resultado$Informacion$Sesion numero <- datos$Resultado$Informacion$NumeroVotacion try(datos <- ldply(datos$Resultado$Votaciones, unlist), TRUE) if (class(datos) == "try-error") return(NULL) if (class(datos) != "data.frame") return(NULL) if(nrow(datos) == 0) return(NULL) datos$sesion <- sesion datos$numero <- numero datos }) unlink("./tmp", recursive = T) # borra el directorio temporal res } tmp <- lapply(1:156, dia_votacion) datos <- tmp[!sapply(tmp, is.null)] datos <- lapply(datos, function(x) do.call(rbind, x)) datos <- do.call(rbind, datos) datos$numero <- as.numeric(unlist(datos$numero)) datos$sesion <- as.numeric(unlist(datos$sesion)) datos$asunto <- as.character(1000000 + 1000 * datos$sesion + datos$numero) datos$ind <- 0 datos$ind[datos$Voto == "No"] <- -1 datos$ind[datos$Voto == "Sí"] <- 1 tmp <- dcast(datos, asunto ~ Diputado, value.var = "ind", fill = 0) matriz_votos <- as.matrix(tmp[, -1]) rownames(matriz_votos) <- NULL colnames(matriz_votos) <- NULL heatmap(matriz_votos, xlab = "Diputados", ylab = "Asuntos", scale = "none") No sé si alguien querrá sacarle más punta a la no historia de hoy.

8 de noviembre de 2018 · Carlos J. Gil Bellosta

Cuatro paquetes interesantes de R

Son paquetes que marcado como potencialmente relevantes pero que aún no he revisado como debiera. Tal vez alguien tenga algo más que decir sobre ellos. Tiene los comentarios, por supuesto, abiertos. longRPart2: Particionamiento recursivo para modelos longitudinales. Extiende ctree y, por supuesto, mob del paquete party a datos de tipo longitudinal. radiant: Más que un paquete, es un conjunto de paquetes para business analytics usando R y Shiny. Ni idea de para qué parte de ese amplio campo del business analytics puede resultar útil, pero si resulta que es precisamente el tuyo, ¡enhorabuena! ...

5 de noviembre de 2018 · Carlos J. Gil Bellosta

Enlaces parasociológicos

Tenía tan bien guardados en el disco duro una serie de enlaces de interés parasociológico que no había forma humana de dar con ellos. Para que no me vuelva a pasar y por su potencial interés para otros, los cuelgo aquí. El primero de ellos (que no sé por qué lo guardé) son las diapositivas de una charla acerca de cómo transformar porcentajes de votos en escaños en España. Los otros tres se refieren a la metodología que utiliza la gente de electionforecast.co.uk: ...

29 de octubre de 2018 · Carlos J. Gil Bellosta

Extingámonos con dignidad: generaciones actuales y futuras, no incurramos en los errores de las anteriores

Participé el otro día en una cena con gente friqui. Constaté con cierto desasosiego cómo han virado los sujetos pasivos de nuestra indignación profesional a lo largo de los años. Antaño, fueron los viejos que seguían apegados a la paleoinformática. Hogaño, los primíparos que usan Python y desdeñan R. Tengo sentimientos encontrados y no sé qué más añadir.

8 de octubre de 2018 · Carlos J. Gil Bellosta

"Embeddings" y análisis del carrito de la compra

Escribiendo la entrada del otro día sobre embeddings, no se me pasó por alto que la fórmula $$ \frac{P(W_i,C_i)}{P(W_i)P(C_i)}$$ que escribí en ella es análoga al llamado lift (¿es el lift?) del llamado análisis del carrito de la compra, i.e., el estudio de productos que tienden a comprarse juntos (véase, por ejemplo, esto). Lo cual me lleva a sugerir mas no escribir una entrada en la que se rehagan este tipo de análisis usando embeddings: los ítems como palabras, los carritos como textos, etc. Si alguien tiene tiempo y le sale algo potable, que avise y lo enlazo aquí. ...

4 de octubre de 2018 · Carlos J. Gil Bellosta

Planes de búsqueda y rescate con R

Existe un paquete muy curioso en CRAN, rSARP para diseñar, optimizar y comunicar la evolución de planes de búsqueda y/o rescate (p.e., de un niño desaparecido en un monte). Es particularmente interesante porque este tipo de problemas lo tienen todo: desde distribuciones a priori (sobre dónde es más probable encontrar lo que se busca) hasta la decisión final (explórese tanto aquí y tanto allá) teniendo en cuenta restricciones de tiempo y recursos. ...

2 de octubre de 2018 · Carlos J. Gil Bellosta

Disponible el fichero de datos abiertos más goloso de ambas castillas: las rutas de Bicimad

Albricias, el ayuntamiento de Madrid ha liberado el fichero más goloso de ambas castillas: el de las rutas de usuarios de Bicimad, viaje a viaje, con su estación de origen, estación de destino, tiempo de recorrido, etc. Tiempo os falta para echarle un vistazo y hacer cosas chulas con él. Los datos están aquí. Se puede leer con código no muy distinto de este: library(RJSONIO) raw <- readLines("201808_Usage_Bicimad.json") dat <- iconv(raw, "latin1", "utf8") dat <- sapply(dat, fromJSON) A bote pronto, se me ocurren algunas cosas que se pueden hacer con esos datos: ...

25 de septiembre de 2018 · Carlos J. Gil Bellosta