Як я можу завантажити об'єкт у ім'я змінної, яке я вказав у файлі даних 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.