【问题标题】:R: non standard evaluation of argumentsR:参数的非标准评估
【发布时间】:2021-07-12 20:10:00
【问题描述】:

我希望将 expression 对象传递给函数,以便其 substitute 给出相同的结果 - 并且似乎无法正确处理。

f1 <- function(x) { 
  print(substitute(x))         # a + 1 
  print(class(substitute(x)))  # "call"
  f2(x)
}

f2 <- function(y) {
  print(substitute(y))         # x
  print(class(substitute(y)))  # "name"
}

f1(a+1)

这里发生了什么?为什么substitute 的类和值存在差异?

有没有办法在 R 中实现“完美转发”(即按原样将表达式传递给函数)?

【问题讨论】:

  • 也许这有帮助:stackoverflow.com/questions/52876164/…>
  • 1. 由于惰性求值,变量 x 被传递到 f2 函数中,因此具有 f2 打印 x 2) 不,由于惰性,您不能按原样进行转发对承诺的评价。请注意,只有在需要时才会评估变量

标签: r


【解决方案1】:

最终这两个函数调用是

f1(a+1)
f2(x)

a 或 x 中的实际内容无关紧要,这就是所有函数 f1 和 f2 看看它们何时被调用。在一种情况下,您传递的是a+1,这是对+ 函数的调用。在另一个你只是传递x 这只是一个符号名称。 R 对这两种情况的处理方式不同,因此它们具有不同的类别。

class(quote(a+1))
# [1] "call"
class(quote(a))
# [1] "name"

如果你想要“完美”的转发,那么最简单的方法就是不要在 inter 函数中捕获变量并通过... 机制传递它。

f1 <- function(...) { 
  f2(...)
}

f2 <- function(y) {
  print(substitute(y))         # x
  print(class(substitute(y)))  # "name"
}

f1(a+1)
# a + 1
# [1] "call"

否则substitute() 会将未计算的表达式存储在变量中,但是如果您想将该表达式扩展回函数调用,则需要使用类似do.call() 的东西

f1 <- function(x) { 
  sx <- substitute(x)
  print(sx)
  print(class(sx))  # "call"
  
  do.call("f2", list(sx))
}

f2 <- function(y) {
  print(substitute(y))         # x
  print(class(substitute(y)))  # "name"
}

f1(a+1)
# a + 1
# [1] "call"
# a + 1
# [1] "call"

【讨论】:

    猜你喜欢
    • 2016-09-18
    • 1970-01-01
    • 2018-08-01
    • 2019-09-18
    • 1970-01-01
    • 1970-01-01
    • 2019-11-29
    • 1970-01-01
    • 2019-11-11
    相关资源
    最近更新 更多