Rで、関数に送信された後にオブジェクトの名前を取得するにはどうすればよいですか?


135

の逆を探しています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(...))はあなたが何を
チェイス

2
変数 "z"とテストするパラメーター "z"と呼ばれるのは悪い例ですが、 "z"を印刷しても、正しく実行したかどうかはわかりません;-)
Tommy

@トミー、それを改善しようとしましたが、必要に応じて編集して改善してください。
エティエンヌローデカリ

反対getRではあるassignが、私はあなたが本当に探しているものの...ということはないよ
トム・ケリー

回答:


160

古いdeparse-substituteトリック:

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

編集:新しいテストオブジェクトで実行しました

注:これは、一連のリストアイテムが最初の引数からに渡された場合、ローカル関数内では成功しませんlapply(また、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]]"  

11
deparse(quote(var))

私の直感的な理解では、引用が評価からvarまたは式をフリーズし、解析関数の逆であるデパース関数は、そのフリーズされたシンボルを文字列に戻します


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 shows 
#"structure(list(a = 1, b = 2), .Names = c(\"a\", \"b\"), class = \"foo\")"
test

私がフォーラムで見た他のコメントは、最後の行動が避けられないことを示唆しています。パッケージの印刷メソッドを作成している場合、これは残念です。


おそらく次のようになります:print.foo=function(x){ cat(deparse(substitute(x))) }またはprint.foo=function(x){ print(deparse(substitute(x)), quote=FALSE) }
IRTFM 2013年

1
またはprint.foo=function(x){ print.default(as.list(x)) }
IRTFM 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.