Análisis de datos 2

Índice

1. Optimización

1.1. generalidades

  • Conceptos
    función objetivo

    función para la que se quiere encontrar

    • su valor óptimo = mejor = máximo o mínimo
    • la solución óptima = combinación de argumentos tales que, si se les aplica la función objetivo, se obtiene su valor óptimo

    téngase en cuenta:

    • pueden existir múltiples soluciones óptimas
    • hay problemas multiobjetivo = interesa obtener óptimos de varias funciones objetivo simultáneamente

    otros nombre de la función objetivo:

    • adaptación/ajuste (fitness) al maximizar en algoritmos genéticos
    • pérdida al minimizar
    solución
    vector con valores para cada variable de la que dependa la función objetivo
    espacio de soluciones
    conjunto de todas las posibles soluciones
    restricción
    condición que ha de cumplir una solución para que se considere válida para calcular el óptimo
    solución factible
    solución que cumple las restricciones
    solución vecina
    solución que está cerca de otra dada, teniendo en cuenta una medida de distancia apropiada dentro del espacio de soluciones
    óptimo local
    solución cuyo valor de la función objetivo es mejor que el valor de la función objetivo en cualquiera de sus vecinos
    • cambiando «es mejor» por «no es peor» se considerarían las soluciones con objetivos iguales a los de sus vecinos
    óptimo global
    solución cuyo valor de la función objetivo es mejor que el valor de la función objetivo en el resto del espacio de soluciones
    • cambiando «es mejor» por «no es peor» se considerarían múltiples soluciones óptimas
  • Muchos paquetes en R

1.2. determinística

1.2.1. irrestricta

1.2.1.1. unidimensional
  • En R: minimizar objetivo en el intervalo entre izquierda y derecha

    optimize (objetivo, c(izquierda, derecha))
    
  • Ejercicio
    • minimizar la función \[f(x) = \left\{\begin{array}{cl} e^\frac{-1}{\mid x-1\mid} & -1<x<4 \\ 10 & \text{otramente} \end{array} \right. \]
    • maximizar \(f(x)=\text{sen}\, x\) con \(10<x<100\) grados sexagesimales
1.2.1.2. multidimensional
  • R

    optim (..., method = "Nelder-Mead", ...) # robusto; por omisión
    optim (..., method = "BGFS", ...)        # rápido
    
  • GSL minimización multidimensional
  • Ejemplo: función de Rosenbroc

    ## ?optim
    fr <- function(x) {   # Rosenbrock Banana function
        x1 <- x[1]
        x2 <- x[2]
        100 * (x2 - x1 * x1)^2 + (1 - x1)^2
    }
    ## "fr" está definida con un solo argumento, para usarla con "optim"
    
    1. dibujar la función mediante persp

      ## definimos otra versión de "fr" pero con 2 argumentos 
      ## para usarla con "outer":
      fr. <- Vectorize (function (x, y) fr (c (x, y)))
      x <- y <- seq(-5,5,.5); persp(x,y,outer(x,y,fr.),col=2,theta=0,phi=0)
      x <- y <- seq(-5,5,.5); persp(x,y,outer(x,y,fr.),col=2,theta=0,phi=-15)
      x <- y <- seq(-5,5,.5); persp(x,y,outer(x,y,fr.),col=2,theta=30,phi=30)
      x <- y <- seq(-5,5,.5); persp(x,y,outer(x,y,fr.),col=2,theta=90,phi=-30)
      

      o bien mediante rgl::surface3d

      install.packages("rgl")
      library(rgl)          # permite girar la gráfica con el ratón
      x <- seq (-5, 5, .5); # si puede tu ordenador, prueba luego
      y <- seq (-5, 5, .5); #  x<-seq(-3,3,.01);y<-seq(-2,5,.01); 
      z <- outer (x, y, fr.)
      ## sigo el ejemplo de ?surface3d
      z <- z / max(abs(z)) * 10 # reescalamos; si no, queda en blanco
      ## se juntan dos paletas para apreciar mejor la parte baja
      nc <- 1000; abajo <- .02 # núm colores y %abajo; prueba 1e5 y 1e-4
      arcoiris <- c (rainbow (nc*abajo), rainbow(nc-nc*abajo)) # 
      ## (z-min(z))/(max(z)-min(z)) reescala entre 0 y 1
      ## * (nc-1) + 1 da un índice entre 1 y nc, la longitud de la paleta
      colores <- arcoiris[(z-min(z))/(max(z)-min(z)) * (nc-1) + 1]
      clear3d()
      # coordenadas, etiquetas y tipo ("n" => nada)
      plot3d(x,y,z,"X","Y","Z","n") # para los ejes
      surface3d(x,y,z, color=colores, front="fill", back="lines")
      
    2. aproximar el mínimo mediante optim

      optim (c(-5,-5), fr)
      optim (c(-5,-5), fr, method="Nelder-Mead") # por omisión, sin gradiente
      optim (c(-5,-5), fr, method="CG")          # gradiente conjugado
      optim (c(-5,-5), fr, method="BFGS")        # cuasiniuton (aproximación de la jesiana)
      
    3. optimizarlo

      print (optim (c(-5,-5), fr)) $ par -> inicio1
      print (optim (inicio1,  fr)) $ par -> inicio2
      print (optim (inicio2,  fr))                   # óptimo
      
  • Ejercicio

    • Sea \(X\) la variable «horas entre averías del aparato de aire acondicionado».
    • Sea la siguiente muestra aleatoria simple para \(X\)

      x <- c (90, 10, 60, 186, 61, 49, 14, 24, 56, 20, 79, 84, 44, 59, 29, 118,
              25, 156, 310, 76, 26, 44, 23, 62, 130, 208, 70, 101, 208)
      
    • Supóngase que \( X \hookrightarrow \gamma \,(\mu;\beta)\) con densidad \[ f_X(x)=\frac {\frac\beta\mu\,\left(\beta\,x\over\mu\right)^{\beta-1}\,e^{-\frac{\beta\,x}{\mu}}} {\Gamma(\beta)} \] donde \(\mu\) es la esperanza de \(X\) y \(\beta\) es el llamado parámetro de forma.
    • Calcúlense estimaciones máximo-verosímiles de \(\mu\) y \(\beta\) dada la muesta x.

    Pasos

    1. Calcular la logverosimilitud \[ n\,\bigl[\log\beta-\log\mu-\log\Gamma(\beta)\bigr] + \sum_{i=1}^n\, (\beta-1)\,\log\frac{\beta\,x_i}{\mu} - \sum_{i=1}^n\,\frac{\beta\,x_i,}{\mu} \]
    2. Implementarla usando
      • function para generar una función de R
      • la función lgamma de R
      • una variable para almacenar el vector \(\left[\beta\,x_i /\mu\right]_{i=1}^n\) y así no calcularlo dos veces
    3. Maximizar la logverosimilitud. Como solución de partida se puede usar que
      • la esperanza de \(X\) vale \(\mu\)
      • la varianza de \(X\) vale \(\mu^2 / \beta\)
      • según el método de los momentos, \(\hat\mu=\bar x\) y \(\hat \beta = (\hat\mu/\hat\sigma)^2 \)
    logvero <- function (parametros)
      { 
          mu   <- parametros[1]
          beta <- parametros[2]
          n    <- length(x)
          aux  <- beta * x / mu
          n * (log(beta) - log(mu) - lgamma(beta)) +
              sum ((beta - 1) * log(aux)) -
              sum (aux)
      }
    
    mean (x)                # estimación de mu
    mean (x) ^ 2 / var (x)  # estimación de beta
    ## representación
    múes  <- seq (70, 100, 1)
    betas <- seq ( 1,   3, 0.1)
    ## usamos "Vectorize" porque "outer" requiere una función vectorizada
    fun   <- Vectorize (function (mu, beta) logvero(c(mu,beta)))
    z     <- outer (múes, betas, fun)
    persp (múes, betas, z, col=2, theta=40, phi=30)
    ## mediante "rgl"
    library (rgl)
    clear3d ()
    plot3d (múes, betas, z, "mu", "beta", "logL", "n")
    surface3d (múes, betas, z)
    ## maximización
    optim (c (83.5, 1.4), logvero, control = list (fnscale = -1))
    optim (c (83.5, 1.4), logvero, control = list (fnscale = -1), method="CG")
    

1.2.2. restringida

1.2.2.1. no lineal
  1. en caja (ortoedro paralelo a ejes)

    El vector de cotas inferiores de las variables se da como argumento "lower" de "optim". Ídem con las cotas superiores y "upper":

    optim (..., method = "L-BFGS-B", lower, upper ...)
    
    • ejemplo artificial: buscar el mínimo de la función "flb" en la caja formada por intervalos desde 2 hasta 4 en cada dimensión:

      ## ejemplo obtenido en la ayuda ?optim
      flb <- function(x)
             { p <- length(x); sum(c(1, rep(4, p-1)) * (x - c(1, x[-p])^2)^2) }
      
      • representar gráficamente mediante persp

        plot3d <- function (fun, xlim, ylim, n = 31, ...)
            ## fun = función de dos argumentos
            ## xlim = c(xmin,xmax)  ylim = c(ymin,ymax)
            ## n = número de puntos en cada dimensión para la malla
        {
          x <- seq (xlim[1], xlim[2], length.out = n)
          y <- seq (ylim[1], ylim[2], length.out = n)
          z <- outer (x, y, fun)
          persp (x, y, z, ...)
        }
        
        ### k = 2
        flb.env <- function (x,y) flb(c(x,y)) # envoltorio para plot3d
        plot3d (Vectorize(flb.env), c(2,4),   c(2,4),   theta=90, phi=-20)
        plot3d (Vectorize(flb.env), c(2,2.2), c(3.8,4), theta=90, phi=-20)
        # el mínimo parece estar con x=2, y=4
        optim (c(3,3), flb, lower=c(2,2), upper=c(4,4), method="L-BFGS-B")
        
      • probar con k <- 3

        ### k = 3
        mejor.x3 <- function (x1,x2) # dados x1 y x2, calcular x3 que minimiza flb
            optimize(function(x3) flb(c(x1,x2,x3)), c(2,4)) $ minimum
        flb.env1 <- function (x1,x2) flb(c(x1, x2, mejor.x3(x1,x2)))
        plot3d (Vectorize(flb.env1), c(2,4),   c(2,4),   theta=90,  phi=-20, col=2)
        plot3d (Vectorize(flb.env1), c(2,2.1), c(2,2.4), theta=-40, phi=0,   col=2)
        ## a ojo, x1 = x2 = 2
        mejor.x2 <- function (x1,x3)
            optimize(function(x2) flb(c(x1,x2,x3)), c(2,4)) $ minimum
        flb.env2 <- function (x1,x3) flb(c(x1, mejor.x2(x1,x3), x3))
        plot3d (Vectorize(flb.env2), c(2,4),   c(2,4),   theta=30, phi=-40, col=3)
        plot3d (Vectorize(flb.env2), c(2,2.2), c(3.8,4), theta=70, phi=0,   col=3)
        ## a ojo, x1 = 2, x3 = 4
        mejor.x1 <- function (x2,x3)
            optimize(function(x1) flb(c(x1,x2,x3)), c(2,4)) $ minimum
        flb.env3 <- function (x2,x3) flb(c(mejor.x1(x2,x3), x2, x3))
        plot3d (Vectorize(flb.env3), c(2,4),   c(2,4),   theta=30,  phi=-40, col=4)
        plot3d (Vectorize(flb.env3), c(2,2.2), c(3.8,4), theta=120, phi=-10, col=4)
        ## a ojo, x2 = 2, x3 = 4
        optim (c(3,3,3), flb, lower=c(2,2,2), upper=c(4,4,4), method="L-BFGS-B")
        ## mínimo en 2.000000 2.109093 4.000000
        
    • ejemplo práctico

      • datos de PISA 2012 en España
      • datos de los tres cebos para estimar exageración: ST62Q04, ST62Q11, ST62Q13
      • https://oecd.org/pisa/data
      • buscar: pisa database 2012 - codebook for student…
      • respuestas de 0 a 4
      • modelo matemático para ajustar la respuesta del alumno \(i\) al ítem \(j\) \[ R_{ij} \approx 4 \cdot C_i \cdot D_j \] donde
        • \(0\leq C_i\leq 1\) es la tendencia a la exageración del alumno \(i\)
        • \(0\leq D_j\leq 1\) es la verosimilez del cebo \(j\), lo real que parece
      • estimar exageración y verosimilez mediante mínimos cuadrados \[ \sum_{i,j}(R_{ij} - 4 \cdot \hat C_i \cdot \hat D_j)^2 \]
      • datos
       OC <- read.table (paste0 ("http://bellman.ciencias.uniovi.es/~carleos/",
                                 "master/manadine/curso2/AnalisisDatos2/apuntes/",
                                 "analisisdatos2/datos/pisa/overclaim.txt"))
      ene <- 1000
      OC0 <- OC[1:ene,]
      nj  <- ncol(OC)
      
      system.time (print (optim (rep (0.5, ene+nj),
                                 function (cd)
                                 {
                                     c <- cd [1 : ene]
                                     d <- cd [(ene+1) : (ene+nj)]
                                     sum ((OC0 - 4 * c %o% d) ^ 2)
                                 },
                                 lower  = 0,
                                 upper  = 1,
                                 method = "L-BFGS-B")))
      
      • alternativa usando media por alumno: \[ \bar R_{i} \approx 4 \cdot C_i \cdot \bar D \] \[ \hat C_i = \frac {\bar R_{i}} {4 \cdot \bar D} \] puede hacerse que la minimización dependa sólo de los \(D_j\)
      d1 <- mean (OC0[["ST62Q04n"]], na.rm=TRUE)
      d2 <- mean (OC0[["ST62Q11n"]], na.rm=TRUE)
      d3 <- mean (OC0[["ST62Q13n"]], na.rm=TRUE)
      dx <- max (d1, d2, d3)
      optim (c (d1, d2, d3) / dx * 0.9,
                   function (d)
                   {
                       c <- apply (OC0, 1, mean) / 4 / mean(d)
                       c <- pmax (0, pmin (1, c))
                       sum ((OC0 - 4 * c %o% d) ^ 2)
                   },
                   method = "L-BFGS-B",
                   lower  = 0,
                   upper  = 1)
      
  2. restricciones lineales

    Optimizar una función sujeta a restricciones de desigualdades lineales. \[ \min f(\vec\theta) \mbox{ sujeta a } U\cdot\vec\theta\geq\vec c \] o sea \[ \min f(\theta_1,...,\theta_n) \mbox{ sujeta a } \sum_{j=1}^n\,u_{ij}\cdot \theta_j \geq c_i\quad \forall\,i=1,...,m \] En R básico existe la función

    constrOptim(theta, f, grad, ui, ci)
    
    • Si el tercer argumento (grad) es NULL, se usa el algoritmo Nelder-Mead. Si no, hay que proporcionar una función gradiente.
    • Las restricciones

      ui %*% theta - ci >= 0
      

      definen la región factible.

    • Para maximizar, úsese la opción

      control = list(fnscale = -1)
      
    • La solución inicial theta debe pertenecer a la región factible.
    ## función banana de Rosenbroc
    fr <- function(x) {   
        x1 <- x[1]
        x2 <- x[2]
        100 * (x2 - x1 * x1)^2 + (1 - x1)^2
    }
    ## usando "optim" como en la sección anterior
    optim (c(3,3), fr, lower = c(2,2), upper = c(4,4), method="L-BFGS-B")
    ## la versión equivalente con "constrOptim"
    constrOptim (c(3,3), fr, NULL,
                 ui = cbind (c(1,-1, 0,0), c(0,0, 1,-1)),
                 ci = c(2,-4, 2,-4))
    

    Ejemplo con restricciones lineales arbitrarias (no de caja) \[ \min b_1^2 + b_2^2 + b_3^2 - 10 b_2\qquad\mbox{sujeta a}\qquad\begin{array}{rrrcr} -4b_1 & -3b_2 & & \geq & -8 \\ 2b_1 & +b_2 & & \geq & 2 \\ & -2b_2 & b_3 & \geq & 0\end{array} \]

    f <- function(b) sum(b^2) - 10*b[2]
    U <- matrix (c(-4,2,0, -3,1,-2, 0,0,1), 3)
    c <- c(-8,2,0)
    constrOptim(c(2,-1,-1), f, NULL, U, c)
    

    Por tanto, se pueden resolver problemas de programación lineal o cuadrática, pero hace falta una solución factible como valor inicial.

1.2.2.2. lineal

\[ \max\quad 0.6x_1+0.5x_2\qquad\mbox{sujeta a}\qquad\begin{array}{rrcr} x_1 & +2x_2 & \leq &1\\ 3x_1 & +x_2 & \leq &2\end{array} \]

  • LP solve
    • desde R

      install.packages("lpSolve")
      library("lpSolve")
      m <- lp ("max", # o "min"
               c(0.6, 0.5),
               rbind(c(1,2),c(3,1)),
               "<=",   # "=" = "=="; "<" = "<="; ">" = ">="
               c(1,2))
      
    • ejercicio: Disponemos de 600 g de fármaco con el que se pueden elaborar pastillas grandes o pequeñas. Cada pastilla grande requiere 40 g de fármaco y se cobra a 2 €. Cada pequeña, 30 g y 1 €. Se necesitan al menos tres pastillas grandes y, como mínimo, el doble de pequeñas que de grandes. ¿Cuántas pastillas se han de elaborar de cada clase para que el beneficio sea máximo? (fuente)
      • planteamiento
        • Variables:
          • \(x\) el número de pastillas grandes
          • \(y\) el número de pastillas pequeñas
        • Objetivo:
          • \(\max 2x + y\)
        • Restricciones:
          • \(40x + 30y \leq 600\)
          • \(x \geq 3\)
          • \(y \geq 2x\)
          • \(x \geq 0\)
          • \(y \geq 0\)
      • solución mediante LpSolve en R

        • la dirección es max
        • consideraremos a las variables en el orden x,y
        • el vector de coeficientes del objetivo es c(2,1)
        • la matriz de coeficientes de las restricciones es

          40 30
           1  0
          -2  1    # porque y > 2x => -2x+y > 0
          

          las restricciones \(x,y\geq0\) se consideran por omisión

        • el vector lado derecho, el de términos independientes, vale c(600,3,0) (el 0 por la inecuación \(-2x+y\geq0\))
        library(lpSolve)
        resultado <- lp("max",
                        c(2, 1), 
                        matrix(c(40,1,-2, 30,0,1), 3),    # ojo a cómo queda la matriz final
                        c("<", ">", ">"),                 # <600, >3, >2x
                        c(600, 3, 0))
        resultado$solution
        
  • GNU linear programming kit

    var x1;
    var x2;
    maximize obj: 0.6 * x1 + 0.5 * x2;
    s.t. c1: x1 + 2 * x2 <= 1;
    s.t. c2: 3 * x1 + x2 <= 2;
    solve;
    display x1, x2;
    end;
    

1.3. heurísticas

1.3.1. Intro y ejemplo

1.3.1.1. metaheurística
  • heurística: algoritmo ad hoc… (quizá sin base teórica)
  • meta: …generalizable
  • problemas complejos (combinatorios)

      n=5 n=10 n=100 n=1000
    n 5 10 100 1.000
    n^2 25 100 10.000 1.000.000
    n^3 125 1.000 1.000.000 1.000.000.000
    2^n 32 1.024 1,27 · 10^30 1,07 · 10^301
    n! 120 3.628.800 9,33 · 10^157 4,02 · 102.567
  • probabilísticos
1.3.1.2. n reinas
  • https://es.wikipedia.org/wiki/Problema_de_las_ocho_reinas
  • compilar el C++ y ejecutarlo

    g++ nreinas.cpp
    ./a.out
    
  • redirigir la salida a un fichero

    ./a.out > salida.txt
    ./a.out | tee salida.txt
    
  • medir cuánto tiempo tarda en ejecutarse

    time ./a.out
    
  • conseguir que pare tras hallar una solución

    time ./a.out | head -n 2
    
  • cambiar el número de reinas; ¿hasta cuántas reinas es posible resolver en un tiempo razonable?
  • hacer gráfica de tiempos en función de número de reinas (ejemplo)
  • traducir el algoritmo a R y ejecutarlo midiendo tiempo

    reinas <- function (k, col, diag45, diag135, nReinas=8)
    {
        if (k==nReinas) stop (paste (col, collapse="-"))
        else for (j in 1:nReinas)
            if (!(j%in%col) && !((j-k)%in%diag45) && !((j+k)%in%diag135))
            {
                reinas (k+1,
                        c (col, j),
                        c (diag45, j-k),
                        c (diag135, j+k),
                        nReinas)
            }
    }
    
    reinas (0, integer(0), integer(0), integer(0))
    
    

1.3.2. Recocido

  • ejemplos
  • algoritmo
  • implementación
    • simplificar el programa de ejemplo eliminando la parte gráfica (solución) e interpretar el algoritmo
  • adaptar el algoritmo para resolver el problema de las reinas;
    • necesitamos:
      • elegir una codificación del problema; por ejemplo, permutaciones;
      • una función para calcular el número de colisiones, dada una permutación;
      • una función para generar una permutación vecina, dada una permutación;
    • en R
    • en R mediante "optim"
  • calcular tiempos y comparar con versión determinística;
  • paralelizar el programa
    • ejercicios previos:
      • comparar tiempos

        Sys.sleep (10)
        system.time (Sys.sleep (10))
        pausa <- function () Sys.sleep(10)
        system.time (pausa ())
        system.time ({pausa (); pausa ()})
        system.time (replicate (2, pausa()))
        pausa <- function (x) Sys.sleep(10)
        system.time (lapply (1:2, pausa))
        system.time (parallel::mclapply (1:2, pausa))
        

        en algunos sistemas operativos mclapply no funciona (no ejecuta en paralelo sino secuencialmente); en tales casos hay que emplear un procedimiento más latoso basado en las funciones makeCluster, parLapply y stopCluster; véanse este listado y el ejercicio 11 (el último) de este examen

      • recordar lapply

        • mtcars
          • Crear una lista que contenga, el R2 y los coeficientes de la regresión de la variable MPG de MTCARS frente a la variable WT.
          • Crear una lista que contenga, para cada variable de MTCARS, el R2 y los coeficientes de la regresión de la variable MPG frente a la susodicha.
          • Crear una lista que contenga, para cada variable de MTCARS, el R2 y la matriz con los coeficientes y sus errores típicos, t-valores y p-valores.
        • recocido
          • definir una función recocido que ejecute un recocido y devuelva información de interés para el problema
          • usar lapply para guardar en una lista los resultados de varios recocidos
          • definir una función que combine los dos pasos anteriores
            • entrada: número de recocidos que ejecutar
            • salida: la lista creada por lapply

        (soluciones)

    • cargar la biblioteca (distribuida con R básico): library(parallel)
    • detectar número de hilos/procesos en paralelo posibles: detectCores()
    • probar mclapply
      • ejemplo trivial
        • generar un millón de muestras de tamaño cien de una población gausiana y calcular la media muestral en cada una; guardar sólo la desviación típica de dichas medias muestrales

          dtmediamuestral <- function (i) sd (replicate (1e6, mean (rnorm (100, 170, 15))))
          # la "i" se descarta; es para el "mclapply"
          
        • realizar dicha operación en paralelo para varios hilos y comparar tiempos de ejecución

          system.time (mclapply (1:4, dtmediamuestral))
          
        • si los tiempos no concuerdan con lo esperado, recoger la basura antes de la medición

          gc (); system.time (mclapply (1:4, dtmediamuestral))
          
    • probar mcparallel
      • en este caso, mclapply viene mal porque espera a que se acaben todos los hilos
      • ejemplo de uso con las reinas
  • ejercicio: aplicar recocido para ruta más corta entre ciudades de "eurodist"

1.3.3. Enjambre

1.3.4. Hormigas

1.3.5. Genéticos

  • intro - evolución y selección
  • esquema (wikipedia)
    • inicialización: n individuos / cromosomas
    • evaluación: función objetivo / aptitud / adaptación
    • mutación (permite explorar el entorno)
    • recombinación / meyosis / cópula
    • selección
  • n reinas
    • implementar:
      • población de 100 individuos
      • torneo con 5 candidatos
      • cruzar los 2 mejores para crear 2 vástagos
      • realizar 1 mutación en cada vástago (con probabilidad pMut en cada uno)
      • seleccionar los 100 mejores de los 102 individuos resultantes
      • hasta ahora
    • probar una biblioteca de R (genalg, GA…)
    • mejorar la evaluación (p.ej. este artículo)
  • hibridación

1.3.6. Lenguajes compilados

1.3.7. Ejercicios

1.3.7.1. Selección de reproductores

En producción animal es necesario controlar la consanguinidad de los futuros reproductores. Esta matriz indica la relación de parentesco entre parejas de 215 individuos de una generación.

  1. Se pretende seleccionar 1 lote de 90 individuos de forma que la media de las relaciones en el lote sea lo menor posible.
  2. Se pretende seleccionar 1 lote de 90 individuos de forma que, en primer lugar, la mediana de las relaciones en el lote sea lo menor posible y, en segundo lugar, la varianza de las relaciones en los lotes sea lo menor posible.
  3. Se pretende seleccionar 3 lotes de 30 individuos cada uno, de forma que, en primer lugar, el máximo de las relaciones en los lotes sea lo menor posible y, en segundo lugar, que la media de las relaciones en los lotes sea lo menor posible.

Resuelve cada situación.

1.3.7.2. Selección de marcadores
  • Datos en este directorio
    • mapa: cromosoma y posición
    • genotipos:
      • ID del individuo
      • alelos (a,A)
        • 0 = homocigoto (aa)
        • 1 = heterocigoto (aA)
        • 2 = homocigoto (AA)
        • 5 = desconocido
  • Objetivo
    • Escoger 50.000 marcadores
    • Maximizar distancia entre ellos (suma de distancias cuadráticas)
    • Maximizar heterocigosis esperada

1.3.8. Programación genética

2. Macrodatos

2.1. formatos textuales

Los formatos textuales tienen la ventaja de que pueden ser examinados directamente por un humano, sin necesidad de un programa específico (le bastaría un programa genérico como un editor de texto).

2.1.1. tabulares

2.1.1.1. campos separados por un delimitador único (dsv)
  • registro = renglón
  • campos separados por coma (csv), punto-y-coma (csv2), tabulador (tsv), tubo "|" (psv)
  • habitualmente llamados CSV todos ellos
read.csv
read.csv2
read.delim
read.delim2
  1. ejercicio 1
    • cargar estos datos
    • comprobar si alguna variable influye en "proportion"
  2. ejercicio 2
    • cargar estos datos
    • crea una variable "nombre.completo" que contenga sólo mayúsculas
    • crea una variable "NombreCompleto" que esté en minúsculas, salvo las iniciales
  3. ejercicio 3
    • cargar estos datos
    • hacer análisis de componentes principales sobre "ce", "altp", "anchp"
    • hallar influencia de "cul" y "edadm" en "ce", "altp" y "anchp"
  4. ejercicio 4
    • cargar estos datos
    • crear variable "familia.de.curso" con los tres primeros caracteres de "CodEspecialidad"
    • hacer una tabla de frecuencias de familias por cada mes
    • hacer análisis de correspondencias con esa tabla
  5. ejercicio 5
    • cargar estos datos
    • calcular la variable "edad" actual
    • crear una tabla con "id", "edad", "sexo", "sit.laboral.ultima", "numero.de.registros"
    • crear una tabla con "id", "edad", "sexo", "sit.laboral.ultima", "numero.de.registros", "tiempo.trabajando" (trabaja si situación=1)
    • relacionar las tres últimas variables con "edad" y "sexo"
  6. ejercicio 6
    • cargar estos datos
    • el segundo campo es el identificador (ID)
    • los campos que contienen ACGT son genotipos
    • hallar las frecuencias de ACGT en total
      • solución 1 (Bash)

        cat genotipos | recode cl..data | cut -d' ' -f7- | tr ' ' '\n' | sort | uniq -c
        
      • solución 2 (cut + R)

        resultados <- sapply (seq (7, 1160007, 10000),
                              function (primeracolumna)
                              {
                               system (paste0 ("cut -d' ' -f ", primeracolumna, "-", primeracolumna+9999,
                                               " genotipos > genotipos.tmp"))
                               table (c (as.matrix (read.table ("genotipos.tmp"))))
                              })
        resultados <- c (resultados, list ({system ("cut -d' ' -f1170007-1178858 genotipos > genotipos.tmp");
                                            table (c (as.matrix (read.table ("genotipos.tmp"))))}))
        ### queda combinar los resultados
        ## opción 1
        n0 <- nA <- nC <- nG <- nT <- nTRUE <- 0
        for (i in 1:118) {
          ## n0 <- n0 + ifelse (is.na (resultados[[i]]["0"]), 0, resultados[[i]]["0"])
          ## n0 <- n0 + if (is.na (resultados[[i]]["0"])) 0 else resultados[[i]]["0"]
          ## if (!is.na (resultados[[i]]["0"])) n0 <- n0 + resultados[[i]]["0"]
          n0    <- sum (n0, resultados[[i]]["0"],    na.rm=TRUE)
          nA    <- sum (n0, resultados[[i]]["A"],    na.rm=TRUE)
          nC    <- sum (n0, resultados[[i]]["C"],    na.rm=TRUE)
          nG    <- sum (n0, resultados[[i]]["G"],    na.rm=TRUE)
          nT    <- sum (n0, resultados[[i]]["T"],    na.rm=TRUE)
          nTRUE <- sum (n0, resultados[[i]]["TRUE"], na.rm=TRUE)
        }
        ## opción 2
        apply (do.call (rbind, lapply (resultados,
                                       function (x) x[c("0","A","C","G","T","TRUE")])),
               2, sum, na.rm=TRUE)
        
    • hallar las frecuencias de ACGT para cada ID y comprobar si existen tendencias respecto al número ID
      • opción «casi todo R»

        numero.de.renglones <- as.numeric (strsplit (system ("wc -l genotipos", intern=TRUE), " ") [[1]] [1])
        resultados <- lapply (1 : numero.de.renglones,
           function (i)
           { recuentos <- system (paste0 ("head -n", i, " genotipos | tail -n 1 | ",
                                          "recode cl..data | cut -d' ' -f7- | tr ' ' '\n' | sort | uniq -c"),
                                  intern = TRUE)
             recuentos <- strsplit (recuentos, " +")  # crea p.ej.: "" "287" "T"
             resultado <- as.numeric (sapply (recuentos, function (x) x[2]))
             names (resultado) <-     sapply (recuentos, function (x) x[3])
             resultado
           })
        resultados <- as.data.frame (do.call (rbind, resultados))
        resultados$id <- as.numeric (system ("cut -d' ' -f2 genotipos", intern=TRUE))
        
      • opción «casi todo Bash»

        for i in {1..23}; do head -n$i genotipos | tail -n1 | awk '{ORS=" id ";print $2}';
                             head -n$i genotipos | tail -n1 | recode cl..data |
                               cut -d' ' -f7- | tr ' ' '\n' | sort | uniq -c | tr '\n' ' '; echo; done > tabla.txt
        
2.1.1.2. campos separados por espacio
read.table
  1. ejercicio 1
  2. ejercicio 2
    • cargar estos datos
    • relacionar peso y día de la semana de nacimiento
2.1.1.3. ancho fijo
read.fwf
  1. ejercicio 1
    • INE.es -> productos y servicios -> información estadística -> ficheros de microdatos
    • demografía y población -> encuesta nacional de inmigrantes
    • cargar TODOS los datos en R
    • hacer gráfica de HAESP (habla español) usando etiquetas apropiadas
    • hacer gráfica de idiomas hablados (IDIO1 a IDIO6) usando etiquetas apropiadas
    • pista 1
    • pista 2
    • pista 3
    • pista 4
    • pista 5
    • extra: automatizarlo
    • pista 6
  2. ejercicio 2
    • INE.es -> productos y servicios -> información estadística -> ficheros de microdatos -> demografía y población
    • censos de población -> ( [diseño de registro] y [fichero de macrodatos] )
    • hallar las cinco provincias con mayor (y las cinco con menor) número medio de hijos por familia y las cinco con mayor (y menor) porcentaje de familias numerosas

2.1.2. ramificados árboles grafos

2.1.2.1. sex sexp s-expresiones
  1. p-lista

    El nombre viene de «lista de propiedades».

    (nombre Fulano edad 44 aficiones (leer cantar viajar) peso 88)
    

    Equivaldría a la expresión de R:

    list (nombre="Fulano", edad=44, aficiones=c("leer","cantar","viajar"), peso=88)
    
  2. a-lista

    El nombre viene de «lista de asociaciones». Su uso es similar al de las p-listas.

    ((nombre Fulano) (edad 44) (aficiones leer cantar viajar) (peso 88))
    

    Con pretty-print:

    ((nombre Fulano)
      (edad 44)
      (aficiones leer
                 cantar
                 viajar)
      (peso 88))
    
  3. pueden expresar programas

    La siguiente expresión en R:

    (sqrt(30*pi) - 1) / (3 + 8 * log(a/b) / (1 + 2 + 3 + 4 + 5 + 6))
    

    se expresaría así, por ejemplo:

    (/ (- (sqrt (* 30 pi)))
       (/ (+ 3 8 (log (/ a b)))
          (+ 1 2 3 4 5 6)))
    

    Las siguientes instrucciones de control en R:

    for (i in 0:9)
      if (i %% 2)
        print (paste (i, "es impar"))
      else print (paste (i, "es par"))
    

    se expresarían así, por ejemplo:

    (dotimes (i 10)
        (if (oddp i)
            (print (list i 'es 'impar))
            (print (list i 'es 'par))))
    

    En R se puede obtener el árbol asociado a un programa, pero es más complejo:

    e <- expression ( (2+3)/sqrt(5) )
    as.list(e[[1]])
    as.list(e[[1]][[2]])
    as.list(e[[1]][[2]][[2]])
    

    Nótese que el operador paréntesis introduce un nivel adicional. Otro ejemplo con instrucción de control:

    e <- expression (for (i in 1:10) print (i**2))
    as.list (e[[1]])
    as.list (e[[1]][[3]])
    as.list (e[[1]][[4]][[2]])
    
2.1.2.2. xml
  • ejemplo de árbol

    <individuo>
      <nombre>Fulano</nombre>
      <edad>44</edad>
      <aficiones>
        <aficion>leer</aficion>
        <aficion>cantar</aficion>
        <aficion>viajar</aficion>
      </aficiones>
      <peso>88</peso>
    </individuo>
    
  • en R

    library (XML)
    xmlParse("individuo.xml") -> x
    xmlToList (x) -> l
    
  • minería de internet (web scraping)
    • en R
    • con navegadores textuales (lynx, links, elinks, w3m, eww…)
      • permiten obtener texto plano a partir de una página ueb, p.ej.

        w3m -dump -cols 300 'https://es.wikipedia.org/wiki/Anexo:Pa%C3%ADses_por_PIB_(nominal)_per_c%C3%A1pita' > pagina.txt
        less -S pagina.txt
        

        ese texto puede tratarse luego con un editor para crear un fichero legible mediante read.fwf en R

      • no soportan javascript (excepto browsh o edbrowse)
    • con navegadores para ciegos
      • edbrowse
      • navegación fácilmente automatizable
  1. ejercicio 1
  2. ejercicio 2
  3. ejercicio 3
    • Importar como lista de R la página Titulares del dUO (htmlParse y xmlToList)

      • HTML
      <html>
        <head><title>dUO</title></head>
        <body>
          <h1>Diario de la U.O.</h1>
          <h2>Actos</h2>
          <ul>
            <li>Concurso <a href="http://bellman.ciencias.uniovi.es/incubadora">Incubadora</a>.
            <li>Conferencia.
          </ul>
          <h2>Avisos</h2>
          <ul>
            <li>Comienza el <strong>MANADINE</strong>.
            <li>Pérdida de título.
          </ul>
        </body>
      </html>
      
    • Navegar la lista e intentar obtener la lista de novedades (de actos, por ejemplo)
    • Intentar lo mismo accediendo al enlace RSS
2.1.2.3. json
  • ejemplo de árbol
{
  nombre: "Fulano",
  edad: 44,
  aficiones: ["leer", "cantar", "viajar"],
  peso: 88
}

En R:

### https://docs.mongodb.com/manual/tutorial/query-documents/
## db.inventory.insertMany([
##     { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
##     { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },
##     { item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
##     { item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
##     { item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }
##     ]);
d <- list (
    list (item = "journal",  qty =  25, size = list (s = 320,              uom = "cc"), status = "A" ),
    list (item = "notebook", qty =  50, size = list (h = 8.5,   w = 11,    uom = "in"), status = "A" ),
    list (item = "paper",    qty = 100, size = list (h = 8.5,   w = 11,    uom = "in"), status = "D" ),
    list (item = "planner",  qty =  75, size = list (h = 22.85, w = 30,    uom = "cm"), status = "D" ),
    list (item = "postcard", qty =  45, size = list (h = 10,    w = 15.25, uom = "cm"), status = "A" )
)
library (jsonlite)
j <- toJSON (d)                         # trasformar a JSON
j <- toJSON (d, pretty = TRUE)          # idem humanolegible
cat (j, file="/tmp/ejemplo.json")       # guardar en fichero
dj <- fromJSON (j)                      # trasformar de JSON a dataframe
dim (dj)                                # ojo: dataframes anidados y con listas
dj$size                                 # dataframe dentro de dj
DJ <- flatten (dj)                      # intenta trasformar a dataframe normal
dim (DJ)
DJ[[1]]                                 # lista en vez de vector
## hace falta trasformar los NULL en NA para obtener un dataframe normal
D <- data.frame (lapply (DJ, function (v) unlist (ifelse (sapply(v,is.null), NA, v))))
## uso lapply en vez de sapply para que no genere una matriz (que son homogéneas en tipo de datos)

ejercicios

2.2. formatos binarios

Los formatos binarios permiten acceder a la documentación almacenada en el disco duro de una manera mucho más rápida que los formatos textuales. Por tanto, son convenientes para almacenar datos que no caben en la memoria del ordenador.

2.2.1. tabulares SQL

Un banco de datos relacional (siglas en inglés: RDBM) contiene una o varias tablas (rectangulares, como dataframes). Dos tablas pueden estar relacionadas a través de un campo clave.

+----------+     +---------------+     +--------------------+
|  cursos  |     |    perfil     |     |    municipios      |
+----------+     +---------------+     +--------------------+
| título   |  +--* identificador |  +--* nombreDelMunicipio |
| IDalumno *--+  | edad          |  |  | partidoJudicial    |
| sector   |     | sexo          |  |  +--------------------+
+----------+     | municipio     *--+
                 +---------------+

Con esas relaciones podríamos obtener la relación entre sector profesional al que se asocian los cursos y el partido judicial al que pertenece el alumno.

2.2.1.1. gestores populares de BB.DD.
  1. PostgreSQL
    • página ueb
    • características técnicas avanzadas
      • muy bien programada
      • fiable y tolerante a fallos
      • extensible
      • portable
  2. MySQL MariaDB
    • MySQL
    • MariaDB
    • muy rápida
    • es la M de LAMP: Linux + Apache + MySQL + Perl ó PHP ó Python
    • usada en Wikipedia, Google, Wordpress.com…
  3. SQLite
    • página ueb
    • muy sencilla y cómoda (no requiere crear usuarios)
    • extendidísima (incluida en Android, Firefox…)
    apt install r-cran-rsqlite
    
2.2.1.2. lenguaje SQL
  1. comparado con R
    R postgresql
    (listar databases) \l
    ls() ; DBI::dbListTables() \d
    sapply(tabla,class) SELECT * from tabla WHERE FALSE; \gdesc
    R sql
    tabla <- read.csv("/tmp/fichero.csv") CREATE TABLE tabla (col1 integer, col2 varchar(100), col3 bigint);
      COPY tabla FROM '/tmp/fichero.csv' WITH NULL AS '' CSV HEADER;
    write.csv(tabla[1:5,], "/tmp/fichero.csv") \copy (SELECT * FROM tabla LIMIT 5) TO '/tmp/fichero.csv' WITH NULL AS 'NA' CSV HEADER;
    rm(tabla) DROP TABLE tabla;
    names(tabla) SELECT * from tabla WHERE FALSE;
    nrows(tabla) SELECT COUNT(*) FROM tabla;
    (rápido pero aproximado) EXPLAIN SELECT * FROM tabla;
    tabla$columna SELECT columna FROM tabla;
    tabla[c("col1","col2")] SELECT col1,col2 FROM tabla;
    subset(tabla,,c(col1,col2))  
    tabla SELECT * FROM tabla;
    tabla[1:n,] SELECT * FROM tabla LIMIT n;
    tabla[tabla$columna==valor,] SELECT * FROM tabla WHERE columna = valor;
    tabla[which(tabla$columna==valor),]  
    select(tabla, columna==valor)  
    == =
    != <> o bien !=
    < > <= >= < > <= >=
    is.na(columna) ; !is.na(columna) columna IS NULL ; columna IS NOT NULL
    barra vertical OR
    & AND
    ! NOT
    %in% c(…,…) IN (…,…)
    columna >= alfa & columna <= alfa BETWEEN alfa AND beta
    grep ("UNIOVI$", columna) columna LIKE '%UNIOVI'
    grep ("^UNI", columna) columna LIKE 'UNI%'
    grep ("UNI", columna) columna LIKE '%UNI%'
    grep("^UO.*ES", columna) columna LIKE 'UO%ES'
    tabla[order(tabla$columna),] SELECT * FROM tabla ORDER BY columna;
    tabla[order(tabla$col1,tabla$col2),] SELECT * FROM tabla ORDER BY col1,col2;
    tabla[order(tabla$col1,tabla$col2),decreasing=TRUE] SELECT * FROM tabla ORDER BY columna DESC;
    cbind(tabla$col1,tabla$col2/tabla$col3) SELECT col1,col2/col3 FROM tabla;
    with(tabla, cbind(col1,col2/col3))  
    mean(tabla$columna,na.rm=TRUE) SELECT AVG(columna) FROM tabla;
    sum(!is.na(tabla$columna),na.rm=TRUE) SELECT COUNT(columna) FROM tabla;
    min(tabla$columna,na.rm=TRUE) SELECT MIN(columna) FROM tabla;
    max(tabla$columna,na.rm=TRUE) SELECT MAX(columna) FROM tabla;
    sum(tabla$columna,na.rm=TRUE) SELECT SUM(columna) FROM tabla;
    unique(tabla$columna) SELECT DISTINCT columna FROM tabla;
    length(unique(tabla$columna)) SELECT COUNT(DISTINCT(columna)) FROM tabla;
    by(tabla$col1, tabla$col2, mean) SELECT col1,AVG(col2) FROM tabla GROUP BY col1;
    by(tabla$col1, tabla$col2, mean) SELECT col1,AVG(col2) FROM tabla GROUP BY 1;
    Filter (function(x)x>50, by(tabla$col1, tabla$col2, mean) SELECT col1,AVG(col2) FROM tabla GROUP BY 1 HAVING AVG(col2)>50;
    with(tabla, cbind(nombre,precio,oferta=ifelse(precio<10,"sí","no"))) SELECT nombre,precio,CASE WHEN precio<10 THEN 'sí' ELSE 'no' END AS oferta FROM tabla
    tabla1 [tabla1$col1 %in% tabla2$col1 , ] SELECT * FROM tabla1 WHERE col1 IN (SELECT col1 FROM tabla2);
    merge(tabla1, tabla2, by.x="id", by.y="codigo") SELECT * FROM tabla1,tabla2 WHERE tabla1.id = tabla2.codigo;
    merge(tabla1, tabla2, by.x="id", by.y="codigo") SELECT * FROM tabla1 INNER JOIN tabla2 ON tabla1.id = tabla2.codigo;
    merge(tabla1, tabla2, by.x="id", by.y="codigo", all.x=TRUE) SELECT * FROM tabla1 LEFT JOIN tabla2 ON tabla1.id = tabla2.codigo;
    merge(tabla1, tabla2, by.x="id", by.y="codigo", all.y=TRUE) SELECT * FROM tabla1 RIGHT JOIN tabla2 ON tabla1.id = tabla2.codigo;
    merge(tabla1, tabla2, by.x="id", by.y="codigo", all=TRUE) SELECT * FROM tabla1 FULL JOIN tabla2 ON tabla1.id = tabla2.codigo;
  2. crear tablas
    create table tablavacas (id integer, peso double, nombre text);
    insert into tablavacas (123290,295,'ESTRELLA');
    
    1. mysql

      Lo habitual es importar desde fuera:

      mysqlimport -u usuario -p --delete --local --fields-terminated-by=';' test vacas.csv
      
    2. postgresql
      \c ejemplos
      create table empleo_contratos (NumCorrelativo integer, tipoContrato integer,
      fechaInicio bigint, fechaFin bigint, ocupacion integer,
      ActEconomica integer);
      create table empleo_cursos (Numcorrelativo integer, FechaInicio varchar(15),
      CodEspecialidad varchar(15), DenominacionEspecialidad varchar(200));
      create table empleo_perfil (NumCorrelativo integer, NivelFormativo integer,
      SitLaboralUltima varchar(10), FechaSitLaboralUltima bigint,
      FechaNacimiento bigint, Sexo integer, Municipio integer,
      SitLaboralHistórico varchar(10), FechaInicioSitLaboralHistórico bigint);
      copy empleo_contratos from '/tmp/empleo_contratos.csv'
            with csv header null as ' ';
      copy empleo_cursos from '/tmp/empleo_cursos.csv'
            with csv header null as ' ';
      copy empleo_perfil from '/tmp/empleo_perfil.csv'
            with csv header null as '';
      
    3. sqlite

      EJERCICIO

      • con los datos de empleabilidad de aquí, crear tres tablas mediante SQLite3

        bash> sqlite3
        sqlite> .open empleo.db
        sqlite> .mode csv
        sqlite> .import empleo_cursos.csv cursos
        sqlite> .import empleo_contratos.csv contratos
        sqlite> .import empleo_perfil.csv perfil
        sqlite> .tables
        sqlite> .schema perfil
        sqlite> .quit
        
  3. consultas
    select * from tablavacas;
    select id,peso/edad from tablavacas;
    select id,peso/edad as crecimiento from tablavacas;
    select * where peso > 10 and edad < 500;
    select id,peso/edad as crecimiento from tablavacas having crecimiento > 1;
    

    Comparando cadenas:

    • % representa cero o algún carácter
    • _ representa exactamente un carácter cualquiera

    Agregación:

    select avg(peso) as pesomedio from tablavacas group by genotipo;
    

    Otros agregadores: count(), min(), max(), var_samp(), stddev_samp() Por ejemplo:

    select genotipo,count(*) from tablavacas group by genotipo;
    select sexo,genotipo,count(*) from tablavacas group by sexo,genotipo;
    select sexo,count(*),avg(peso) as media,stddev_samp(peso) as dt
      from tablavacas group by genotipo;
    

    EJERCICIO

    bash> sqlite3
    sqlite> .open empleo.db
    sqlite> .tables
    sqlite> .schema perfil
    sqlite> select count(*) from perfil;
    sqlite> select * from perfil limit 20;
    sqlite> select * from perfil limit 20 offset 100;
    sqlite> select * from perfil where NumCorrelativo=2;
    sqlite> select perfil.*,cursos.*,contratos.* from perfil,cursos,contratos where perfil.NumCorrelativo=contratos.NumCorrelativo and perfil.NumCorrelativo=cursos.Numcorrelativo limit 5;
    sqlite> .headers on
    sqlite> .mode csv
    sqlite> .output empleo_todo.csv
    sqlite> select perfil.*,cursos.*,contratos.* from perfil,cursos,contratos where perfil.NumCorrelativo=contratos.NumCorrelativo and perfil.NumCorrelativo=cursos.Numcorrelativo;
    sqlite> .output stdout
    

    primeros campos:

    select * from pragma_table_info('pisa') limit 5;
    select cnt,count(*) from pisa group by CNT;
    
  4. varias tablas

    Juntar varias tablas, teniendo una columna idvaca de enlace:

    select facilidadparto from partos join tablavacas using(idvaca);
    

    Se usa LEFT JOIN para mantener los registros de la primera tabla, aunque no haya correspondencia con la segunda. EJERCICIO

    bash> sqlite3 empleo.db
    sqlite> select count(*) from perfil,cursos;
    29787628
    sqlite> select count(*) from perfil,cursos where perfil.NumCorrelativo=cursos.Numcorrelativo;
    2510
    sqlite> select count(*) from perfil join cursos where perfil.NumCorrelativo=cursos.Numcorrelativo;
    2510
    sqlite> select count(*) from perfil left join cursos on perfil.NumCorrelativo=cursos.Numcorrelativo;
    43350
    
  5. modificar
    update tablavacas set peso=198,alzada=150 where id=123123;
    delete from tablavacas where id=123123;
    drop table tablavacas
    drop database aseava;
    

2.2.2. ramificados NoSQL

2.2.2.1. MongoDB
  1. características
    • BSON: JSON binarizado
    • cualquier contenido (p.ej. vídeos)
    • optimizada; sólo disponible para arquitecturas i386 y amd64
  2. ejemplo

    Instalación en Debian, Ubuntu, etcétera:

    sudo apt install mongodb
    

    Importaremos los datos de R mtcars, suponiendo que han sido exportados a un fichero de texto CSV:

    mongoimport --file mtcars.csv --type csv --headerline
    

    En versiones antiguas, hay que añadir una opción --collection, por ejemplo:

    mongoimport --file mtcars.csv --type csv --headerline --collection mtcars
    

    Si mtcars estuviera en formato JSON, usado por omisión por MongoDB:

    mongoimport --file mtcars.json
    

    Las consultas pueden hacerse directamente desde el cliente de MongoDB:

    mongo
    > show collections
    > db.mtcars.find({am: 0}).count()
    

    EJERCICIO

    • Importar en MongoDB los datos de empleo (ojo a la opción «–jsonArray» de «mongodb»).
    • Hallar cuántos varones y mujeres hay.

Autor: Carlos Enrique Carleos Artime

Created: 2024-11-05 mar 11:41

Validate