【问题标题】:Evaluate args of a function call and convert the call to a character vector in R评估函数调用的参数并将调用转换为 R 中的字符向量
【发布时间】:2013-12-30 18:32:19
【问题描述】:

我正在尝试编写一个函数,该函数将函数调用作为参数,评估此函数调用的数字参数,然后返回相应的字符向量。这就是我想出的:

ConvertToCharacter <- function(function.call) {
  call.str <- deparse(substitute(function.call))
  return(call.str)
}

> a <- 1
> ConvertToCharacter(sum(2, a))
"sum(2, a)"

> ConvertToCharacter(ddply(mtcars, .(vs), summarize, col=mean(cyl)))
"ddply(mtcars, .(vs), summarize, col = mean(cyl))"

现在,我希望在将数字参数转换为字符向量之前对其进行评估。因此 ConvertToCharacter(sum(2, a)) 将返回“sum(2, 1)”。我尝试将 env=parent.frame() 传递给替换,但它不起作用。知道我该怎么做吗?

谢谢!

【问题讨论】:

    标签: r function-call expression-evaluation


    【解决方案1】:

    您需要递归地检查您的调用,评估符号,并像这样在数值中插入数值:

    ConvertToCharacter <- function(function.call, env=parent.frame()) {  
      call <- substitute(function.call)
      convert_recurse <- function(x, env) {
        if(is.call(x)) {
          return(as.call(lapply(x, match.fun(sys.call()[[1]]), env=env)))
        } else if (
          is.symbol(x) && 
          is.numeric(try(val <- eval(x, env), silent=TRUE))
        ) {
          return(val)
        } else {
          return(x)
        }    
      }
      deparse(convert_recurse(call, env))
    }
    a <- 1
    ConvertToCharacter(sum(2, a))
    lbsToKgs <- 2.2  
    ConvertToCharacter(ddply(mtcars, .(vs), summarize, col=mean(cyl), wtkg=mean(wt * lbsToKgs)))
    

    这就是你得到的:

    # [1] "sum(2, 1)"         
    # [1] "ddply(mtcars, .(vs), summarize, col = mean(cyl), wtkg = mean(wt * "
    # [2] "    2.2))"
    

    另外,感谢 Robert 提供的解决方法 apply/Recall issue

    【讨论】:

    • 太棒了!只是好奇你为什么要参加 match.fun。为什么不简单地 lapply(x, convert_recurse, env=env) 似乎有效?再次感谢您的出色解决方案!
    • 这样,如果你在某个时候重命名函数,你也不必更新内部代码。通常这是使用Recall 完成的,但这在这里不起作用。
    【解决方案2】:
    ConvertToCharacter <- function(function.call) {
    library(stringr)
    str_replace(deparse(substitute(function.call)),"a",eval(a,envir=.GlobalEnv))
    }
    

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 2020-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-21
      • 1970-01-01
      • 1970-01-01
      • 2021-05-21
      相关资源
      最近更新 更多