将准引号与 `$` 运算符一起使用
using quasiquotation with `$` operator
我正在尝试使用 rlang
编写自定义函数。虽然我可以在函数涉及 data
参数时执行此操作,但是当函数需要向量并且我需要使用 $
运算符时,我无法正确使用准引号。
这是一个玩具示例-
library(tidyverse)
# proper implementation
tryfn <- function(data, x, y) {
# creating a dataframe
data <-
dplyr::select(
.data = data,
!!rlang::enquo(x),
!!rlang::enquo(y)
) %>% # dropping unused levels
dplyr::mutate(.data = .,
!!rlang::enquo(x) := droplevels(as.factor(!!rlang::enquo(x))))
# checking if data is getting imported properly
print(data)
# figuring out number of levels in the grouping factor
return(length(levels(data$`!!rlang::enquo(x)`))[[1]])
}
# using the function
tryfn(ggplot2::msleep, vore, brainwt)
#> # A tibble: 83 x 2
#> vore brainwt
#> <fct> <dbl>
#> 1 carni NA
#> 2 omni 0.0155
#> 3 herbi NA
#> 4 omni 0.00029
#> 5 herbi 0.423
#> 6 herbi NA
#> 7 carni NA
#> 8 <NA> NA
#> 9 carni 0.07
#> 10 herbi 0.0982
#> # ... with 73 more rows
#> Warning: Unknown or uninitialised column: '!!rlang::enquo(x)'.
#> [1] 0
如此处所示,数据已正确导入,但 return
值不正确,因为我不知道如何在 $
运算符的上下文中使用准引号。我该怎么做?
我们可以使用 as_name
转换为 character
class 并使用 [[
提取。为避免使用 enquo
重复转换,一次完成,存储在标识符中并重复使用
tryfn <- function(data, x, y) {
x <- rlang::enquo(x)
y <- rlang::enquo(y)
# creating a dataframe
data <-
dplyr::select(
.data = data,
!!x,
!!y
) %>% # dropping unused levels
dplyr::mutate(.data = .,
!!x := droplevels(as.factor(!!x)))
# checking if data is getting imported properly
print(data)
# figuring out number of levels in the grouping factor
return(length(levels(data[[rlang::as_name(x)]]))[[1]])
}
-测试
tryfn(ggplot2::msleep, vore, brainwt)
# A tibble: 83 x 2
# vore brainwt
# <fct> <dbl>
# 1 carni NA
# 2 omni 0.0155
# 3 herbi NA
# 4 omni 0.00029
# 5 herbi 0.423
# 6 herbi NA
# 7 carni NA
# 8 <NA> NA
# 9 carni 0.07
#10 herbi 0.0982
# … with 73 more rows
#[1] 4
您可以使用 dplyr::pull
来提取使用与 select
相似的语义的列。使用 rlang 0.4 的 {{...}}
进行插值(enquo
和 !!
合二为一)并简化一点,
library(tidyverse)
tryfn <- function(data, x, y) {
data <- data %>% transmute({{x}} := as.factor({{x}}), {{y}})
print(data)
data %>% pull({{x}}) %>% nlevels()
}
tryfn(ggplot2::msleep, vore, brainwt)
#> # A tibble: 83 x 2
#> vore brainwt
#> <fct> <dbl>
#> 1 carni NA
#> 2 omni 0.0155
#> 3 herbi NA
#> 4 omni 0.00029
#> 5 herbi 0.423
#> 6 herbi NA
#> 7 carni NA
#> 8 <NA> NA
#> 9 carni 0.07
#> 10 herbi 0.0982
#> # … with 73 more rows
#> [1] 4
我正在尝试使用 rlang
编写自定义函数。虽然我可以在函数涉及 data
参数时执行此操作,但是当函数需要向量并且我需要使用 $
运算符时,我无法正确使用准引号。
这是一个玩具示例-
library(tidyverse)
# proper implementation
tryfn <- function(data, x, y) {
# creating a dataframe
data <-
dplyr::select(
.data = data,
!!rlang::enquo(x),
!!rlang::enquo(y)
) %>% # dropping unused levels
dplyr::mutate(.data = .,
!!rlang::enquo(x) := droplevels(as.factor(!!rlang::enquo(x))))
# checking if data is getting imported properly
print(data)
# figuring out number of levels in the grouping factor
return(length(levels(data$`!!rlang::enquo(x)`))[[1]])
}
# using the function
tryfn(ggplot2::msleep, vore, brainwt)
#> # A tibble: 83 x 2
#> vore brainwt
#> <fct> <dbl>
#> 1 carni NA
#> 2 omni 0.0155
#> 3 herbi NA
#> 4 omni 0.00029
#> 5 herbi 0.423
#> 6 herbi NA
#> 7 carni NA
#> 8 <NA> NA
#> 9 carni 0.07
#> 10 herbi 0.0982
#> # ... with 73 more rows
#> Warning: Unknown or uninitialised column: '!!rlang::enquo(x)'.
#> [1] 0
如此处所示,数据已正确导入,但 return
值不正确,因为我不知道如何在 $
运算符的上下文中使用准引号。我该怎么做?
我们可以使用 as_name
转换为 character
class 并使用 [[
提取。为避免使用 enquo
重复转换,一次完成,存储在标识符中并重复使用
tryfn <- function(data, x, y) {
x <- rlang::enquo(x)
y <- rlang::enquo(y)
# creating a dataframe
data <-
dplyr::select(
.data = data,
!!x,
!!y
) %>% # dropping unused levels
dplyr::mutate(.data = .,
!!x := droplevels(as.factor(!!x)))
# checking if data is getting imported properly
print(data)
# figuring out number of levels in the grouping factor
return(length(levels(data[[rlang::as_name(x)]]))[[1]])
}
-测试
tryfn(ggplot2::msleep, vore, brainwt)
# A tibble: 83 x 2
# vore brainwt
# <fct> <dbl>
# 1 carni NA
# 2 omni 0.0155
# 3 herbi NA
# 4 omni 0.00029
# 5 herbi 0.423
# 6 herbi NA
# 7 carni NA
# 8 <NA> NA
# 9 carni 0.07
#10 herbi 0.0982
# … with 73 more rows
#[1] 4
您可以使用 dplyr::pull
来提取使用与 select
相似的语义的列。使用 rlang 0.4 的 {{...}}
进行插值(enquo
和 !!
合二为一)并简化一点,
library(tidyverse)
tryfn <- function(data, x, y) {
data <- data %>% transmute({{x}} := as.factor({{x}}), {{y}})
print(data)
data %>% pull({{x}}) %>% nlevels()
}
tryfn(ggplot2::msleep, vore, brainwt)
#> # A tibble: 83 x 2
#> vore brainwt
#> <fct> <dbl>
#> 1 carni NA
#> 2 omni 0.0155
#> 3 herbi NA
#> 4 omni 0.00029
#> 5 herbi 0.423
#> 6 herbi NA
#> 7 carni NA
#> 8 <NA> NA
#> 9 carni 0.07
#> 10 herbi 0.0982
#> # … with 73 more rows
#> [1] 4