【问题标题】:Passing multiple lists of arguments through rlang quosures and dplyr通过 rlang quosures 和 dplyr 传递多个参数列表
【发布时间】:2017-10-23 18:53:01
【问题描述】:

目标:编写一个将数据帧作为第一个数据帧的函数 参数,然后是两个附加参数,参数列表,传递给 dplyr::select 这样函数将返回两个数据帧。

这是一个工作示例

my_select <- function(.data, df1, df2) {
  DF1 <- dplyr::select(.data, rlang::UQS(df1))
  DF2 <- dplyr::select(.data, rlang::UQS(df2))
  list(DF1 = DF1, DF2 = DF2)
}

working_eg <-
  my_select(mtcars,
          df1 = alist(dplyr::contains("r"), dplyr::matches("^.p.*")),
          df2 = alist(disp))

str(working_eg, max.length = 1L)

## List of 2
##  $ DF1:'data.frame': 32 obs. of  5 variables:
##   ..$ drat: num [1:32] 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
##   ..$ gear: num [1:32] 4 4 4 3 3 3 3 4 4 4 ...
##   ..$ carb: num [1:32] 4 4 1 1 2 1 4 2 2 4 ...
##   ..$ mpg : num [1:32] 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
##   ..$ hp  : num [1:32] 110 110 93 110 175 105 245 62 95 123 ...
##  $ DF2:'data.frame': 32 obs. of  1 variable:
##   ..$ disp: num [1:32] 160 160 108 258 360 ...

我希望参数 df1df2 采用 list 而不是 alist。 但是,如果参数是 list,函数 my_select 将失败

my_select(mtcars,
          df1 = list(dplyr::contains("r"), dplyr::matches("^.p.*")),
          df2 = list(disp))
## Error: Variable context not set

如果可能的话,我不想让最终用户使用alist,因为我没有 测试 alist 用于传递参数而不是 list 的好方法。

我尝试了rlang::UQrlang::UQErlang::UQS 的几种组合 使用rlang::quorlang::enquosrlang::quos 来解决此问题。我什么 认为最好的方法是:

my_select2 <- function(.data, df1, df2) {
  DF1 <- dplyr::select(.data, rlang::UQS(rlang::quos(df1)))
  DF2 <- dplyr::select(.data, rlang::UQS(rlang::quos(df2)))
  list(DF1 = DF1, DF2 = DF2)
}

my_select2(mtcars,
          df1 = list(dplyr::contains("r"), dplyr::matches("^.p.*")),
          df2 = list(disp))
## Error: `df1` must resolve to integer column positions, not a list

有没有办法使用rlang 使用dplyr 打包,以便 my_select2 的语法将返回与 my_select 相同的对象 参数通过alist?

packageVersion("dplyr")
# [1] ‘0.7.4’
packageVersion("rlang")
# [1] ‘0.1.2’

【问题讨论】:

  • 如果有人试图做 x &lt;- list(dplyr::contains("r"), dplyr::matches("^.p.*")); y&lt;- list(disp); my_select2(mtcars, x, y) 怎么办,因为那你真的遇到了麻烦,因为那些第一个任务永远不会与 list() 一起工作,但会与 alist() 一起工作。
  • 由于您使用的是dplyr(),因此您可能应该在这里使用vars() 而不是list()alist()。这与它在包的其余部分中的使用方式是一致的。
  • 我太专注于 dplyr (&gt;= 0.7.0)rlang 的变化,以至于忘记了 dplyr::vars()。这就是答案。谢谢你,@MrFlick。我会发布解决方案。

标签: r dplyr rlang


【解决方案1】:

@MrFlick 的评论是我需要解决问题和改进 api 的提醒。

my_select3 <- function(.data, df1, df2) {
  DF1 <- dplyr::select(.data, rlang::UQS((df1)))
  DF2 <- dplyr::select(.data, rlang::UQS((df2)))
  list(DF1 = DF1, DF2 = DF2)
}

working_eg2 <-
  my_select3(mtcars,
            df1 = dplyr::vars(dplyr::contains("r"), dplyr::matches("^.p.*")),
            df2 = dplyr::vars(disp))

all.equal(working_eg, working_eg2)
# [1] TRUE

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多