Esta es una nota que me dejo a mí mismo sobre paralelización en R para no tener que ir buscándola en otras partes:
library(parallel)
foo <- function(i){
Sys.sleep(i)
}
cl <- makeCluster(4)
system.time(parSapply(cl, 1:4, foo))
# user system elapsed
# 0.025 0.006 4.007
system.time(sapply(1:4, foo))
# user system elapsed
# 0.039 0.033 10.001
stopCluster(cl)
Suelo trabajar un servidor con ocho CPUs. Cuando quiero paralelizar código en R, suelo utilizar [parallel::mclapply](https://stat.ethz.ch/R-manual/R-devel/library/parallel/html/mclapply.html)
(como aquí). Pero no tengo una máquina. Tengo varias. Y antes, de hecho, muchas.
¿Cómo paralelizar en distintas máquinas?
Se puede usar Spark (y SparkR), por ejemplo. Pero una ruta que no había ensayado jamás es la de la vieja escuela, i.e., MPI, snow
y demás.
Pero si
Hay quienes preguntan cómo cargar con R un csv de 8GB en un portátil de 4GB de RAM. La verdad, he leído respuestas la mar de extravagantes a este tipo de cuestiones: p.e., recomendar SQLite.
Yo recomendaría Scalable Strategies for Computing with Massive Data. Entre otras cosas, porque para eso lo escribieron sus autores: para que se lea. Y porque está cargado de razón y buenos consejos.
Una cosa con la que tropezará enseguida quien lo hojee es:
Estoy sin tiempo, así que os suelto el código y me largo a casa a no cenar. Es así:
library(parallel)
cl <- makeCluster(8)
# solo si hay aleatorización
# clusterSetRNGStream(cl, 123)
clusterEvalQ(cl,
{
# las librerías necesarias tienen que cargarse
# en cada esclavo
library(rpart)
# en la práctica, hay que cargar los datos
# (¿desde fichero?) en cada esclavo
my.data <- iris
# lo mismo con las funciones necesarias
foo <- function(x, dat){
train <- 1:nrow(dat) %% 10 != 1
mod <- rpart(Species ~ ., data = dat[train,])
res <- predict(mod, dat[!train,])
}
})
res <- parSapply(cl, 0:9,
function(x) foo(x, my.data), simplify = F)
Trabajo sobre una máquina de 8 núcleos y 24 GB de RAM. Y que conste que se me ha llegado a quedar chica.
Algunos programas que ejecuto tienen (o contienen pedazos de) la forma
- calcula A
- calcula B
- calcula C
- combina A, B y C
Obviamente, se me ocurre ejecutarlos así:
- calcula A, B y C en paralelo
- cuando acabe el paso anterior, combina A, B y C
Y aún me sobrarían 5 núcleos y bastante RAM. La pregunta es: ¿cómo?
Hoy traigo a mis páginas cuatro enlaces que apuntan a recetarios y tutoriales sobre la solución a cuatro problemas que pueden encontrar los usuarios de R:
¡Espero que os resulten útiles!
Me llegó recientemente un artículo con una lista de veinte paquetes de R para data scientists. Y no la encuentro afortunada. Voy a agrupar esos veinte paquetes en algunas categorías y añadiré comentarios. La primera de ellas es la de manipulación de datos, tal vez la más amplia, que recoge los siguientes: sqldf
, plyr
, stringr
(para procesar texto), lubridate
(para procesar fechas),reshape2
y los paquetes de acceso a bases de datos.
Esta es la tercera entrega de una serie de artículos en los que comparo SAS y R a la hora de realizar diversos tipos de simulaciones basados en Don’t Be Loopy: Re-Sampling and Simulation the SAS® Way.
Esta vez toca compararlos a la hora de aplicar el método del jackknife.
Primero, el código SAS que recomienda el autor del artículo, que calcula la curtosis de un conjunto de datos trivial (una muestra de 10k valores que siguen una distribución uniforme):
Parcialmente en agradecimiento a Revolution Analytics por haber concedido una subvención a las III Jornadas de usuarios de R voy a discutir en esta entrada cómo paralelizar bucles usando los paquetes foreach
y doMC
desarrollados por dicha empresa.
El paquete foreach
contiene, esencialmente, una única función, foreach
, que, en su forma más básica, permite ejecutar bucles con una sintaxis un tanto peculiar:
foreach( i = 1:3 ) %do% log( i )
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