Ind*_*til 6 r dplyr purrr tidyeval rlang
我有一个自定义函数,我正在从数据框中读取输入的变量rlang.无论输入的参数是引用还是不引用,此函数都可以正常工作.但是,奇怪的是,当使用此函数时purrr::pmap,它仅在引用参数时起作用.
所以我有两个问题:
为什么函数行为这样?
如何使用rlang这样一个函数,即使用于我也不必引用参数purrr::pmap?
这是一个使用简单函数突出显示此问题的最小代表:
# loading the needed libraries
library(rlang)
library(dplyr)
library(purrr)
# defining the function
tryfn <- function(data, x, y) {
data <-
dplyr::select(
.data = data,
x = !!rlang::enquo(x),
y = !!rlang::enquo(y)
)
# creating a dataframe of means
result_df <- data.frame(mean.x = mean(data$x), mean.y = mean(data$y))
# return the dataframe
return(result_df)
}
# without quotes (works!)
tryfn(iris, Sepal.Length, Sepal.Width)
#> mean.x mean.y
#> 1 5.843333 3.057333
# with quotes (works!)
tryfn(iris, "Sepal.Length", "Sepal.Width")
#> mean.x mean.y
#> 1 5.843333 3.057333
# pmap without quotes (doesn't work)
purrr::pmap(.l = list(
data = list(iris, mtcars, ToothGrowth),
x = list(Sepal.Length, wt, len),
y = list(Sepal.Width, mpg, dose)
),
.f = tryfn)
#> Error in is.data.frame(.l): object 'Sepal.Length' not found
# pmap with quotes (works!)
purrr::pmap(.l = list(
data = list(iris, mtcars, ToothGrowth),
x = list("Sepal.Length", "wt", "len"),
y = list("Sepal.Width", "mpg", "dose")
),
.f = tryfn)
#> [[1]]
#> mean.x mean.y
#> 1 5.843333 3.057333
#>
#> [[2]]
#> mean.x mean.y
#> 1 3.21725 20.09062
#>
#> [[3]]
#> mean.x mean.y
#> 1 18.81333 1.166667
Run Code Online (Sandbox Code Playgroud)
由reprex包(v0.2.0)于2018-05-21创建.
问题是:R 看到了Sepal.Length, wt, len符号,因此它尝试在当前环境中查找并评估它们。当然,它会导致错误,因为它们是数据框的列。当您引用它们时,R 不会尝试计算并返回值,因为它将这些值视为字符串。
如果你替换list为base::alistordplyr::vars或rlang::exprs,它应该可以工作
注意:由于我们已经引用了输入,因此我们不再需要使用rlang::enquoinside tryfn。
# loading the needed libraries
library(rlang)
library(tidyverse)
# defining the function
tryfn <- function(data, x, y) {
data <-
dplyr::select(
.data = data,
x = !! x,
y = !! y
)
# creating a data frame of means
result_df <- data.frame(mean.x = mean(data$x), mean.y = mean(data$y))
# return the data frame
return(result_df)
}
# alist handles its arguments as if they described function arguments.
# So the values are not evaluated, and tagged arguments with no value are
# allowed whereas list simply ignores them.
purrr::pmap(.l = list(
data = list(iris, mtcars, ToothGrowth),
x = alist(Sepal.Length, wt, len),
y = alist(Sepal.Width, mpg, dose)
),
.f = tryfn)
#> [[1]]
#> mean.x mean.y
#> 1 5.843333 3.057333
#>
#> [[2]]
#> mean.x mean.y
#> 1 3.21725 20.09062
#>
#> [[3]]
#> mean.x mean.y
#> 1 18.81333 1.166667
purrr::pmap(.l = list(
data = list(iris, mtcars, ToothGrowth),
x = dplyr::vars(Sepal.Length, wt, len),
y = dplyr::vars(Sepal.Width, mpg, dose)
),
.f = tryfn)
#> [[1]]
#> mean.x mean.y
#> 1 5.843333 3.057333
#>
#> [[2]]
#> mean.x mean.y
#> 1 3.21725 20.09062
#>
#> [[3]]
#> mean.x mean.y
#> 1 18.81333 1.166667
purrr::pmap(.l = list(
data = list(iris, mtcars, ToothGrowth),
x = rlang::exprs(Sepal.Length, wt, len),
y = rlang::exprs(Sepal.Width, mpg, dose)
),
.f = tryfn)
#> [[1]]
#> mean.x mean.y
#> 1 5.843333 3.057333
#>
#> [[2]]
#> mean.x mean.y
#> 1 3.21725 20.09062
#>
#> [[3]]
#> mean.x mean.y
#> 1 18.81333 1.166667
Run Code Online (Sandbox Code Playgroud)
由reprex 包(v0.2.0)于 2018-05-21 创建。
| 归档时间: |
|
| 查看次数: |
127 次 |
| 最近记录: |