Programación

¿Es Cobol tan robusto como cuentan?

El diario El País se ha hecho eco de algo que no hace falta ser particularmente perspicaz para advertir. Y no me refiero tanto a la tesis global del artículo como a este parrafito,

[…] ambos opinan que la primera disfunción está en la Universidad. “Estamos hablando de trabajadores sobreeducados que, sin embargo, carecen de las habilidades necesarias para desempeñar el trabajo”. Este contrasentido está en relación directa “con el tipo de docencia impartida en las Universidades”, añaden. “Los graduados se quejan de que los modos de enseñanza se siguen basando en clases magistrales, dándole poca importancia a las clases prácticas a la adquisición directa de experiencia laboral”. Esta formación academicista, exenta de habilidades prácticas, es el factor que más influye, según el estudio, […]

La función monotonic de PROC SQL de SAS

Previamente he hablado en este blog de las ventajas que ofrece PROC SQL en SAS sobre otros métodos más propiamente SAS de realizar ciertas manipulaciones de datos. Existen no obstante cierto tipo de manipulaciones que exigen pasos data: gran parte de las que hacen uso de la variable automática n.

No obstante, existe una función no documentada de SAS que permite implementar con SQL muchas operaciones de este tipo: monotonic.

Comportamiento inesperado... ¿sólo por mí?

R

El otro día, bajo el encabezamiento Unexpected behabiour of min, tapply and POSIXct/POSIXlt classes?, mandé a la lista de desarrolladores de R el siguiente pedazo de código:

before <- Sys.time()
Sys.sleep( 1 )
now1 <- now2 <- Sys.time()

my.times <- c( before,  now1, now2
class( my.times )                     ## [1] "POSIXct" "POSIXt
min( my.times )                       ## [1] "2010-10-28 18:52:17 CEST"

### So far, so good... but:

my.period <- c( "a", "b", "b" )
tapply( my.times, my.period, min )

##          a          b
## 1288284737 1288284780

## Where did my POSIXct class go?

my.times.lt <- as.POSIXlt( my.times
min( my.times.lt )                    ## [1] "2010-10-28 18:52:17 CEST"; good

tapply( my.times.lt, my.period, min )

# $a
# [1] 17.449
#
# $b
# [1] 52
#
# Mensajes de aviso perdidos
# In ansmat[index] <- ans :
#   número de items para para sustituir no es un múltiplo de la
# longitud del reemplazo
#
# ¿?  :(

Invito a mis lectores a lo siguiente:

¿Siete lenguajes de programación emergentes?

R

Hace un par de días apareció un artículo en InfoWorld en el que se enumeraban siete lenguajes de programación emergentes. Parece que por emergentes ha de entenderse cada vez más extendidos en la empresa. Como R hacía parte del rol, comencé alegrándome. Después me surgieron dos elementos de sospecha.

Véase la lista de los siete lenguajes seleccionados:

  • Python, un viejo conocido.
  • Ruby
  • Matlab
  • JavaScript, que está gozando de una segunda primavera gracias a AJAX y demás
  • R, ¡cómo no!
  • Erlang (vale la pena echarle un vistazo: tiene cosas la mar de interesantes)
  • Cobol (¡ufa!)
  • Extensiones CUDA

Los elementos de sospecha son dos (ni tres ni siete):

Rutinas de C en R

R

[Nota: esta entrada está totalmente desactualizada y la mantengo en en blog por una mezcla de sentimentalismo y fidelidad a la “memoria histórica”; el interesado en cómo interconectar R y C (o C++) hoy hará bien en buscar en otra parte.]

Esta entrada que ahora hago es un pequeño tutorial que publiqué en mi primera página de internet a principios de siglo, cuando todavía usaba Windows regularmente. Es posible que gran parte de lo que en ella cuente esté ya mandado a recoger. No obstante, tampoco hace tanto, eché mano de lo que en ella había dejado escrito para ver cómo migrar a Windows algo que había hecho en Linux y… todavía funcionó.

Una tarea para mis lectores: ¡resultados!

R

El otro día dejé planteada una tarea para mis lectores (que han sido menos diligentes que yo, incluso). Trataba de una comparación entre varios métodos para acceder a diccionarios (o hashes) de datos desde R para tratar de identificar el más eficiente en términos de velocidad de acceso.

Acá van los resultados:

n <- 100000
dat <- data.frame( id = paste( "id", 1:n, sep = "_" ),
    valor = rnorm( n ), stringsAsFactors = F )

n.sample <- 20000
seleccion <- sample( dat$id, n.sample )

### Con vectores:
system.time( res <- sapply( seleccion,
    function( x ) dat$valor[ dat$id == seleccion ] ) )

#  user  system elapsed
# 84.79    5.24   90.14

### Con listas:
mi.lista <- sapply( dat$valor, I, simplify = F )
names( mi.lista ) <- dat$id
system.time( res <- sapply( seleccion, function( x ) mi.lista[[x]] ) )

#  user  system elapsed
# 19.15    0.00   19.20

### Con entornos:
mi.entorno.0 <- new.env()
invisible( sapply( 1:n, function(i)
  assign( dat$id[i], dat$valor[i], env = mi.entorno.0 ) ) )
system.time( res <- sapply( seleccion, function( x ) mi.entorno.0[[x]] ) )

#  user  system elapsed
# 67.89    0.03   68.06

### Con el paquete data.table:
require( data.table )
tmp.dat <- dat
tmp.dat$id <- factor( tmp.dat$id )
mi.data.table <- data.table( tmp.dat )
setkey( mi.data.table, id )
system.time( res <- sapply( seleccion,
  function( x ) mi.data.table[ J(x) ]$valor ) )

#   user  system elapsed
# 371.07   25.91  400.39

### Con hashes:
mi.entorno.1 <- new.env( hash = T )
invisible( sapply( 1:n, function(i)
  assign( dat$id[i], dat$valor[i], env = mi.entorno.1 ) ) )
system.time( res <- sapply( seleccion,
    function( x ) mi.entorno.1[[x]] ) )

#  user  system elapsed
#  0.14    0.00    0.14

Los números son tan concluyentes que me excusan de la necesidad de ofrecer explicaciones y distingos. Aunque para que mis lectores no tengan que ir subiendo y bajando por la entrada para realizar comparaciones, los resumo en un gráfico:

El paquete multicore de R

R

Tengo acceso a una máquina que, aunque anda un poco corta de memoria, cuenta con ocho CPUs. Tenía unas simulaciones bastante pesadas que correr y quise aprovechar su naturaleza perfectamente paralelizable. Y, de paso, hacer con R lo mismo por lo que he visto a un consultor de SAS cobrar a razón de 3.000 dólares diarios.

En el fondo, es una trivialidad. Supongamos que la función que implementa la simulación se llama foo. Habitualmente, haríamos

Una tarea para mis lectores

R

Ayer me dieron los resultados de unos análisis de sangre y, contra todo pronóstico, la médica me dijo que tengo el colesterol bajo control. ¡Con razón —me dije—, si en el blog lo hago yo todo! Así que para mejorar la circulación sanguínea de mis lectores, esta entrada es un ejercicio para quienes me leen. Espero pues que, a pesar de lo vacacional de las fechas, tengan tiempo de completar lo que queda sin hacer y lo hagan constar —antes de que pase lista— en un comentario explicando sus averiguaciones.

Más de diez motivos para usar PROC SQL en SAS

Hace no mucho escribí una entrada en este blog sobre, bromas aparte, cómo no escribir código SAS. Habría respondido in situ a uno de los comentarios que hicieron mis lectores pero, abusando de mi condición de dueño del blog, lo voy a hacer desde más encumbrado púlpito: una entrada ad hoc. Conste que escribo para discrepar. Pero conste también que lo hago desde la más genuina cordialidad y con la esperanza de generar un debate que a todos nos enriquezca.

¿Puedo cambiar mi código retroactivamente?

R

La verdad, me gustaría, Me gustaría volver atrás y modificar algunas docenas de código en R que malescribí como un diletante por no estar al tanto de una función de R cuya verdadera utilidad descubrí recientemente (gracias le sean dadas, de nuevo, a Jorge Iván Vélez).

La verdad, no tengo excusa. Incluso se habló de ella en nuestro blog hermano.

Y es que nunca me había percatado de la potencia de la función mapply. He aquí el problema: se tienen dos listas de la misma longitud y se quieren transformar los objetos de la primera en función de datos extraídos de los objetos correspondientes de la segunda. En los tiempos oscuros que duraron hasta anteayer, me veía abocado a utilizar un bucle que llevase la contabilidad del índice para poder recorrer ambas listas simultáneamente:

Madre Teresa, patriotas, idiotas... y queries recursivas

No es éste foro para opinar sobre si nos interesa la Madre Teresa o si los patriotas son idiotas, pero sí para mostrar nuestro desacuerdo con la canción (por abreviar, acá está su letra) y dejar claro que las jerarquías no son una porquería. Si no que se lo digan a un indirecto cliente mío que consume lo que no nos devuelve a los accionistas como dividendo en pagar hordas de consultores poco avisados de lo que acá cuento. Y lo cuento y dejo públicamente escrito para que tengan todavía menos excusa.

Creando paquetes con R: r-forge

Hace poco no asistí a una conferencia del profesor Campo Elías Pardo en la Universidad Nacional de Colombia sobre la creación de paquetes de R. Me penó no poder asistir porque sospeché primero y corroboré después que se había obviado en ella una herramienta muy útil para la creación de paquetes con R: la forja oficial.

La conferencia trababa esencialmente de cómo crear paquetes bajo Windows. Windows es un sistema operativo del que sé poco y siempre me han parecido excesivamente arcanos los liturgias y herramientas necesarias para compilar los paquetes. Especialmente cuando uno cuenta con Linux. Pero ésa es otra historia.