Velocidad de cálculo en R?

16

Se me ha encomendado la tarea de trasladar uno de nuestros modelos estocásticos grandes actuales de SAS a un nuevo idioma. Personalmente, prefiero un lenguaje compilado tradicional, pero el PI quiere que revise R, que nunca he usado. Nuestra motivación para sacar el modelo de SAS es (1) muchas personas no tienen acceso a él porque SAS es costoso, (2) estamos buscando alejarnos de un lenguaje interpretado, y (3) SAS es lento para El tipo de modelo que tenemos.

Para (1), obviamente R satisface la necesidad de que sea libre. Para (2), idealmente, nos gustaría crear un ejecutable, pero R normalmente se usa como un lenguaje de script. Veo que alguien ha lanzado recientemente un compilador R, ¿ha sido bien recibido? ¿Es fácil de usar? Preferimos no obligar al usuario a descargar R ellos mismos. Para (3), nuestro problema con SAS es todo el tiempo dedicado a escribir y leer conjuntos de datos de E / S. Nuestro modelo es computacionalmente intensivo, y a menudo estamos limitados por el tiempo de ejecución. (por ejemplo, no es raro que alguien secuestre las computadoras de las personas durante el fin de semana para realizar ejecuciones). Tenemos un modelo similar construido en Fortran que no tiene el mismo problema porque todo el trabajo se realiza en la memoria. ¿Cómo funciona R? ¿Será lo mismo que SAS, ya que funciona en pasos de datos, leyendo y escribiendo archivos? ¿O puede hacer una manipulación de matriz en la memoria?

Toronjil
fuente
Por lo general, puede acelerar sas haciendo todo su trabajo en un solo paso de datos. Esto debería reducir los tiempos de E / S, ya que efectivamente solo está leyendo datos una vez. Usar muchos procedimientos también lo retrasará. Por ejemplo, si modela repetidamente llame a proc glm o proc logistic (digamos para un bootstrap), es más rápido crear un gran conjunto de datos y usar una declaración by que invocar muchas llamadas proc (digamos usando un macro% do loop). si programa SAS así, no debería tener problemas de tiempo de ejecución debido a la lectura y outputing archivos (al menos no más que otro software
probabilityislogic
Además, puede usar matrices temporales en pasos de datos sas de manera similar a cómo usaría matrices en R.
probabilidadislogica

Respuestas:

18

R funciona en la memoria, por lo que sus datos deben caber en la memoria para la mayoría de las funciones.

El paquete compilador, si estoy pensando en lo que está pensando (el paquete compilador de Luke Tierney suministrado con R), no es lo mismo que un lenguaje compilado en el sentido tradicional (C, Fortran). Es un compilador de bytes para R en el sentido del código de bytes de Java ejecutado por Java VM o la compilación de bytes del código LISP de Emacs. No compila el código R en código de máquina, sino que prepara el código R en código de bytes para que pueda usarse de manera más eficiente que el código R sin procesar para ser interpretado.

Tenga en cuenta que si ha formado Fortran bien, probablemente podría tener lo mejor de ambos mundos; R puede llamar a rutinas compiladas de Fortran.

Restablece a Mónica - G. Simpson
fuente
¡Gracias! Es bueno saber que podría tener los excelentes gráficos R y las rutinas compiladas de Fortran. Esta puede ser la respuesta!
Melissa
2
Solo para ampliar la nota de Gavin sobre la memoria: consulte la sección sobre Memoria grande en esta vista de tareas CRAN si está trabajando con conjuntos de datos más grandes: cran.r-project.org/web/views/HighPerformanceComputing.html
Brandon Bertelsen
1
También piense que es importante tener en cuenta que Rcpp probablemente podría usarse para obtener ganancias incrementales en el rendimiento.
Brandon Bertelsen
Rcpp es útil para envolver C ++ para su uso en / con R. Ayuda al proceso (inmensamente) pero todavía está usando las herramientas básicas de R para llamar al código compilado. Si el OP ya tiene códigos Fortran o habilidades Fortran, Rcpp puede ser de menor uso.
Restablece a Monica - G. Simpson el
13

Lo he usado SASdurante 15 años, y he comenzado a usarlo Rseriamente en los últimos 6 meses, con algunos ajustes por un par de años antes de eso. Desde una perspectiva de programación, R las manipulaciones de datos se realizan directamente, no hay equivalentes DATAni PROC SQLprocedimientos porque no son necesarios (este último es más eficiente SAScuando hay mucha manipulación de datos para hacer desde fuentes de datos externas, por ejemplo, datos administrativos). Esto significa que, ahora que me estoy acostumbrando, la manipulación de datos es más rápida Ry requiere mucho menos código.

El principal problema que he encontrado es la memoria. No todos los paquetes R permiten WEIGHTespecificaciones de tipo, por lo que si tiene SASconjuntos de datos con variables utilizadas en FREQo REPLICATEdeclaraciones, puede tener problemas. He examinado los paquetes ffy bigmemoryen R, pero no parecen ser compatibles con todos los paquetes de R, por lo que si tiene conjuntos de datos muy grandes que requieren análisis que son relativamente poco comunes y se han agregado, es posible que tenga problemas con la memoria.

Para la automatización, si lo tiene SAS macros, debería poder programar el equivalente Ry ejecutarlo como lote.

Para codificar R, estaba usando Notepad++y configurando el idioma R, y ahora estoy descubriendo las alegrías de R Studio. Ambos productos son gratuitos y marcan el lenguaje como la SASGUI de sintaxis mejorada (solo he usado la pantalla de sintaxis SAS).

Hay un sitio web y un libro relacionado para que las personas cambien de SASa R. Los encontré útiles para tratar de averiguar cómo traducir algunos SAScomandos R.

Actualización: una cosa que me volvía loco cuando viene a Res que Rno asume todo es un conjunto de datos ( data frameen Rla jerga), porque no es un paquete estadístico de la manera que SAS, SPSS, Stata, etc son. Entonces, por ejemplo, me tomó un tiempo hacer que las ifdeclaraciones funcionaran porque seguía recibiendo ayuda para las ifdeclaraciones con vectores (o tal vez matrices), mientras que necesitaba una ifdeclaración que funcionara data frames. Por lo tanto, es probable que las páginas de ayuda se deban leer más detenidamente de lo normal, ya que deberá verificar que el comando que desea ejecutar funcione con el tipo de objeto de datos que tiene.

La parte que todavía me vuelve loco al aprender un nuevo Rcomando (por ejemplo, el método de análisis en un paquete contribuido) es que la ayuda para los comandos a menudo no es completamente autónoma. Iré a la página de ayuda para tratar de aprender el comando y las notas de uso que a menudo ...contienen. A veces, tratar de averiguar qué puede o debe ir donde ...está me ha llevado a un círculo recursivo. La relativa brevedad de las notas de ayuda, que provienen de SASejemplos detallados de sintaxis y ejemplos trabajados con una explicación del estudio en el ejemplo, fue un shock bastante grande.

Michelle
fuente
2
+1 Considere actualizar nuestro metahilo donde hemos recopilado enlaces a recursos de software de estadísticas. Hay una respuesta para R y otra para SAS: ambos se beneficiarían de tener un enlace a r4stats.com. (Ese hilo es en realidad una parte de nuestras preguntas frecuentes. Esperamos mantenerlo actualizado y útil.)
whuber
1
R también tiene paquetes que admiten acceso SQL a través de controladores RODBC o SQLite.
DWin
1
Estoy de acuerdo con tus comentarios sobre la ayuda de R. De hecho, señalé esencialmente lo que estás diciendo en una de las listas de correo de R hace muchos años. La respuesta no fue positiva. Para ser justos, (a) probablemente no me expresé muy bien y no di ningún ejemplo concreto y (b) no seguí el asunto. Para resumir, el problema 1 son ejemplos demasiado complicados e involucran demasiados conceptos no relacionados. Los ejemplos complicados están bien, pero deben seguir ejemplos simples. El problema 2 es que casi no hay anotaciones o explicaciones de lo que hacen los ejemplos.
Faheem Mitha
En cuanto a la "ayuda" de R, recuerda algo que me dijo mi jefe. "aprendes R haciéndolo con alguien que ya conoce a R sentado a tu lado en la computadora"
probabilistico
Y para todos los demás hay libros y Stack Overflow. Sí, aprender R por ti mismo es bastante difícil, al menos lo ha sido para mí.
Michelle
10

R es un lenguaje de programación. No funciona en pasos de datos. Hace lo que quieras que haga, ya que no es más que un lenguaje de programación, un esclavo de tus deseos, expresado en un lenguaje de llaves y dos puntos.

Piense en ello como Fortran o C, pero con vectorización implícita para que no tenga que recorrer los arreglos, y administración de memoria dinámica para que no tenga que malloc () o declarar tamaños de matriz en cualquier momento.

Principalmente hace todo su trabajo en la memoria, pero si desea leer parte de un archivo, mezclarlo, luego escupe algunos de los resultados y lee el siguiente bit, bueno, continúe y escriba un programa R que hace eso.

Se contradice a sí mismo al decir que el modelo es computacionalmente intenso pero SAS es lento debido a E / S ... Uno u otro seguramente ...

Si ya tiene algo similar en Fortran y dice que quiere alejarse de un idioma interpretado, ¿por qué no hacerlo también en Fortran?

El compilador R puede causar algunas aceleraciones, pero si su código R está bien escrito de todos modos, no obtendrá nada demasiado masivo, no como escribirlo en C o Fortran.

Hombre espacial
fuente
Ah, no me expliqué bien. Es intensivo en su manipulación de conjuntos de datos, lo que en SAS significa demasiado tiempo dedicado a E / S. Mi sugerencia inicial fue Fortran, pero el PI está interesado en que cambiemos a R, por lo que quería que lo revisara. ¡Gracias!
Melissa
7

Entiendo que, de forma predeterminada, SAS puede trabajar con modelos que son más grandes que la memoria, pero este no es el caso con R, a menos que utilice específicamente paquetes como biglm o ff.

Sin embargo, si está haciendo un trabajo de matriz en R que se puede vectorizar, será muy rápido, tal vez la mitad de la velocidad de un programa C en algunos casos, pero si está haciendo algo que no se puede vectorizar, entonces parecerá bastante lento. Para darle un ejemplo:

# create a data.frame with 4 columns of standard normally distributed RVs
N <- 10000

# test 1
system.time( {df1 <- data.frame(h1=rnorm(N),
                h2=rpois(N, lambda=5),
                h3=runif(N),
                h4=rexp(N))
} )
# about 0.003 seconds elapsed time

# vectorised sum of columns 1 to 4
# i.e. it can work on an entire column all at once
# test 2
system.time( { df1$rowtotal1 <- df1$h1 + df1$h2 + df1$h3 + df1$h4 })
# about 0.001 seconds elapsed time

# test 3
# another version of the vectorised sum
system.time( { df1$rowtotal2 <- rowSums(df1[,c(1:4)]) })
# about 0.001 seconds elapsed time

# test 4
# using a loop... THIS IS *VERY* SLOW AND GENERALLY A BAD IDEA!!! :-)
system.time( {
        for(i in 1:nrow(df1)) {
                df1$rowtotal3 <- df1[i,1]+ df1[i,2] + df1[i,3] + df1[i,4]
        }
} )
# about 9.2 seconds elapsed time

Cuando he aumentado N por un factor de diez a 100.000, di arriba en la prueba 4, después de 20 minutos, pero las pruebas 1: 3 tomó 61, 3 y 37 mili -seconds cada

Para N = 10,000,000 el tiempo para las pruebas 1: 3 es 3.3s, 0.6s y 1.6s

Tenga en cuenta que esto se hizo en una computadora portátil i7 y a 480mb por N = 10million, la memoria no fue un problema.

Para los usuarios en ventanas de 32 bits, hay un límite de memoria de 1.5 gb para R, sin importar cuánta memoria tenga, pero no existe dicho límite para las ventanas de 64 bits o Linux de 64 bits. En estos días, la memoria es muy barata en comparación con el costo de una hora de mi tiempo, así que solo compro más memoria en lugar de perder el tiempo tratando de solucionar esto. Pero esto supone que su modelo quedará en la memoria.

Sean
fuente
1
(+1) ¡Gracias por ofrecer las útiles ilustraciones, Sean!
whuber
3

(2), idealmente, nos gustaría crear un ejecutable, pero R normalmente se usa como un lenguaje de script

Sí, y esta es la buena razón para mudarse a R. El interés de escribir un paquete R es permitir a los usuarios hacer que sus funciones interactúen fácilmente con otras herramientas proporcionadas por R, por ejemplo, dándoles datos de arranque ... o lo que quieran. Si no cree que esto sea importante, utilice C / C ++ o su lenguaje compilado favorito.

O()rle()

Así que ten mucho cuidado. Después de sus primeros intentos, seguramente tendrá un disgusto con R, porque lo encontrará lento, con una sintaxis extraña, etc. Una vez que lo sepa, puede ser una herramienta muy eficiente. Incluso puede terminar escribiendo sus métodos en R como una fase preliminar para la codificación C / C ++. La etapa final será aprender la API de R para crear funciones precompiladas, y serás un asistente de R :)

Elvis
fuente
2

La manipulación de la matriz en la memoria es una gran cosa para SAS, aparentemente. No conozco los detalles específicos sobre R, pero supongo que R opera en la memoria por defecto, ya que los paquetes de expansión de memoria para R, ff y bigmemory, mueven datos de la memoria al disco. Tengo punteros para usted si desea mejorar la velocidad o el uso de la memoria. Para mejorar la velocidad, primero debe usar R según lo previsto, es decir: vectorizar su código y usar la compilación de código de bytes. (Además: evite las operaciones de copia de memoria tanto como sea posible). En segundo lugar, use el generador de perfiles de código Rprof () para identificar parches lentos en su código y vuelva a escribirlos en C o C ++ si es necesario. Si necesita más memoria, puede usar el argumento de omisión en la función read.table () para leer en sus datos un fragmento a la vez y también puede usar un paquete como RMySQL, que agrega utilidades de manipulación de bases de datos a R. Si necesita aún más memoria y puede permitirse la disminución concomitante de la velocidad, puede usar el paquete de nieve para ejecutar R en paralelo. (Puede encontrar detalles sobre esto, y mucho más, en el libro "The Art of R Programming", de Norman Matloff, publicado a fines del año pasado. Los detalles sobre los paquetes mencionados aquí se pueden encontrar en línea).

Jean-Victor Côté
fuente