我正在尝试使用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
的值是错误的,因为我没有在$
运算符的上下文中使用准引号。我该怎么办?
答案 0 :(得分:4)
我们可以使用character
转换为as_name
类,并使用[[
进行提取。为了避免重复使用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
答案 1 :(得分:1)
您可以使用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