2012-01-02 11 views
40

Tengo un archivo Rdata que contiene varios objetos:Obtener objeto específico de rdata presentar

New.Rdata 
    |_ Object 1 (e.g. data.frame) 
    |_ Object 2 (e.g. matrix) 
    |_... 
    |_ Object n 

Por supuesto que puedo cargar la trama de datos con load('New.Rdata'), sin embargo, hay una manera inteligente para cargar sólo un objeto específico a cabo de este archivo y descartar los otros?

+1

En los comentarios, @DWin dice que no. http://stackoverflow.com/questions/6550510/examining-contents-of-rdata-file-by-attaching-into-a-new-environment-possible –

+1

Pero en todos los asuntos-R Debo a Simon. –

Respuesta

61

.R Los archivos de datos no tienen un índice (los contenidos se serializan como una gran pairlista). Podría hackear una forma de ir a través de la nave y asignar solo las entradas que desee, pero no es fácil, ya que no puede hacerlo en el nivel R.

Sin embargo, simplemente puede convertir el archivo .RData en una base de datos de carga diferida que serializa cada entrada por separado y crea un índice. Lo bueno es que la carga será bajo demanda:

# convert .RData -> .rdb/.rdx 
e = local({load("New.RData"); environment()}) 
tools:::makeLazyLoadDB(e, "New") 

Al cargar el DB, solo se carga el índice pero no el contenido. Los contenidos se cargan a medida que se utilizan:

lazyLoad("New") 
ls() 
x # if you had x in the New.RData it will be fetched now from New.rdb 

Al igual que con load() puede especificar un entorno para cargar en lo que no es necesario para contaminar el espacio de trabajo mundial, etc.

+1

Pero la búsqueda aún requerirá un acceso en serie a través de "New.RData" para obtener "x", ¿verdad? Entonces, si "x" está al final de "New.RData", es posible que no se ahorre tiempo. Pregunta 2: ¿no habrá memoria ocupada con los otros objetos encontrados mientras el proceso de desserialización se abre paso a través de "New.RData"? –

+1

No, la búsqueda solo busca 'New.rdb' al principio de' x' y solo carga 'x'. –

+8

¿Cuáles son las posibilidades de que estas funciones se vuelvan menos internas? – hadley

10

Se puede utilizar en lugar attach que load que unirá el objeto de datos a la ruta de búsqueda, entonces puede copiar el objeto que le interesa y separar el objeto .Rdata.

Esto todavía carga todo, pero es más fácil de trabajar que cargar todo en el espacio de trabajo global (posiblemente sobrescribiendo cosas que no desea sobreescribir) y luego deshacerse de todo lo que no desea.

+3

Esta respuesta es buena, pero sería más completa con un ejemplo, porque separar el objeto .RData de la ruta de búsqueda no es intuitivo. Ejemplo para recuperar 'someObj' de' someFile.RData': 'attach ('someFile.RData'); someObj <- someObj; detach ('file: someFile.RData') ' – C8H10N4O2

+0

@ C8H10N4O2, su ejemplo es bueno (y muy explícito). Pero si lo adjunta en la posición predeterminada (2) y no agrega nada más antes de llamar a detach, los valores predeterminados funcionan y puede llamar a 'detach()' sin ningún argumento y se separará el archivo. Esto es más rápido y simple; tu enfoque es más seguro –

4

La respuesta de Simon Urbanek es muy, muy agradable. Un inconveniente es que no parecen funcionar si un objeto para ser salvo es demasiado grande:

tools:::makeLazyLoadDB(
    local({ 
    x <- 1:1e+09 
    cat("size:", object.size(x) ,"\n") 
    environment() 
    }), "lazytest") 
size: 4e+09 
Error: serialization is too large to store in a raw vector 

supongo que esto se debe a una limitación de la aplicación actual de R (tengo 2.15. 2) en lugar de quedarse sin memoria física e intercambiar. Sin embargo, el paquete saves puede ser una alternativa para algunos usos.

+1

Esto es más un comentario extendido que una respuesta. – C8H10N4O2

Cuestiones relacionadas