Como posso carregar um objeto em um nome de variável que eu especifico de um arquivo de dados R?

97

Quando você salva uma variável em um arquivo de dados R usando save, ela é salva com o nome que tinha na sessão que a salvou. Mais tarde, quando vou carregá-lo de outra sessão, ele é carregado com o mesmo nome, que o script de carregamento não pode saber. Este nome pode substituir uma variável existente com o mesmo nome na sessão de carregamento. Existe uma maneira de carregar com segurança um objeto de um arquivo de dados em um nome de variável especificado sem risco de sobrepor as variáveis ​​existentes?

Exemplo:

Salvando sessão:

x = 5
save(x, file="x.Rda")

Carregando sessão:

x = 7
load("x.Rda")
print(x) # This will print 5. Oops.

Como eu quero que funcione:

x = 7
y = load_object_from_file("x.Rda")
print(x) # should print 7
print(y) # should print 5
Ryan C. Thompson
fonte

Respostas:

93

Se você estiver apenas salvando um único objeto, não use um .Rdataarquivo, use um .RDSarquivo:

x <- 5
saveRDS(x, "x.rds")
y <- readRDS("x.rds")
all.equal(x, y)
Hadley
fonte
Atualizado para refletir que em 2.13 eles não são mais experimentais.
hadley de
Isso significa que eles são totalmente compatíveis, assim como os arquivos .Rdata?
Ryan C. Thompson
Uma vez que não são mais experimentais, estou marcando essa como a resposta aceita. É isso que estou usando.
Ryan C. Thompson
Fazer saveRDSe readRDS, correspondentemente, salvar e restaurar todos os atributos do objeto, incluindo aqueles criados por um aplicativo (via attr)? Tentei usar essa abordagem em vez de savee load, tentando encontrar uma solução alternativa para o meu problema. No entanto, não parece ser o caso, a menos que eu esteja fazendo algo errado: stackoverflow.com/questions/23701195/… .
Aleksandr Blekh
37

Eu uso o seguinte:

loadRData <- function(fileName){
#loads an RData file, and returns it
    load(fileName)
    get(ls()[ls() != "fileName"])
}
d <- loadRData("~/blah/ricardo.RData")
ricardo
fonte
1
Esta é uma pequena função excelente. Estava tendo problemas ao tentar carregar as coisas (não queria apenas colocá-las no ambiente global, pois eu sei que
haveria
4
Algo assim pertence à base R
Repmat de
1
AMD. Isso é incrível. Exatamente o que eu preciso! #loveit
Sander W. van der Laan
Você pode expandir a lógica da instrução GET? Por que não corresponder a FILENAME em vez de excluir?
nnachefski
35

Você pode criar um novo ambiente, carregar o arquivo .rda nesse ambiente e recuperar o objeto de lá. No entanto, isso impõe algumas restrições: ou você sabe qual é o nome original do seu objeto ou há apenas um objeto salvo no arquivo.

Esta função retorna um objeto carregado de um arquivo .rda fornecido. Se houver mais de um objeto no arquivo, um arbitrário será retornado.

load_obj <- function(f)
{
    env <- new.env()
    nm <- load(f, env)[1]
    env[[nm]]
}
Hong Ooi
fonte
3
É new.envrealmente necessário? A própria chamada de função não fornece um ambiente temporário?
Ryan C. Thompson,
Você pode retornar o ambiente inteiro (return (env) ou return (environment ()) ao modificar a função de acordo com a sugestão de @Ryan).
Wojciech Sobala
2
Se você usar o ambiente de função, ele conterá f e terá um pai. Provavelmente não é o que você quer
hadley
27

Você também pode tentar algo como:

# Load the data, and store the name of the loaded object in x
x = load('data.Rsave')
# Get the object by its name
y = get(x)
# Remove the old object since you've stored it in y 
rm(x)
por 0
fonte
4
O objetivo é evitar sobrecarregar o valor de x ao carregar.
Ryan C. Thompson
2

Caso alguém queira fazer isso com um arquivo fonte simples, em vez de um arquivo Rdata / RDS / Rda salvo, a solução é muito semelhante à fornecida por @Hong Ooi

load_obj <- function(fileName) {

  local_env = new.env()
  source(file = fileName, local = local_env)

  return(local_env[[names(local_env)[1]]])

}

my_loaded_obj = load_obj(fileName = "TestSourceFile.R")

my_loaded_obj(7)

Impressões:

[1] "O valor de arg é 7"

E no arquivo de origem separado TestSourceFile.R

myTestFunction = function(arg) {
  print(paste0("Value of arg is ", arg))
}

Novamente, essa solução só funciona se houver exatamente um arquivo, se houver mais, ela retornará apenas um deles (provavelmente o primeiro, mas isso não é garantido).

user2711915
fonte
1

Estou estendendo a resposta de @ricardo para permitir a seleção de uma variável específica se o .Rdataarquivo contiver várias variáveis ​​(já que meus créditos são baixos para editar uma resposta). Ele adiciona algumas linhas para ler a entrada do usuário após listar as variáveis ​​contidas no .Rdataarquivo.

loadRData <- function(fileName) {
  #loads an RData file, and returns it
  load(fileName)
  print(ls())
  n <- readline(prompt="Which variable to load? \n")
  get(ls()[as.integer(n)])
}

select_var <- loadRData('Multiple_variables.Rdata')

SeanM
fonte
1

Arquivo Rdata com um objeto

assign('newname', get(load('~/oldname.Rdata')))
Javier Acosta
fonte
1
Isso não carregará o objeto com o nome antigo e, em seguida, também o atribuirá ao novo nome? Isso não ajudará se eu estiver preocupado com a possibilidade de sobrescrever uma variável existente.
Ryan C. Thompson de