ใน R จะรับชื่อวัตถุหลังจากส่งไปยังฟังก์ชันได้อย่างไร?


139

ฉันกำลังมองหาสิ่งที่ตรงกันข้ามของget().

เมื่อระบุชื่อวัตถุฉันต้องการให้สตริงอักขระที่เป็นตัวแทนของวัตถุนั้นแยกออกจากวัตถุโดยตรง

ตัวอย่างเล็กน้อยกับfooการเป็นตัวยึดสำหรับฟังก์ชันที่ฉันกำลังมองหา

z <- data.frame(x=1:10, y=1:10)

test <- function(a){
  mean.x <- mean(a$x)
  print(foo(a))
  return(mean.x)}

test(z)

จะพิมพ์:

  "z"

วิธีแก้ปัญหาของฉันซึ่งยากที่จะนำไปใช้ในปัญหาปัจจุบันของฉันคือ:

test <- function(a="z"){
  mean.x <- mean(get(a)$x)
  print(a)
  return(mean.x)}

test("z")

35
ฉันคิดdeparse(substitute(...))ว่าคุณเป็นอย่างนั้น
Chase

2
ตัวอย่างที่ไม่ดีแม้ว่าจะมีตัวแปรที่เรียกว่า "Z" และพารามิเตอร์ในการทดสอบยังเรียกว่า "Z" ... พิมพ์ "Z" ไม่ได้จริงๆบอกคุณถ้าคุณคิดว่ามันถูกต้องแล้ว ;-)
ทอมมี่

@ ทอมมี่พยายามปรับปรุง แต่โปรดปรับปรุงแก้ไขหากต้องการ
Etienne Low-Décarie

สิ่งที่ตรงกันข้ามกับgetใน R คือassignแต่ฉันไม่แน่ใจว่านั่นคือสิ่งที่คุณกำลังมองหาจริงๆ ...
Tom Kelly

คำตอบ:


163

เคล็ดลับการทดแทนแบบเก่า:

a<-data.frame(x=1:10,y=1:10)
test<-function(z){
   mean.x<-mean(z$x)
   nm <-deparse(substitute(z))
   print(nm)
   return(mean.x)}

 test(a)
#[1] "a"   ... this is the side-effect of the print() call
#          ... you could have done something useful with that character value
#[1] 5.5   ... this is the result of the function call

แก้ไข: เรียกใช้ด้วย test-object ใหม่

หมายเหตุ: สิ่งนี้จะไม่ประสบความสำเร็จในฟังก์ชันโลคัลเมื่อชุดของรายการถูกส่งจากอาร์กิวเมนต์แรกไปยังlapply(และจะล้มเหลวเมื่อวัตถุถูกส่งผ่านจากรายการที่กำหนดให้ a for-loop) คุณจะสามารถแยก ".Names" - แอตทริบิวต์และลำดับของการประมวลผลจากผลลัพธ์ของโครงสร้างหากเป็นเวกเตอร์ที่มีชื่อที่กำลังประมวลผล

> lapply( list(a=4,b=5), function(x) {nm <- deparse(substitute(x)); strsplit(nm, '\\[')} )
$a
$a[[1]]
[1] "X"    ""     "1L]]"


$b
$b[[1]]
[1] "X"    ""     "2L]]"

> lapply( c(a=4,b=5), function(x) {nm <- deparse(substitute(x)); strsplit(nm, '\\[')} )
$a
$a[[1]]
[1] "structure(c(4, 5), .Names = c(\"a\", \"b\"))" ""                                            
[3] "1L]]"                                        


$b
$b[[1]]
[1] "structure(c(4, 5), .Names = c(\"a\", \"b\"))" ""                                            
[3] "2L]]"  

13
deparse(quote(var))

ความเข้าใจโดยสัญชาตญาณของฉันซึ่งคำพูดจะตรึง var หรือนิพจน์จากการประเมินผลและฟังก์ชัน deparse ซึ่งเป็นฟังก์ชันผกผันของฟังก์ชันแยกวิเคราะห์ทำให้สัญลักษณ์ที่ตรึงนั้นกลับไปเป็น String


6

โปรดทราบว่าสำหรับวิธีการพิมพ์ลักษณะการทำงานอาจแตกต่างกัน

print.foo=function(x){ print(deparse(substitute(x))) }
test = list(a=1, b=2)
class(test)="foo"
#this shows "test" as expected
print(test)

#this (just typing 'test' on the R command line)
test
#shows
#"structure(list(a = 1, b = 2), .Names = c(\"a\", \"b\"), class = \"foo\")"

ความคิดเห็นอื่น ๆ ที่ฉันเคยเห็นในฟอรัมแสดงให้เห็นว่าพฤติกรรมสุดท้ายเป็นสิ่งที่หลีกเลี่ยงไม่ได้ นี่เป็นเรื่องโชคร้ายหากคุณกำลังเขียนวิธีการพิมพ์สำหรับบรรจุภัณฑ์


บางทีมันควรจะเป็น: print.foo=function(x){ cat(deparse(substitute(x))) }หรือprint.foo=function(x){ print(deparse(substitute(x)), quote=FALSE) }
IRTFM

1
หรือprint.foo=function(x){ print.default(as.list(x)) }
IRTFM

as.list()จะไม่ทำงานเนื่องจาก "การทดสอบ" อาจเป็นอะไรก็ได้ ฉันเพิ่งใช้รายการในตัวอย่างของเล่นของฉัน
Eli Holmes

อัปเดต R 3.6 ขณะนี้มีการเปลี่ยนแปลงพฤติกรรมเล็กน้อย แต่ก็ยังไม่ได้รับการแก้ไข print(test)สร้างtestในขณะtestที่บรรทัดคำสั่งสร้างx(ไม่ใช่testตามที่คุณต้องการ) ทั้งหมดนี้มีพฤติกรรมเหมือนกัน print.foo=function(x){ print(deparse(substitute(x))) }หรือprint.foo=function(x){ cat(deparse(substitute(x))) }หรือprint.foo=function(x){ print(deparse(substitute(x)), quote=FALSE) }
Eli Holmes
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.