Bagaimana cara memuat objek ke dalam nama variabel yang saya tentukan dari file data R?

97

Saat Anda menyimpan variabel dalam file data R menggunakan save, itu disimpan dengan nama apa pun yang dimilikinya di sesi yang menyimpannya. Ketika saya nanti akan memuatnya dari sesi lain, itu dimuat dengan nama yang sama, yang mungkin tidak diketahui oleh skrip pemuatan. Nama ini dapat menimpa variabel yang ada dengan nama yang sama di sesi pemuatan. Apakah ada cara untuk memuat objek dengan aman dari file data ke dalam nama variabel tertentu tanpa risiko mengganggu variabel yang ada?

Contoh:

Sesi penyimpanan:

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

Memuat sesi:

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

Bagaimana saya ingin bekerja:

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

Jawaban:

93

Jika Anda hanya menyimpan satu objek, jangan gunakan .Rdatafile, gunakan .RDSfile:

x <- 5
saveRDS(x, "x.rds")
y <- readRDS("x.rds")
all.equal(x, y)
hadley
sumber
Diperbarui untuk mencerminkan bahwa di 2.13, ini tidak lagi eksperimental.
hadley
Apakah itu berarti mereka didukung penuh, seperti file .Rdata?
Ryan C. Thompson
Karena ini bukan lagi percobaan, saya tandai ini sebagai jawaban yang diterima. Inilah yang saya gunakan.
Ryan C. Thompson
Apakah saveRDSdan readRDS, terkait, menyimpan dan memulihkan semua atribut objek, termasuk yang dibuat oleh aplikasi (melalui attr)? Saya mencoba menggunakan pendekatan ini daripada savedan load, mencoba menemukan solusi untuk masalah saya. Namun, tampaknya tidak demikian, kecuali saya melakukan sesuatu yang salah: stackoverflow.com/questions/23701195/… .
Aleksandr Blekh
37

Saya menggunakan yang berikut ini:

loadRData <- function(fileName){
#loads an RData file, and returns it
    load(fileName)
    get(ls()[ls() != "fileName"])
}
d <- loadRData("~/blah/ricardo.RData")
Ricardo
sumber
1
Ini adalah fungsi kecil yang bagus. Mengalami masalah saat mencoba memuat sesuatu (tidak ingin menempatkannya di lingkungan global karena saya tahu itu akan menjadi masalah.
Trevor Nederlof
4
Sesuatu seperti ini termasuk dalam basis R
Repmat
1
OH TUHAN. Ini luar biasa. Hanya yang saya butuhkan! #loveit
Sander W. van der Laan
Bisakah Anda memperluas logika pernyataan GET? Mengapa tidak mencocokkan dengan FILENAME alih-alih mengecualikan?
nnachefski
35

Anda dapat membuat lingkungan baru, memuat file .rda ke lingkungan tersebut, dan mengambil objek dari sana. Namun, hal ini memberlakukan beberapa batasan: entah Anda tahu apa nama asli objek Anda, atau hanya ada satu objek yang disimpan di file.

Fungsi ini mengembalikan objek yang dimuat dari file .rda yang disediakan. Jika ada lebih dari satu objek dalam file, satu objek akan dikembalikan.

load_obj <- function(f)
{
    env <- new.env()
    nm <- load(f, env)[1]
    env[[nm]]
}
Hong Ooi
sumber
3
Apakah new.envbenar - benar perlu? Bukankah panggilan fungsi itu sendiri menyediakan lingkungan sementara?
Ryan C. Thompson
Anda dapat mengembalikan seluruh lingkungan (return (env) atau return (environment ()) saat Anda memodifikasi fungsi sesuai dengan saran @Ryan).
Wojciech Sobala
2
Jika Anda menggunakan fungsi lingkungan itu akan berisi f dan memiliki orang tua. Mungkin bukan yang Anda inginkan
hadley
27

Anda juga bisa mencoba sesuatu seperti:

# 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)
oleh0
sumber
4
Intinya adalah untuk menghindari menggumpal nilai x saat memuat.
Ryan C. Thompson
2

Jika ada yang ingin melakukan ini dengan file sumber biasa, daripada file Rdata / RDS / Rda yang disimpan, solusinya sangat mirip dengan yang disediakan oleh @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)

Cetakan:

[1] "Nilai arg adalah 7"

Dan dalam file sumber terpisah TestSourceFile.R

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

Sekali lagi, solusi ini hanya berfungsi jika hanya ada satu file, jika ada lebih banyak, maka itu hanya akan mengembalikan salah satunya (mungkin yang pertama, tetapi itu tidak dijamin).

pengguna2711915
sumber
1

Saya memperluas jawaban dari @ricardo untuk memungkinkan pemilihan variabel tertentu jika .Rdatafile tersebut berisi banyak variabel (karena kredit saya rendah untuk mengedit jawaban). Ia menambahkan beberapa baris untuk membaca masukan pengguna setelah mencantumkan variabel yang terdapat dalam .Rdatafile.

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
sumber
1

File rdata dengan satu objek

assign('newname', get(load('~/oldname.Rdata')))
Javier Acosta
sumber
1
Tidakkah ini akan memuat objek ke nama lama, dan kemudian juga menetapkannya ke nama baru juga? Itu tidak akan membantu jika saya khawatir tentang kemungkinan menimpa variabel yang ada.
Ryan C. Thompson