【问题标题】:In R, how to get an object's name after it is sent to a function?在 R 中,如何在将对象发送到函数后获取对象的名称?
【发布时间】:2016-03-22 19:41:52
【问题描述】:

我正在寻找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")

【问题讨论】:

  • 我认为deparse(substitute(...)) 是你所追求的
  • 虽然变量名为“z”,而用于测试的参数 also 名为“z”……但打印“z”并不能真正告诉您是否那你做对了;-)
  • @Tommy,尝试改进它,但如果您愿意,请通过编辑进行改进。
  • R 中 get 的反义词是 assign,但我不确定这是否是您真正想要的...

标签: r


【解决方案1】:

详细说明 Eli Holmes 的回答:

  1. myfunc 效果很好
  2. 我很想在另一个函数中调用它(正如他在 20 年 8 月 15 日的评论中所讨论的)
  3. 失败
  4. 函数中,直接编码(而不是从外部函数调用),deparse(substitute() 技巧很有效。
  5. 这一切都隐含在他的回答中,但为了便于窥视我的健忘程度,我想把它拼出来。
an_object <- mtcars
myfunc <- function(x) deparse(substitute(x))

myfunc(an_object)
#> [1] "an_object"

# called within another function 
wrapper <- function(x){
  myfunc(x)
}

wrapper(an_object)
#> [1] "x"

【讨论】:

    【解决方案2】:

    旧的 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      # This "a" and the next one in the print output are put in after processing
    $a[[1]]
    [1] "X"    ""     "1L]]"  # Notice that there was no "a"
    
    
    $b
    $b[[1]]
    [1] "X"    ""     "2L]]"
    
    > lapply( c(a=4,b=5), function(x) {nm <- deparse(substitute(x)); strsplit(nm, '\\[')} )
    $a
    $a[[1]]   # but it's theoretically possible to extract when its an atomic vector
    [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]]"  
    

    【讨论】:

      【解决方案3】:

      请注意,对于打印方法,行为可能会有所不同。

      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\")"
      

      我在论坛上看到的其他 cmets 表明最后一种行为是不可避免的。如果您正在为包编写打印方法,这将是不幸的。

      【讨论】:

      • 或许应该是:print.foo=function(x){ cat(deparse(substitute(x))) }print.foo=function(x){ print(deparse(substitute(x)), quote=FALSE) }
      • print.foo=function(x){ print.default(as.list(x)) }
      • as.list() 不起作用,因为“测试”可以是任何东西。我只是在我的玩具示例中使用了一个列表。
      • 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) }
      【解决方案4】:
      deparse(quote(var))
      

      我的直觉理解 其中报价冻结了评估中的 var 或表达式 和解析函数的逆解析函数使冻结的符号回到字符串

      【讨论】:

        猜你喜欢
        • 2012-05-18
        • 1970-01-01
        • 1970-01-01
        • 2022-11-19
        • 1970-01-01
        • 2017-12-16
        • 1970-01-01
        • 1970-01-01
        • 2011-02-23
        相关资源
        最近更新 更多