Descarga de datos del Ibex 35 (¿y otros?) minuto a minuto en tiempo (casi) real

El código es

library(httr)
library(plyr)
 
base.url <- "http://www.infobolsa.es/1/wtdb/ChartIntraday"
 
res <- POST(base.url,
            body = list(mv = "M SAN",
                        date = "20160518",
                        compressionMult = 1,
                        isSession = 1))
 
dat <- content(res, as = "parsed",
                type = "application/json")
 
dat <- dat$answer$LST$TV$T09
dat <- ldply(dat, unlist)

Los mutatis mutandis, si alguien tiene la gentileza, en los comentarios.

Cómo capturar datos usados en visualizaciones en la red: una alternativa robusta al scraping

Se me pregunta cómo llegué a los datos con los que armé esta entrada. Recuérdese que gráficos como los que aparecen aquí los pinta tu propio navegador con javascript. De alguna manera, el servidor manda datos a tu navegador y, por lo tanto, de alguna manera, esos datos obran en tu poder. Sólo hay que saber capturarlos.

La manera (más bien, una de ellas):

  • Abre la página con Chrome
  • Abre Chrome DevTools (con control-mayúscula-c en algunas máquinas o a través de menús (Tools, etc.) siempre).
  • Entra a la pestaña Network y selecciona XHR.
  • Busca entre los distintos ficheros intercambiados: típicamente, los datos están en el fichero más voluminoso.

Hay variantes (p.e., el navegador puede estar haciendo una petición POST), pero como todos los lectores de este blog menos, que me conste, uno sois gente lista, seguro que dais con la manera.

Transparencia, ley de transparencia y todas esas cosas

Hace un tiempo se aprobó la ley de Transparencia (ver en el BOE). Son muy interesantes el preámbulo y las excepciones, a las que volveré después.

Hace unos días hubo un muy inoportuno debate sobre la conveniencia o no de hacer públicos los resultados de nosequé pruebas de nivel (honestamente, ni sé cuáles son ni me interesan) que realizan los estudiantes de primaria. Pocos nos recordaron que publicar esa información se atiene al espíritu de la ley anterior tal como recoge su preámbulo y que bajo ninguna de las excepciones que contempla podría justificarse su ocultamiento. Pocos nos recordaron, además, que esa información es pública y accesible en países tales como el RU.

Melt y cast en Spark con scala

Trabajar con Spark usando Scala implica renunciar a ese paraíso que son las funciones melt y (d)cast de reshape2.

¿O no?

import org.apache.spark.sql.types.StructField;
import org.apache.spark.sql.types.StructType;
import org.apache.spark.sql.types.StringType;
import org.apache.spark.sql.types.DoubleType;
import org.apache.spark.sql.Row;

/** Create some data **/

val nrows = 20
val origDF = sc.parallelize(1.to(nrows).map(x => (x, math.pow(x,2), math.pow(x,3)))).toDF("id", "cuadrado", "cubo")

/** Melt **/

val ids  = Map("id" -> 0)
val cols = Map("cuadrado" -> 1, "cubo" -> 2)

def melt(x:Row, ids:Map[String, Int] , cols:Map[String, Int]) = {
        var tmp = ids.mapValues(y => x(y))
        for((k,v) <- cols) yield tmp + ("var" -> k, "value" -> x(v))
}

val df = origDF.flatMap(x => melt(x, ids, cols))

val newStructure = StructType( ids.values.map(x => origDF.schema(x)).toList ::: List(StructField("var", StringType), StructField("value", DoubleType)) )
val meltDF = sqlContext.applySchema(df.map(x => Row.fromSeq(x.values.toList)), newStructure)

/** cast **/

val castDF = meltDF.groupBy("id").pivot("var").sum("value")

Tartas con porciones negativas

Aunque te pueda costar imaginarlas, existen:

tarta00

Están sacadas de la página de Red Eléctica (es que hoy he puesto una lavadora) y el gajo que sobresale a las diez es la aportación negativa de la conexión con las Baleares a sistema eléctrico peninsular:

tarta01

¿Por qué —me pregunto— añadirán un uso de la electricidad en una gráfica que, según su título, corresponde a su generación? ¿Quién tuvo la idea de colocar un gajo negativo? ¿Quién tuvo la idea de utilizar tartas? ¿¡Quién, quién, quién!?

Encuestas electorales: medios y sesgos (II)

Aquí quedó pendiente hablar de datos y métodos. Los primeros proceden de El Mundo. Solicité a Marta Ley, una coautora, los datos pero, antes de que contestase que sí (¡gracias!), me di cuenta de que podía obtenerlos solito: basta con capturar la llamada que el javascript local hace al servidor.

¿Métodos? Mejorables: se suaviza la intención de voto (con loess) y se estima la diferencia con un modelo de efectos mixtos, i.e.,

modelo<- lmer(delta ~ 1 + (1 | medio),
    data = misdatos)

¿Caveats? Veo dos: el primero, que loess suaviza teniendo en cuenta también observaciones futuras. Los autores de las encuestas no ven la verdad: solo los resultados de las encuestas previas. Debería haber usado como referencia la mejor predicción basada en observaciones pasadas. El segundo, que los porcentajes de los distintos partidos suman un total. Los sesgos no son independientes y yo los modelo como tales.

Un corpus de textos en español para NLP

Mañana doy clase de NLP en el máster de ciencia de datos de KSchool. Para lo que necesito un corpus decente. Los hay en inglés a tutiplén, pero las hordas de lingüistas hispanoparlantes que se pagan los vicios a costa de tajadas de mi IRPF han sido incapaces de colgar ninguno en español que pueda ubicar y reutilizar.

Necesito una colección de textos en español con ciertas características:

  • Tener un cierto tamaño (¿unas cuantas centenas de ellos?)
  • Que no sean demasiado grandes (¿unos cuantos párrafos?)
  • Ser medianamente homogéneos.
  • Estar bien escritos, sin faltas de ortografía, etc.

Así que he decidido poner en valor otra de esas onerosas reliquias de la cultura analógica y de letras que es el Museo Thyssen; en particular, las descripciones que constan en las fichas de los cuadros. De hecho, corriendo esto: