通过 rlang quosures 和 dplyr 传递多个参数列表
Passing multiple lists of arguments through rlang quosures and dplyr
Objective: 编写一个函数,将数据帧作为第一个
参数,然后是两个附加参数,参数列表,传递给
dplyr::select
这样函数将 return 两个数据帧。
这是一个工作示例
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 ...
我希望参数 df1
和 df2
采用 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::UQ
、rlang::UQE
、rlang::UQS
的几种组合
使用 rlang::quo
、rlang::enquos
和 rlang::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
的语法将 return 与 my_select
相同的对象
参数通过 alist
?
传递
packageVersion("dplyr")
# [1] ‘0.7.4’
packageVersion("rlang")
# [1] ‘0.1.2’
@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
Objective: 编写一个函数,将数据帧作为第一个
参数,然后是两个附加参数,参数列表,传递给
dplyr::select
这样函数将 return 两个数据帧。
这是一个工作示例
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 ...
我希望参数 df1
和 df2
采用 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::UQ
、rlang::UQE
、rlang::UQS
的几种组合
使用 rlang::quo
、rlang::enquos
和 rlang::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
的语法将 return 与 my_select
相同的对象
参数通过 alist
?
packageVersion("dplyr")
# [1] ‘0.7.4’
packageVersion("rlang")
# [1] ‘0.1.2’
@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