【问题标题】:R6 pass a self$FUN as parameterR6 传递一个 self$FUN 作为参数
【发布时间】:2020-10-01 10:09:06
【问题描述】:

我开始构建一个“用户友好”的 R6 类,并希望创建一个函数来完成我类的大部分工作。这是我目前的结构

x <- X$new()
veggie_cubes <- veggie %>% x$cubesX(ID)
veggie_slices <- veggie %>% x$sliceX(ID)

我现在的问题是是否可以重写代码:

x <- X$new()
veggie_cubes <- veggie %>% x$cutX(cubesX, ID)
veggie_slices <- veggie %>% x$cutX(sliceX, ID)

函数头应该看起来像:cut(.data, FUN, KEY)

到目前为止,我的想法是写cut 喜欢:

cutX= function(.data, FUN, KEY)
{
   .data %>%
     FUN({{ KEY }}) %>%
     base::return()
}

唯一可行的方法是调用veggie %&gt;% x$cutX(x$cubesX, ID),我不太喜欢作为“用户友好”的解决方案,我也不太喜欢为此使用字符串。没有x$有没有办法写?

这里是简化的 R6 类:

X <- R6::R6Class(
  classname = "X",
  public = base::list(
    cubesX = function(.data, KEY)
    {
      .data %>% 
        dplyr::select(!{{ KEY }}) %>% 
        base::return()
    },
    sliceX = function(.data, KEY)
    {
      .data %>% 
        dplyr::select({{ KEY }}) %>% 
        base::return()
    },
    cutX = function(.data, FUN, KEY)
    {
      .data %>% 
        FUN( {{ KEY}}) %>% 
        base::return()
    }
  )
)

运行示例:

x <- X$new()
iris %>% x$sliceX(Species)
iris %>% x$cubesX(Species)
# with FUN
iris %>% x$cutX(x$sliceX, Species)
iris %>% x$cutX(x$cubesX, Species)

没有运行:

iris %>% x$cutX(sliceX, Species)
iris %>% x$cutX(cubesX, Species)

在此先感谢 :-)

【问题讨论】:

  • 你能发布你的R6类定义的代码吗?

标签: r r6


【解决方案1】:

以下实现将允许您通过三种方法中的任何一种调用您的函数。它通过使用非标准评估来确定FUN 的格式是x$func 还是仅仅是func。在任何一种情况下,它都采用裸函数名并构建一个调用以将其转换为self$func。然后它只是评估那个函数。

因此,以下 R6 类在您的所有测试示例中都可以正常工作:

X <- R6::R6Class(
  classname = "X",
  public = base::list(
    cubesX = function(.data, KEY)
    {
      .data %>% 
        dplyr::select(!{{ KEY }}) %>% 
        base::return()
    },
    sliceX = function(.data, KEY)
    {
      .data %>% 
        dplyr::select({{ KEY }}) %>% 
        base::return()
    },
    cutX = function(.data, FUN, KEY)
    {
      if(is.call(substitute(FUN))) {
        FUN <- substitute(FUN) 
        FUN[[2]] <- quote(self)
      }
      else 
        FUN <- as.call(list(quote(`$`), quote(self), substitute(FUN)))
 
      eval(as.call(list(FUN, quote(.data), substitute(KEY))))
    }
  )
)

所以,例如:

x <- X$new()
iris %>% x$cutX(sliceX, Species)

#>        Species
#> 1       setosa
#> 2       setosa
#> 3       setosa
#> 4       setosa
#> 5       setosa
#> 6       setosa
#> 7       setosa
#> 8       setosa
#> 9       setosa
#> 10      setosa
#> 11      setosa
#> 12      setosa
#> 13      setosa
#> 14      setosa
#> 15      setosa
#> 16      setosa
#> 17      setosa
#> 18      setosa
#> 19      setosa
#> 20      setosa
#> ...etc

【讨论】:

    猜你喜欢
    • 2021-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-15
    • 2021-10-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多