Как я могу загрузить объект в имя переменной, которое я определяю из файла данных R?

Когда вы сохраняете переменную в файле данных R, используя save, он сохраняется под любым именем в сеансе, в котором он был сохранен. Когда я позже иду, чтобы загрузить его из другого сеанса, он загружается с тем же именем, которое не может знать сценарий загрузки. Это имя может перезаписать существующую переменную с тем же именем в сеансе загрузки. Есть ли способ безопасно загрузить объект из файла данных в указанное имя переменной без риска забить существующие переменные?

Пример:

Сохранение сессии:

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

Сессия загрузки:

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

Как я хочу, чтобы это работало:

x = 7
y = load_object_from_file("x.Rda")
print(x) # should print 7
print(y) # should print 5

9 ответов

Решение

Если вы просто сохраняете один объект, не используйте .Rdata файл, используйте .RDS файл:

x <- 5
saveRDS(x, "x.rds")
y <- readRDS("x.rds")
all.equal(x, y)

Я использую следующее:

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

Вы можете создать новую среду, загрузить файл.rda в эту среду и извлечь объект оттуда. Однако это накладывает некоторые ограничения: либо вы знаете, каково оригинальное имя вашего объекта, либо в файле сохранен только один объект.

Эта функция возвращает объект, загруженный из предоставленного файла.rda. Если в файле более одного объекта, возвращается произвольный.

load_obj <- function(f)
{
    env <- new.env()
    nm <- load(f, env)[1]
    env[[nm]]
}

Вы также можете попробовать что-то вроде:

# 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)

Как и в других приведенных выше решениях, я загружаю переменные в переменную среды. Таким образом, если я загружаю несколько переменных из .Rda, они не будут загромождать мою среду.

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

Демо:

      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

Rdata файл с одним объектом

assign('newname', get(load('~/oldname.Rdata')))

В случае, если кто-то хочет сделать это с простым исходным файлом, а не с сохраненным файлом Rdata/RDS/Rda, решение очень похоже на решение, предоставленное @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)

Печать:

[1] "Значение аргумента равно 7"

И в отдельном исходном файле TestSourceFile.R

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

Опять же, это решение работает только в том случае, если существует ровно один файл, если их больше, то он просто вернет один из них (вероятно, первый, но это не гарантируется).

Я расширяю ответ от @ricardo, чтобы разрешить выбор конкретной переменной, если .Rdata Файл содержит несколько переменных (так как мои кредиты невелики для редактирования ответа). Он добавляет несколько строк для чтения пользовательского ввода после перечисления переменных, содержащихся в .Rdata файл.

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')

Следуя @ricardo, еще один пример использования (эффективного) отдельной среды

      load_rdata <- function(file_path) {
    res <- local({
        load(file_path)
        return(get(ls()))
    })
    return(res)
}

Аналогичные предостережения с ожиданием возврата только одного объекта

Другие вопросы по тегам