web-dev-qa-db-fra.com

Obtenir un objet spécifique du fichier rdata

J'ai un fichier Rdata contenant divers objets:

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

Bien sûr, je peux charger la trame de données avec load('New.Rdata'), cependant, existe-t-il un moyen intelligent de ne charger qu'un objet spécifique de ce fichier et de supprimer les autres?

51
Seb

Les fichiers .RData n'ont pas d'index (le contenu est sérialisé comme une grande paire). Vous pouvez pirater une façon de passer par la paire de paire et n'attribuez que des entrées que vous aimez, mais ce n'est pas facile car vous ne pouvez pas le faire au niveau r.

Cependant, vous pouvez simplement convertir le fichier .RData en une base de données paresseuse qui sérialise chaque entrée séparément et crée un index. La bonne chose est que le chargement sera à la demande:

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

Chargement de la DB puis chargée uniquement l'index mais pas le contenu. Les contenus sont chargés comme ils sont utilisés:

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

Tout comme avec load() Vous pouvez spécifier un environnement à charger pour que vous n'ayez pas besoin de polluer l'espace de travail global, etc.

67
Simon Urbanek

La réponse de Simon Urbanek est très très agréable. Un inconvénient est qu'il ne semble pas fonctionner si un objet à sauver est trop grand:

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

Je suppose que cela est dû à une limitation de la mise en œuvre actuelle de R (j'ai 2.15.2) plutôt que de manquer de mémoire physique et d'échange. Le package sauvegarde peut être une alternative à des utilisations.

4
Mars