2009-02-27 8 views
12

Tengo 12 data.frame s para trabajar. Son similares y tengo que hacer el mismo procesamiento para cada uno, así que escribí una función que toma un data.frame, lo procesa y luego devuelve un data.frame. Esto funciona. Pero me temo que estoy pasando por una estructura muy grande. Puedo hacer copias temporales (¿verdad?) Esto no puede ser eficiente. ¿Cuál es la mejor manera de evitar pasar un data.frame?¿Cuál es la mejor manera de evitar pasar un marco de datos?

doSomething <- function(df) { 
    // do something with the data frame, df 
    return(df) 
} 
+0

Pregunta de seguimiento: Cuando termine con 'doSomething', el comando 'rm (doSomething)' liberará el objeto para la recolección de basura, ¿verdad? – bernie

+0

Adam, sí. Estás en lo correcto. –

+0

, pero tenga en cuenta que en el ejemplo anterior 'doSomething' es una función, no datos, por lo que no es muy grande. –

Respuesta

11

De hecho, está pasando el objeto y usando algo de memoria. Pero no creo que pueda hacer una operación en un objeto en R sin pasar el objeto. Incluso si no creó una función e hizo sus operaciones fuera de la función, R se comportaría básicamente igual.

La mejor manera de ver esto es crear un ejemplo. Si está en Windows, abra el Administrador de tareas de Windows. Si está en Linux, abra una ventana de terminal y ejecute el comando superior. Voy a asumir Windows en este ejemplo. En R ejecute el siguiente:

col1<-rnorm(1000000,0,1) 
col2<-rnorm(1000000,1,2) 
myframe<-data.frame(col1,col2) 

rm(col1) 
rm(col2) 
gc() 

esto crea un par de vectores llamados col1 y col2 luego las combina en una trama de datos llamada MyFrame. A continuación, suelta los vectores y fuerza la recolección de elementos no utilizados para que se ejecute. Mire en su administrador de tareas de Windows el uso de memoria para la tarea Rgui.exe. Cuando comienzo R, usa aproximadamente 19 megas de mem. Después de ejecutar los comandos anteriores mi máquina está utilizando poco menos de 35 meg por R.

Ahora intente esto:

myframe<-myframe+1 

el uso de memoria para R debe saltar a más de 144 megas. Si fuerza la recolección de basura usando gc() verá que se reduce a alrededor de 35 megas. Para probar esto usando una función, puede hacer lo siguiente:

doSomething <- function(df) { 
    df<-df+1-1 
return(df) 
} 
myframe<-doSomething(myframe) 

cuando se ejecuta el código anterior, el uso de memoria saltará hasta 160 megas o menos. Al ejecutar gc(), se reducirá a 35 megas.

¿Qué hacer con todo esto? Bueno, realizar una operación fuera de una función no es mucho más eficiente (en términos de memoria) que hacerlo en una función. La recolección de basura limpia las cosas muy bien. ¿Deberías forzar a gc() a correr? Probablemente no, ya que se ejecutará automáticamente según sea necesario, simplemente lo ejecuté arriba para mostrar cómo afecta el uso de la memoria.

Espero que ayude!

8

No soy un experto en R, pero la mayoría de los idiomas usan un esquema de recuento de referencias para objetos grandes. No se realizará una copia de los datos del objeto hasta que modifique la copia del objeto. Si sus funciones solo leen los datos (es decir, para el análisis), entonces no se debe hacer ninguna copia.

+3

Así es como R también funciona, Neil. Buen punto. –

1

me encontré con esta pregunta buscando otra cosa, y es vieja - así que voy a darle una respuesta breve por ahora (dejar un comentario si desea una explicación más detallada).

Puede pasar entornos en R que contienen desde 1 a todas sus variables. Pero probablemente no necesites preocuparte por eso.

[También es posible que haga algo similar con las clases. Actualmente solo entiendo cómo usar clases para las funciones polimórficas, y tenga en cuenta que hay más de un sistema de clases dando vueltas.]

Cuestiones relacionadas