Як я можу завантажити об'єкт у ім'я змінної, яке я вказав у файлі даних R?


97

Коли ви зберігаєте змінну у файлі даних 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

Відповіді:


93

Якщо ви просто зберігаєте один об'єкт, не використовуйте .Rdataфайл, використовуйте .RDSфайл:

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

Оновлено так, що в 2.13 вони вже не експериментальні.
хадлі

Чи означає це, що вони повністю підтримуються, як і файли .Rdata?
Райан К. Томпсон,

Оскільки вони вже не експериментальні, я відзначаю це як прийняту відповідь. Це те, що я використовував.
Райан К. Томпсон,

Зберігають saveRDSі readRDS, відповідно, зберігають і відновлюють усі атрибути об'єкта, включаючи створені додатком (через attr)? Я намагався використати такий підхід замість, saveі load, намагаючись знайти рішення для своєї проблеми. Як би там не було, якщо тільки я не роблю щось неправильно: stackoverflow.com/questions/23701195/… .
Олександр Блех

37

Я використовую наступне:

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

1
Це чудова маленька функція. У мене виникли проблеми із спробою завантаження речей (я не хотів просто ставити їх у глобальне середовище, оскільки я знаю, що це мало проблеми.
Тревор Недерлоф

4
Щось подібне належить до бази R
Repmat

1
О БОЖЕ МІЙ. Це круто. Тільки те, що мені потрібно! #loveit
Sander W. van der Laan

Чи можете ви, будь ласка, розширити логіку заяви GET? Чому б не відповідати FILENAME замість виключення?
nnachefski

35

Ви можете створити нове середовище, завантажити файл .rda у це середовище та отримати звідти об’єкт. Однак це накладає деякі обмеження: або ви знаєте, що таке оригінальна назва вашого об'єкта, або у файлі збережений лише один об’єкт.

Ця функція повертає об'єкт, завантажений із доданого файлу .rda. Якщо у файлі більше одного об’єкта, повертається довільний.

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

3
Чи new.envсправді потрібно? Чи сам виклик функції не забезпечує тимчасове середовище?
Райан К. Томпсон,

Ви можете повернути ціле середовище (return (env) або return (оточення ()), коли ви змінюєте функцію відповідно до пропозиції @Ryan).
Войцех Собала

2
Якщо ви використовуєте середовище функції, воно буде містити f і мати батьків. Напевно, не те, що ти хочеш
hadley

27

Ви також можете спробувати щось на кшталт:

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

4
Сенс полягає в тому, щоб уникнути розхитування значень x при завантаженні.
Райан К. Томпсон

2

У випадку, якщо хтось хоче зробити це з простого вихідного файлу, а не із збереженим файлом 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] "Значення arg дорівнює 7"

І в окремому вихідному файлі TestSourceFile.R

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

Знову ж таки, це рішення працює лише за наявності саме одного файлу, якщо їх більше, то він просто поверне один з них (можливо, перший, але це не гарантується).


1

Я розширюю відповідь від @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')


1

Файл Rdata з одним об'єктом

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

1
Чи не завантажить цей об’єкт у стару назву, а потім також призначить його новому імені? Це не допоможе, якщо я переживаю за можливість перезапису існуючої змінної.
Райан К. Томпсон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.