【问题标题】:custom function not accepting arguments with rlang::enquo [duplicate]自定义函数不接受带有 rlang::enquo 的参数 [重复]
【发布时间】:2018-02-02 19:05:12
【问题描述】:

我正在编写一个自定义函数,该函数需要从输入的参数中创建一个数据框。我希望用户允许两种不同的方式输入参数。正如您在下面看到的,其中一种方法是有效的,但不是依赖于rlang 的方法。

我的想法是,我想为函数用户提供尽可能多的灵活性,因此可以使用可选参数和两种不同的方法来输入参数。

这是一个可重现的代码:

# loading libraries
library(dplyr)
library(rlang)
library(datasets)

# preparing the dataset
iris <- datasets::iris
iris$newvar <- 1:length(iris$Sepal.Length)
str(iris)
#> 'data.frame':    150 obs. of  6 variables:
#>  $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
#>  $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
#>  $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
#>  $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
#>  $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
#>  $ newvar      : int  1 2 3 4 5 6 7 8 9 10 ...

# defining the custom function
myfun <- function(data = NULL, x, y, z = NULL) {
  if (!is.null(data)) {
    if (!is.null(z)) {
      data <-
        dplyr::select(
          .data = data,
          x = !!rlang::enquo(x),
          y = !!rlang::enquo(y),
          z = !!rlang::enquo(z)
        )
    } else {
      data <-
        dplyr::select(
          .data = data,
          x = !!rlang::enquo(x),
          y = !!rlang::enquo(y)
        )
    }
  } else {
    if (!is.null(z)) {
      data <-
        base::cbind.data.frame(x = x,
                               y = y,
                               z = z)
    } else {
      data <- base::cbind.data.frame(x = x,
                             y = y)
    }
  }

  print(str(data))

}

# method 1
# using the custom fuction without the optional argument
myfun(x = iris$Species, y = iris$Sepal.Length)
#> 'data.frame':    150 obs. of  2 variables:
#>  $ x: Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
#>  $ y: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
#> NULL

# using the custom fuction with the optional argument
myfun(x = iris$Species, y = iris$Sepal.Length, z = iris$newvar)
#> 'data.frame':    150 obs. of  3 variables:
#>  $ x: Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
#>  $ y: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
#>  $ z: int  1 2 3 4 5 6 7 8 9 10 ...
#> NULL

# method 2
# using the custom fuction without the optional argument
myfun(data = iris, x = Species, y = Sepal.Length)
#> 'data.frame':    150 obs. of  2 variables:
#>  $ x: Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
#>  $ y: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
#> NULL
# using the custom fuction with the optional argument
myfun(data = iris,
      x = Species,
      y = Sepal.Length,
      z = newvar)
#> Error in myfun(data = iris, x = Species, y = Sepal.Length, z = newvar): object 'newvar' not found

reprex package (v0.1.1.9000) 于 2018 年 2 月 2 日创建。

【问题讨论】:

  • @MrFlick 是的!这解决了这个问题。非常感谢!
  • @MrFlick 我如何接受您的回答?它没有向我显示任何将您的评论作为正确答案的选项。
  • 因为它基本上是重复的。我可以将这个问题作为一个副本关闭。如果您愿意,可以投票支持我对另一个问题的回答。
  • @MrFlick 完成!谢谢。

标签: r dplyr tidyverse rlang


【解决方案1】:

似乎测试!is.null(z)) 失败了。它试图解释z,但z 设置为名称newvar,并且is.null 调用无法解释它,因为找不到newvar 对象。

试试这个吧:

!is.null(quo(z)))

【讨论】:

  • 感谢您的建议。这似乎确实解决了我面临的问题,但产生了不同的问题。如果我现在输入:myfun(data = iris, x = Species, y = Sepal.Length),它会给我以下错误:Error: NULL must resolve to integer column positions, not NULL
  • 有趣的问题。如果您删除定义中z 的NULL 分配,myfun(data = iris, x = Species, y = Sepal.Length) 将起作用。但是,另一种形式的调用则没有。嗯。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-01
  • 2016-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-30
  • 1970-01-01
相关资源
最近更新 更多