【问题标题】:In R is there a way to escape the substitute() function?在 R 中有没有办法逃避替代()函数?
【发布时间】:2019-10-24 07:19:15
【问题描述】:

我遇到了一个包,它使用substitute 函数来解析其中一个函数中的参数。 使用的函数或多或少如下:

f <- function(...) {
    ref <- as.list(substitute(list(...))[-1])
    # for clarity
    print(ref)
    counter <- 0L
    for (i in ref) {
        if (as.character(i[1]) == "==") {
            counter <- counter + 1L
        }
    }
    return(counter)
}


f(df1$a == df1$b, df1$b == df1$c)
#> [[1]]
#> df1$a == df1$b
#> 
#> [[2]]
#> df1$b == df1$c
#> [1] 2

reprex package (v0.3.0) 于 2019 年 10 月 24 日创建

我想将df1$a == df1$b, df1$b == df1$c 作为一个字符传递,但我找不到方法来实现它,因为我无法覆盖substitute 函数。到目前为止,我已经尝试了一些选项,但它们似乎都不起作用:

char <- "df1$a == df1$b, df1$b == df1$c"

f(get(char))
#> [[1]]
#> get(char)
#> [1] 0
f(parse(text = char))
#> [[1]]
#> parse(text = char)
#> [1] 0
f(eval(parse(text = char)))
#> [[1]]
#> eval(parse(text = char))
#> [1] 0

reprex package (v0.3.0) 于 2019 年 10 月 24 日创建

编辑:

在@Roland 的回答解决了我最初的问题之后,我想知道是否还有一种简单的方法可以通过使用另一个参数的函数来解决稍微更一般的情况:

f2 <- function(parameter, ...) {
  ref <- as.list(substitute(list(...))[-1])
  # for clarity
  print(ref)
  counter <- 0L
  for (i in ref) {
    if (as.character(i[1]) == "==") {
      counter <- counter + 1L
    }
  }
  return(counter)
}

【问题讨论】:

  • 只要do.call(f2, c(list(parameter = somevalue), char))
  • @Roland 非常感谢您再次及时回复。我从未使用过substitute,也很少使用do.call。它非常适合这种情况。

标签: r


【解决方案1】:

你不能脱离substitute。这是不可能的,因为没有评估函数参数。但你可以这样做:

char <- "df1$a == df1$b, df1$b == df1$c"

#turn char into list of language objects
char <- strsplit(char, ",", fixed = TRUE)[[1]]
char <- as.list(parse(text = char))

#pass to f
do.call(f, char)
#[[1]]
#df1$a == df1$b
#
#[[2]]
#df1$b == df1$c
#
#[1] 2

【讨论】:

  • 非常感谢它为我工作。我将编辑该问题,以采用更通用的方式,包括函数中的另一个参数。我使用了一个包装器,但我想知道是否有更好的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-16
  • 2010-10-14
  • 1970-01-01
  • 1970-01-01
  • 2021-12-19
相关资源
最近更新 更多