如何在函数内的 if 条件内使用 dplyr NSE?
How to use dplyr NSE inside an if condition inside a function?
我有一个接受 NSE 参数的函数。
假设我有一个需要排序的列。我想创建一个函数,该函数可以根据在函数参数中输入的名称对列的名称进行排序。
但是,如果我不使用该参数,我希望它不对列进行排序,因此我使用 column_name = NULL
作为默认参数(或 column_name = NA
)
sort_tibble <- function(column_name = NULL) {
tibble_data <- tibble::tibble(NSE_name = c(0.2, -0.4, 1.7, 0.09, -0.6, -1))
if (!is.null(({{ column_name }}))) {
tibble_data <- tibble_data %>% arrange({{ column_name }})
# Do stuff
}
}
sort_tibble(NSE_name)
#> Error in sort_tibble(NSE_name): objet 'NSE_name' not found
由 reprex package (v2.0.1)
于 2022-04-11 创建
然而,尽管引号、{{var}} 或 rlang::eval_tidy 有多少种组合,但我找不到让 R 理解 column_name 不为空(因此使用)的想法。它找不到它,因为它不是一个变量而是一个整洁的评估,除了它没有在整洁的函数中使用。
我终于找到了解决办法!
这里的想法不是直接尝试使用 {{var}} 为 dplyr 注入数据,而是首先使用字符串作为函数参数输入,并允许使用 [=12= 通过 dplyr 对其进行评估] 和 !!
。这允许其他非整洁操作在函数中工作,包括子集数据框或仅评估参数是否为空(这是我的 if 函数的条件)。
我参考了https://tidyeval.tidyverse.org/sec-why-how.html#unquoting-code
使用sym()
将字符串变成一个符号。
符号需要被评估为 dplyr
中的列
sym("NSE_name")
# NSE_name
然后使用!!
将评估注入代码
library(tidyverse)
f1 <- function(order = NULL) {
df <-
tibble::tibble(NSE_name = c(0.2, -0.4, 1.7, 0.09, -0.6, -1))
f2(order = order)
}
f2 <- function(order = NULL) {
if (!is.null(order)) {
ordered_df <- df %>% arrange(!!sym(order))
return(ordered_df)
}
else print ("No order")
}
f1(order = "NSE_name")
f1()
我有一个接受 NSE 参数的函数。
假设我有一个需要排序的列。我想创建一个函数,该函数可以根据在函数参数中输入的名称对列的名称进行排序。
但是,如果我不使用该参数,我希望它不对列进行排序,因此我使用 column_name = NULL
作为默认参数(或 column_name = NA
)
sort_tibble <- function(column_name = NULL) {
tibble_data <- tibble::tibble(NSE_name = c(0.2, -0.4, 1.7, 0.09, -0.6, -1))
if (!is.null(({{ column_name }}))) {
tibble_data <- tibble_data %>% arrange({{ column_name }})
# Do stuff
}
}
sort_tibble(NSE_name)
#> Error in sort_tibble(NSE_name): objet 'NSE_name' not found
由 reprex package (v2.0.1)
于 2022-04-11 创建然而,尽管引号、{{var}} 或 rlang::eval_tidy 有多少种组合,但我找不到让 R 理解 column_name 不为空(因此使用)的想法。它找不到它,因为它不是一个变量而是一个整洁的评估,除了它没有在整洁的函数中使用。
我终于找到了解决办法!
这里的想法不是直接尝试使用 {{var}} 为 dplyr 注入数据,而是首先使用字符串作为函数参数输入,并允许使用 [=12= 通过 dplyr 对其进行评估] 和 !!
。这允许其他非整洁操作在函数中工作,包括子集数据框或仅评估参数是否为空(这是我的 if 函数的条件)。
我参考了https://tidyeval.tidyverse.org/sec-why-how.html#unquoting-code
使用sym()
将字符串变成一个符号。
符号需要被评估为 dplyr
sym("NSE_name")
# NSE_name
然后使用!!
将评估注入代码
library(tidyverse)
f1 <- function(order = NULL) {
df <-
tibble::tibble(NSE_name = c(0.2, -0.4, 1.7, 0.09, -0.6, -1))
f2(order = order)
}
f2 <- function(order = NULL) {
if (!is.null(order)) {
ordered_df <- df %>% arrange(!!sym(order))
return(ordered_df)
}
else print ("No order")
}
f1(order = "NSE_name")
f1()