103

When you save a variable in an R data file using save, it is saved under whatever name it had in the session that saved it. When I later go to load it from another session, it is loaded with the same name, which the loading script cannot possibly know. This name could overwrite an existing variable of the same name in the loading session. Is there a way to safely load an object from a data file into a specified variable name without risk of clobbering existing variables?

Example:

Saving session:

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

Loading session:

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

How I want it to work:

x = 7
y = load_object_from_file("x.Rda")
print(x) # should print 7
print(y) # should print 5
zx8754
  • 42,109
  • 10
  • 93
  • 154
Ryan C. Thompson
  • 37,328
  • 27
  • 87
  • 147

8 Answers8

98

If you're just saving a single object, don't use an .Rdata file, use an .RDS file:

x <- 5
saveRDS(x, "x.rds")
y <- readRDS("x.rds")
all.equal(x, y)
hadley
  • 94,313
  • 27
  • 170
  • 239
  • Updated to reflect that in 2.13 these are no longer experimental. – hadley Apr 20 '11 at 14:00
  • Does that mean that they're fully supported, just like .Rdata files? – Ryan C. Thompson Apr 23 '11 at 02:43
  • Since these are no longer experimental, I'm marking this as the accepted answer. This is what I've been using. – Ryan C. Thompson May 26 '12 at 19:56
  • Do `saveRDS` and `readRDS`, correspondingly, save and restore all object's attributes, including ones created by an application (via `attr`)? I tried to use this approach instead of `save` and `load`, trying to find a workaround for my problem. Howver, it doesn't seem to be the case, unless I'm doing something wrong: http://stackoverflow.com/questions/23701195/can-i-access-r-data-objects-attributes-without-fully-loading-objects-from-file. – Aleksandr Blekh May 18 '14 at 11:34
40

I use the following:

loadRData <- function(fileName){
#loads an RData file, and returns it
    load(fileName)
    get(ls()[ls() != "fileName"])
}
d <- loadRData("~/blah/ricardo.RData")
ricardo
  • 7,345
  • 6
  • 39
  • 64
37

You can create a new environment, load the .rda file into that environment, and retrieve the object from there. However, this does impose some restrictions: either you know what the original name for your object is, or there is only one object saved in the file.

This function returns an object loaded from a supplied .rda file. If there is more than one object in the file, an arbitrary one is returned.

load_obj <- function(f)
{
    env <- new.env()
    nm <- load(f, env)[1]
    env[[nm]]
}
Hong Ooi
  • 51,703
  • 12
  • 121
  • 162
28

You could also try something like:

# 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)
by0
  • 7,718
  • 6
  • 56
  • 74
3

Rdata file with one object

assign('newname', get(load('~/oldname.Rdata')))
  • 2
    Won't this load the object into the old name, and then also assign it to the new name as well? That won't help if I'm worried about the possibility of overwriting an existing variable. – Ryan C. Thompson Aug 16 '19 at 18:11
2

In case anyone is looking to do this with a plain source file, rather than a saved Rdata/RDS/Rda file, the solution is very similar to the one provided by @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)

Prints:

[1] "Value of arg is 7"

And in the separate source file TestSourceFile.R

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

Again, this solution only works if there is exactly one file, if there are more, then it will just return one of them (probably the first, but that is not guaranteed).

user2711915
  • 2,223
  • 1
  • 15
  • 17
2

Similar to the other solutions above, I load variables into an environment variable. This way if I load multiple variables from the .Rda, those will not clutter my environment.

load("x.Rda", dt <- new.env())

Demo:

x <- 2
y <- 1
save(x, y, file = "mydata.Rda")
rm(x, y)

x <- 123
# Load 'x' and 'y' into a new environment called 'dt'
load("mydata.Rda", dt <- new.env())
dt$x
#> [1] 2
x
#> [1] 123
HBat
  • 3,195
  • 3
  • 26
  • 42
1

I'm extending the answer from @ricardo to allow selection of specific variable if the .Rdata file contains multiple variables (as my credits are low to edit an answer). It adds some lines to read user input after listing the variables contained in the .Rdata file.

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
  • 135
  • 7