ฉันจะโหลดออบเจ็กต์เป็นชื่อตัวแปรที่ฉันระบุจากไฟล์ข้อมูล 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 สิ่งเหล่านี้ไม่ใช่การทดลองอีกต่อไป
hadley

หมายความว่าได้รับการสนับสนุนอย่างสมบูรณ์เช่นเดียวกับไฟล์. RData หรือไม่
Ryan

เนื่องจากสิ่งเหล่านี้ไม่ใช่การทดลองอีกต่อไปฉันจึงทำเครื่องหมายว่าเป็นคำตอบที่ยอมรับ นี่คือสิ่งที่ฉันใช้
Ryan

ทำsaveRDSและreadRDSบันทึกและกู้คืนแอตทริบิวต์ของวัตถุทั้งหมดรวมถึงสิ่งที่สร้างโดยแอปพลิเคชัน (ผ่านattr) ด้วยหรือไม่ ฉันพยายามใช้วิธีนี้แทนsaveและloadพยายามหาวิธีแก้ปัญหาสำหรับปัญหาของฉัน ดูเหมือนจะไม่เป็นเช่นนั้นเว้นแต่ฉันจะทำอะไรผิด: stackoverflow.com/questions/23701195/… .
Aleksandr Blekh

38

ฉันใช้สิ่งต่อไปนี้:

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

1
นี่เป็นฟังก์ชั่นเล็ก ๆ น้อย ๆ ที่ยอดเยี่ยม กำลังมีปัญหากับการพยายามโหลดสิ่งต่างๆเข้ามา (ไม่ได้ต้องการแค่ให้มันอยู่ในสภาพแวดล้อมระดับโลกอย่างที่ฉันรู้ว่ามันจะมีปัญหา
Trevor Nederlof

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สิ่งที่จำเป็นจริงๆ? ฟังก์ชันเรียกตัวเองไม่ได้จัดเตรียมสภาพแวดล้อมชั่วคราวหรือไม่?
Ryan

คุณสามารถคืนสภาพแวดล้อมทั้งหมด (return (env) หรือ return (environment ()) เมื่อคุณแก้ไขฟังก์ชันตามคำแนะนำของ @Ryan)
Wojciech Sobala

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 เมื่อโหลด
Ryan C. Thompson

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
สิ่งนี้จะไม่โหลดออบเจ็กต์เป็นชื่อเก่าแล้วกำหนดให้เป็นชื่อใหม่ด้วยหรือไม่? นั่นจะไม่ช่วยอะไรถ้าฉันกังวลเกี่ยวกับความเป็นไปได้ในการเขียนทับตัวแปรที่มีอยู่
Ryan C. Thompson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.