Cómo empezar a procesar millones de tuits (o tweets)

Nota de junio 2020: hay una funcionalidad del t-hoarder que permite el procesado de todos los tuits almacenados. Estoy ayudando a documentarla en la wiki de t-hoarder. Estoy teniendo algunos problemas para que me funcione, tema de CGI.

Para mi tesis sobre cobertura de corrupción en España llevo tiempo recopilando tuits. Llevo el seguimiento de mensajes de Twitter relacionados con algunos casos de corrupción, para luego poder compararlos con cómo los medios de comunicación han hablado del tema.

Utilizo t-hoarder, desarrolllado por Mariluz Congosto, para capturar tuits según se van publicando. Lo tengo instalado en un servidor remoto que está continuamente descargándose tuits que contienen una determindad lista de palabras. Con un interfaz en la línea de comandos desarrollado en python permite interactuar de manera sencilla con la API de Twitter para obtener y procesar tuits descargados (ver este manual que escribimos hace un tiempo para aprender a usarlo).

T-hoarder guarda los tuits en archivos .txt en formato .tsv. Cada cierto tiempo comprime el archivo streaming_cifuentes-master_0.txt en uno comprimido streaming_cifuentes-master_0.txt.tar.gz que contiene entre 150.000 o 250.000 tuits.

En el servidor se van acumulando estos archivos comprimidos que me descargo periódicamente con rsync:
rsync -zvtr -e ssh numeroteca@111.111.111.111:/home/numeroteca/t-hoarder/store/ .

Con ese sistema tengo un directorio con múltiples archivos de los diferentes temas que voy capturando:

El primer paso consiste en entender de forma básica qué he conseguido recopilar. Hay múltiples razones por las que puedo tener agujeros en los datos: el servidor se llenó, el acceso a la API de Twitter se interrumpió por algún problema de permisos, etc.

Para ello he desarrollado este pequeño script en bash para obtener la información básica que contiene cada archivo de tuits:

Este script lee todos los archivos como streaming_cifuentes-master_20.txt
y va guardando en cada línea del archivo mycifuentes.txt en líneas separadas: el nombre del archivo tar.gz, la fecha y hora del primer tuit (head) y del último (tail) y por último el número de tuits. Con eso obtengo un archivo como este:

Que proceso a mano en gedit son sustituciones masivas (me falta generar mejor el tsv donde cada campo esté en la línea que le corresponde):

Actualización 8 junio 2020: Gracias a @jartigag@mastodon.social que me llegó por Twitter no me hace falta el procesado manual ya que cada dato va a su propia columna:

streaming_cifuentes-master_0.txt.tar.gz2018-04-05 14:41:192018-04-08 16:35:20828374
streaming_cifuentes-master_10.txt.tar.gz2018-04-25 23:09:132018-04-26 18:28:23158526
streaming_cifuentes-master_11.txt.tar.gz2018-04-26 18:28:242018-05-02 06:54:32157770
streaming_cifuentes-master_12.txt.tar.gz2018-05-02 06:54:372018-05-11 10:33:00155426

Proceso este archivo mycifuentes_processed.tsv, sin cabecera con este otro script de R:

lo que hace es leer el archivo (read_tsv) y cuenta las horas entre el primer y último tuit y calcula los tuits por hora:

Ahora ya podemos hacer las primeras visualizaciones para explorar los datos. En este primer gráfico cada línea es un archivo que va del primer al último tuit según su fecha. En el eje vertical se indica el número medio de tuits por hora. En el caso del master de Cifuentes el primer archivo no se comprimió por error y contiene 828.374 tuits. el fondo gris indica cuando no hay tuits descargados. Hay un periodo en blanco la inicio del caso y otro en diciembre de 2019, la escala vertical es logarítmica, para que se puedan ver todos los archivos incluyendo los primeros.

En este otro gráficos (escala vertical lineal) muestro los archivos de tuits que he capturado de unos cuantos medios de comunicación españoles, para luego poder comparar las diferentes coberturas, vuelvo a tener agujeros para los que todavía tengo que encontrar explicación.

En este otro gráfico comparo la fecha del archivo con el número de tuits que contiene:

Este es un primer análisis muy “meta” que no entra ni de lejos a analizar el contenido de los tuits pero me sirve como primer paso para entrar en faena a analizar los datos que tengo. Tenía que haber hecho esto hace tiempo. En cualquier caso bueno es ponerse en marcha y documentar. Mis conocimientos de bash son escasos pero creo que merece la pena y es más rápido en este caso que usar R. Inspirado por este libro que estoy a medio leer Data Science at the Command Line de Jeroen Janssens.

El código de R para procesar los datos está disponible en este script: https://code.montera34.com:4443/numeroteca/tuits-analysis/-/blob/master/analysis/index-tweet-containers.R

Análisis de propagación de COVID-19 por comunidades autónomas en España

Nota: no soy experto en epidemias ni en medicina. Me he limitado a plasmar gráficamente los datos publicados por el Ministerio de Sanidad. Si ves errores en los gráficos o de concepto, házmelo saber. Son datos de casos registrados, no tienen en cuenta los protocolos para obtención de datos (pruebas) de cada comunidad autónoma ni todos los casos “reales” que hay pero no han sido detectados.

Errores por resolver: la bajada de datos en Galacia en una base de datos acumulativa debe ser un error. Estamos mirando a qué puede deberse.


Hemos montado desde Montera34 una web para mantener actualizados estos datos en lab.montera34.com/covid19/


Cuando ayer publiqué una reflexión sobre lo que estaba pasando en relación al COVID-19 y la necesidad de autoencerrarse para la parar su propagación, no había mirado si había gráficos de evolución por comunidad autónoma en España. Sí que encontré mapas de “bolas”, tablas con el número por comunidad autónoma, pero no su evolución en el tiempo.

Lo primero que encontré fue el repositorio de datos por países (y algunas provincias y estados) que recopilan desde la universidad de Johns Hopkins y que se pueden ver en este dashboard de Rami Krispin. Sin embargo, lo que buscaba eran datos desagregados por comunidad autónoma o provincia en España, y esos no estaban disponibles. Quería conocer el avance del virus en mi entorno más cercano.

Encontré que el Ministerio de Sanidad, Consumo y Bienestar Social los estaba publicando en PDF (!) en informes diarios desagregados por comunidad autónoma. Cuando estaba descargando todos los PDF encontré que desde Datadista los habían pasado a un formato reutilizable. Alegría, visitad su respositorio. (Todavía no sé de qué PDF han sacado los datos previos al 3 de marzo, espero aclararlo cuando pueda).

Con los datos a mano monté un repositorio de R para analizar cómo estaba evolucionando la propagación por comunidad autónoma. Estos son los resultados.

Número de casos registrados

Lo primero es ver el número de casos registrados por cada comunidad autónoma. Un “small multiple” parece una buena opción para ver cada uno de los lugares:

Todos tienen una pendiente parecida. Sorprenden las “mesetas”, zona horizonal de de Cantabria y Extremadura. Ojo, porque estamos usando una escala logarítmica en el eje vertical, si usáramos una escala lineal veríamos poco o casi nada. (Sobre escala logarítmica y pandemias).

Podemos ver los mismos datos superpuestos en el siguiente gráfico, donde se aprecia que la pendiente es similar en cada línea. Una línea recta en una escala logarítmica indica que el crecimiento es exponencial. Madrid encabeza en número de casos seguido de País Vasco y Cataluña.

Si profundizamos un poco más podemos calcular los datos relativos a la población de cada comunidad autónoma. Aunque el número de casos acumulados es lo que muchos quieren saber, el relativo a su población nos puede permitir entender mejor lo que está pasando. En este caso representamos a los casos acumulados de COVID-19 por millón de habitantes:

La Rioja pasa del 4º al primer puesto con 647 por cada millón de habitanes, seguido por Madrid (208), País Vasco (156) y Navarra (111).

Número de ingresos en la UCI

Miremos ahora los casos registrados de personas en la UCI (Unidad de Cuidados Intensivos):

Madrid (135) parece está a la cabeza claramente en número de ingresos en la UCI por el COVID-19, seguida de Euskadi (18), y Castilla-La Mancha (9):

En números relativos también es la comunidad de Madrid la primera con respecto a su población, tiene 20,3 por cada millón de habitantes, seguida de Euskadi (8,2) y Navarra (4,6):

Fallecimientos por COVID-19

El número total de fallecimientos registrados por COVID-19 a día 12 de marzo de 2020 ascendía a 84 en toda España.

En números totales la Comunidad de Madrid va primera en fallecimientos con 56, muy lejos de Euskadi con 11.

Sin embargo, si lo relacionamos con su población, vemos que las diferencias no son tan grandes. La Rioja (6,3 fallecidos por cada millón de habitanes) pasa a estar muy cerca de Madrid (8,4), les siguen Euskadi (4,9) y Aragón (4,5).

Todo el código para producir estos gráficos está en este repositorio: https://code.montera34.com:4443/numeroteca/covid19. Os animo a echar un ojo y ayudar a mejorarlo. En la carpeta de imágenes podéis encontrar todas las que no han tenido cabida en este artículo.

Los datos representados son de casos registrados, según otros análisis, hasta que pasen varias semanas no sabremos

Fuente de los datos

Del COVID-19 en España están sacados del repositorio de Datadista los extrae a su vez de las tablas de la situación diaria de la enfermedad por el coronavirus (COVID-19) en España que publica el Ministerio de Sanidad, Consumo y Bienestar Social en incómodos PDF. Actualizados a día 12 de marzo de 2020. ¿Por qué no los publica en mejores formatos? Eso da para otro artículo.

Los datos de población en 2019 por comunidades autónomas son del INE.

Repositorio para ver cómo están hechos los gráficos con R. Participa. Los datos procesados están en /data/output.

Las visualizaciones actualizadas en lab.montera34.com/covid19

Coda: escala lineal vs escala logarítmica

A petición popular subo este gif animado que representa los mismos datos, número de casos registrados por comunidad autónoma en España cambiando la escala del eje vertical:

  1. escala líneal,
  2. escala logarítmica y
  3. escala logarítmica y casos por millón de habitantes.
A la izquierda escal lineal y a la derecha logarítmica

En la escala lineal solo se aprecia de manera clara los datos de Madrid.

Comparativa escala logarítmica y lineal en el eje vertical.

El hilo

Estoy para que me encierren

Actualización 12.03.2020: Análisis de propagación de COVID-19 por comunidades autónomas en España.

Los inevitables chistes, los del Atleti jugando el partido de la Champions en Anfield con todo el público y sus 2.000 aficionados cantando “coronavirus lo lo lo lo lo coronavirus”, los coles cerrados, otros coles abiertos, las universidades posponiéndolo todo, otras abiertas, las fallas suspendidas, la semana santa sevillana que no la toquen, los congresos cancelados, las videoconferencias, el teletrabajo, parlamentarios infectados, plantillas infectadas, verse por la calle y darse dos besos, verse y no tocarse, los pintxos en la barra, la tortilla en la barra, otras tortillas protegidas por plástico, la economía que va mal, las ayudas, los que pierden trabajo, los abuelos que echan una mano, los sistemas sanitarios saturados, políticos echándose las culpas, desde ayer es oficialmente pandemia y mientras… mis hijos en el cole.

Vivimos tiempos confusos, de precrisis o de crisis total. Sabemos muchas cosas aunque parece que no las sepamos. Ninguno queremos parecer paranoicos. Parece imposible pararlo todo ¡hasta los viajes en avión! ¡hasta el (sacrosanto) trabajo! pero todo es posible si la vida está en juego. Parece que es el momento de arrimar el hombro, preocuparse por lo importante (no me refiero a hacer acopio de comida en el súper), pero no lo hacemos del todo. Hace falta que nos obliguen, que nos lo manden.

Me imagino que si los efectos del cambio del clima fueran más rápidos y palpables (y cercanos) también entraríamos en estado de pánico y empezaríamos a actuar. ¿Recordáis aquel volcán que hizo que no se pudiera viajar en avión en Europa? Lo imposible era posible y no era Greta cruzando el Atlántico. Había otra forma de moverse o de quedarse en su sitio. La crisis del coronavirus pone de manifiesto los problemas de la producción deslocalizada (made in China), del crecimiento económico como mantra, por citar dos, cuando el centro de la vida no está ahí sino en pulmones respirando y corazones latiendo.

Habrá que hacer lo que sea para parar esto. Esperemos que se quede en una pandemia que conseguimos parar, o amainar por lo menos, pero para eso nos lo tenemos que tomar en serio, como si la vida de muchos estuviera en juego. Tenemos los manuales, las recomendaciones, pero algunos no los ponemos en práctica del todo. Parece como si el problema fuera de otros, cuando ya está llamando ahora mismo a nuestra puerta. Estamos para que nos encierren ¡ciérralo antes de que sea demasiado tarde! ¡antes de que pase otro día!

Por mi,
por todos mis compañeros
y, sobre todo,
por nuestros padres y abuelos.

Escrito desde un Bilbao feliz
con pintxos en la barra,
besándonos en la cara,
hablando a medio metro de distancia.

PD: poco después de publicar este post, que escribí anoche para mandarlo por el chat de whatsapp familiar, se anunció el cierre de todas las clases en centros educativos en Euskadi. El resto de medidas está por llegar.

PD2: he montado un repositorio para ayudar a procesar con R los datos del Ministerio de Sanidad.

Una serie de recursos de interés sobre el COVID-19:

Brand new features: edit areas, fork threads, multi taxonomy!

After a while we are glad to announce brand new features in PageOneX.

We developed these features last summer, but until now they have not been available in the hosted version at pageonex.com. We worked with Juanjo Bazán (@xuanxu) in this.

Export a thread in raw format

Download raw areas

Rebuilding the thread in R it is now possible. It also works for multiple newspapers. Here a cleaner version. Compare it with the thread in @PageOneX website. You can do it downloading Raw Areas Data json. R code available: https://t.co/4bVMRMbRws pic.twitter.com/gQXBhR2T1Y

— numeroteca (@numeroteca) May 10, 2019

Until now you could export the percentage of coverage per day and paper in json and spreadsheet, now there is an extra feature that allows you to export the raw data: the extact location of every area and all its classifications (read following feature). We are starting a new project pageonexR that allows you to import your threads to R and analyse their data.

Classify by multiple taxonomies

This new feature would add the capability to add extra information to drawn areas. A highlighted area could have multiple taxonomies and open fields.

Until this new release you could only classify each area with one taxonomy. For example, an area could be categorized as “International coveragae” but not as “International  coverage” AND “Nigeria” AND “positive framing”. Now you can do it . This feature is only available for certain users. If you want to use it write a comment to this post. We are studying how to make this available for all the users.

Fork a thread

Another cool feature is that you can fork a thread in @pageonex.
If you see a thread that you like you can clone it and work on it! pic.twitter.com/BxsH9wq6Ub

— numeroteca (@numeroteca) May 10, 2019

If you like another’s user thread: you can clone and edit it.

For a thread in PageOneX

Edit and remove areas

Something basic that is now possible is to edit and delete areas in https://t.co/TSwWbvktjk. Very useful for everyone, specially for heavy users. Before you have to delete all the areas in a day to edit the category of one! @PageOneX pic.twitter.com/PosXAwteTl

— numeroteca (@numeroteca) May 10, 2019

Before you had to erase all the areas in a front page to remove one. Now you can remove them separately and re-classify them.


Another great thing is the new containerized versions of PageOneX. Rafa Porres (@walter_burns)  developed it and Rahul Bhargava  (@rahulbot) deployed it at Civic media server. Thanks for your support!!

Containeraized versions, make your own deployment

Pageonex is an open-source project. Thanks to Rafa Porres (@walter_burns) we have PageOneX ready to use in a docker container. In fact, the new containerized version is what we are using now in the production version at pageonex.com. If you don’t want to use the hosted version of pageonex at http://pageonex.com you have a few options to run it yourself. Read our documentation and choose the best option for you. We hope this helps other developers help extending the features of PageOneX.

x-posted from PageOneX blog.

Cobertura de partidos en páginas de inicio en elecciones generales 28A

Sacado de este hilo de twitter:

He analizado los titulares de las páginas de inicio de algunos periódicos online antes del #28A para medir la cobertura de los principales partidos de ámbito estatal. Cuento nº de titulares que contengan los nombres, siglas o líderes de cada partido #homepagex c @PageOneX

He calculado también el porcentaje de esos titulares sobre el total de titulares de cada página de inicio #28A.  Una forma de medir automatizadamente la cobertura que realiza cada medio.

Y aquí agrupando por partido, que facilita la comparativa entre cabeceras. Las líneas finas son los datos por hora y las más gruesas el redondeo que permite ver las tendencias más fácilmente #28A

Son análisis preliminares mientras refino la herramienta. Encantado si queréis aportar vuestra lectura y crítica. Hoy no me dará tiempo a más. Se basan en una base de datos que recopila hora a hora las páginas de inicio de cada periódico

Este análisis trata de aplicar una metodología parecida a la que hago con @PageOneX con las portadas de los periódicos impresos https://ijoc.org/index.php/ijoc/article/view/4442 …

Primer museo de las letras en Berlín

Escribí este artículo hace 10 años para la revista Pasajes. Lo rescató con motivo de la exposición Paco Graco sobre rotulación comercial rescatada que cierra hoy.


Se prepara en Berlín el museo de las letras: rótulos y letras de todos los tamaños esperan en su almacén mientras buscan dónde ser expuestos. Desde las letras de la AEG de Behrens hasta la U de su U-bahn. Para visitar una parte del Berlín que ya no es el que era (ni nunca lo fue).


El legado tipográfico de de las ciudades ha sido recopilado hasta el momento, si hubo suerte, en catálogos fotográficos. Existen extensos libros que recogen las gráficas de las ciudades pero hasta el momento no se conocía un lugar donde mostrar los rótulos que las ciudades van tirando a la basura. Por cualquierchatarrería del mundo van pasando siempre kilos de letras que ya nadie quiere, como las toneladas que vieron los ferro-velhos de São Paulo tras la ley que suprimía toda la rotulación de sus calles.

En Madrid hemos visto desaparecer hace poco tiempo uno de sus más bellos rótulos, tanto por su tipografía como por su contenido. Estaba en la Plaza de los Mostenses y ha sido sustituido por unvinilo infame. Además, el rótulo daba nombre a uno de los primeros libros sobre la gráfica de Madrid: El sol sale para todos. Seguramente tendría que haber viajado a este nuevo Walhalla de la letras,  pero ¿no hubiera sido suficiente con que los nuevos dueños se dieran cuanta de lo que tenían entre manos?

Para echar un ojo al museo buchstabenmuseum.de

Siguen las tribulaciones de un autónomo vizcaíno

Desde hace un tiempo me debato entre contratar a alguien para que me solucione todos mis asuntos con Hacienda (vizcaína) o seguir por mi cuenta. En el fondo, me gusta estar al tanto de mis obligaciones fiscales, de lo que tengo que preparar, pero también pienso que puede que no sea la mejor inversión de mi tiempo. Los trámites que tengo que hacer, iguales para cualquier autónomo, son presentar los modelos 303 (trimestral) y 390 (anual) de IVA, los 110 (trimestral) y 140 (anual) de IRPF, el 140 (anual) , que es el libro de con todas las facturas emitidas y recibidas y la declaración de la renta.

Me lo he he tomado como una gincana en la que cada año se van añadiendo nuevas pruebas que tienes que aprender cómo solucionar. Desde hace poco, por ejemplo, hay que enviar en febrero el libro de facturas, que te obliga a meter una a una a mano todas las facturas de gastos y las emitidas. No te facilitan un método para poder introducirlas masivamente.

Así que hoy, 25 de abril de 2019, aquí estoy de nuevo entregando el documento que acredita mis ingresos y gastos del IVA trimestral. Esta vez me salía a compensar y he tenido que instalar una nueva cosa (id@zki) para que me permitiera firmar digitalmente con mi certificado digital habitual de la FNMT.

Habitualmente, como los bancos donde tengo cuenta, no son entidades colaboradoras con la hacienda vizcaína, tengo que hacer la engorrosa operación de sacar el dinero en efectivo y pagarlo en cualquier de los bancos que sí tienen un convenio colaborador. Esto obliga, cuando el importe supera los 3.000€, a que la entidad informe a la AEAT o hacienda correspondiente, para prevenir el blanqueo de capitales.

Además está el repetido tema de tener que pagar el IVA de facturas que no has cobrado todavía. Si esas facturas son de la Diputación de Vizcaya la cosa tiene se da la paradoja de tener que pagarles (“devolver”) el IVA que no te han pagado.

Bueno, lo dejo por hoy, es un post de queja, que hacía casi 6 años que no escribía sobre el tema. Estamos en el cierre de la campaña electoral y escucho hablar a muchos candidatos de apoyar a los autónomos, pero en nada se han simplificado mis trámites (al contrario) o reducido los costes en mis 15 años de autónomo. Sigo pagando a la Seguridad Social un fijo, da igual lo que facture, ni puedo pagar digitalmente (ni domiciliando cuenta ni con tarjeta de crédito o débiro).

Lo que he mejorado ha sido la gestión de mis facturas con unas tablas dinámicas desde LibreOffice. Algo básico pero que me ha facilitado la vida. Os lo cuento en otra ocasión. O no.

Actualización (octubre 2019): si se realizan operaciones intracomunitarias, esto es, facturas a mientros de la EU que están dados de alta (comprobar aquí http://ec.europa.eu/taxation_customs/vies/?locale=es con su número identificador) hace falta presentar el modelo 349 trimestralmente, no llevan IVA. Se incluirá la cantidad en el modelo 303 del IVA trimestral en la casilla 108 “Prestaciones intracomunitarias de servicios localizadas fuera del territorio de aplicación del impuesto (TAI)”. En la casilla 106 “Otras operaciones no sujetas o exentas con derecho a deducción” se indican las que no llevan IVA por otras razones (por ejemplo, las que docentes).

¡Soy profesor! algunas referencias sobre visualización de datos para dinamizar el foro

Este curso he empezado como profesor colaborador de la asignatura de Periodismo de datos para estudiantes del máster de ciencia de datos en la Universitat Oberta de Catalunya (UOC). A principios de año preparamos desde Montera34 (con Alfonso) tres ejercicios prácticos sobre análisis y visualzición de datos: análisis de Twitter, de datos de Airbnb y sobre segregación escolar.

Para dinamizar la clase y dar algunas referencias que he ido viendo estos días he escrito lo siguiente en el foro de la clase:

Recopilo en este hilo algunas referencias que pueden ser de interés e inspiración:

Recopilaciones de proyectos como Fivethirtyeight (https://projects.fivethirtyeight.com/) o The Pudding (https://pudding.cool).

El canal de Telegram de DataLab Madrid (de Medialab Prado) suele tener referencias interesantes: https://t.me/joinchat/AAAAAA3XteJ2mWKCwBRIvQ

Politibot: un bot de Telegram que te manda cada día una temática y (a veces) visualizaciones de datos: https://telegram.me/politi_bot

Dive. Una herramienta relativamente reciente para visualizar datos online (que aún no he probado), de Kevin Hu y César Hidalgo del laboratorio Collective Learning Group de Medialab de MIT https://dive.media.mit.edu/ (código https://github.com/MacroConnections/DIVE-backend/).

Y unos artículos:

Y dos artículos críticos con el Índice de Desarrollo Humano: