r - 具有整洁评估的变异变量(符号或字符串)
问题描述
我想在我的函数中使用整洁的评估,同时改变输入的变量,但似乎无法让函数正常工作。
我已经阅读了tidy eval 与例如 mtcars %>% mutate(target := log(target))和Tidy Evaluation not working with mutate 和 stringr,他们似乎建议需要根据符号是否有不同的解决方案或者一个字符串作为参数传递。但我更喜欢对这两个输入都适用的这个问题的通用解决方案。
有没有办法做到这一点?
功能
library(magrittr)
foo <- function(data, x) {
# I know this is one solution to solve my problem
# But I want to avoid it because it creates problem if the function is to be used within a loop
# x <- rlang::ensym(x)
df <- tibble::as_tibble(dplyr::select(data, {{ x }}))
df %>% dplyr::mutate(.data = ., {{ x }} := droplevels(as.factor({{ x }})))
}
按预期工作
foo(mtcars, am)
#> # A tibble: 32 x 1
#> am
#> <fct>
#> 1 1
#> 2 1
#> 3 1
#> 4 0
#> 5 0
#> 6 0
#> 7 0
#> 8 0
#> 9 0
#> 10 0
#> # ... with 22 more rows
没有按预期工作
foo(mtcars, "am")
#> # A tibble: 32 x 1
#> am
#> <fct>
#> 1 am
#> 2 am
#> 3 am
#> 4 am
#> 5 am
#> 6 am
#> 7 am
#> 8 am
#> 9 am
#> 10 am
#> # ... with 22 more rows
PS如果您对可能的解决方案在循环中引起的问题感到好奇,这里有一个代表:
library(magrittr)
col.name <- colnames(mtcars)
foo <- function(data, x) {
x <- rlang::ensym(x)
df <- tibble::as_tibble(dplyr::select(data, {{ x }}))
df %>% dplyr::mutate(.data = ., {{ x }} := droplevels(as.factor({{ x }})))
}
for (i in 3:length(mtcars)) {
foo(mtcars, col.name[i])
}
#> Error: Only strings can be converted to symbols
解决方案
通常不建议尝试使您的函数与屏蔽列和列名兼容,因为这不是 tidyverse 函数的设计方式。
首先选择是否要采取行动或选择。如果您采用后者,那么您可以使用 tidyselect 功能,例如all_of()
与字符向量兼容。在所有 dplyr 动词中进行选择的一种简单方法是使用across()
.
在这种情况下,您也可以使用select()
开头,所以我们可以使用across(everything())
. 一般来说,你可以做across({{ x }})
.
foo <- function(data, x) {
data %>%
as_tibble() %>%
select({{ x }}) %>%
# Could also remove the `select()` step and pass `{{ x }}` to across()
mutate(across(everything(), ~ droplevels(as.factor(.))))
}
foo(mtcars, am)
由于您已转发x
到选择上下文,因此您的函数现在支持所有 tidyselect 功能。如果您需要传递字符向量或字符串,只需使用all_of()
. 调整你的例子:
nms <- names(mtcars)
for (i in 3:length(mtcars)) {
foo(mtcars, all_of(nms[i]))
}
推荐阅读
- c# - 对分区 CosmosDB 集合的查询不一致
- c - 将一个文本文件拆分为多个在 c 中具有特定名称的文本文件
- c# - 当键为结构时,C# 字典性能受到很大影响
- angularjs - 如何像班次一样在电子中加载多个页面
- android - 未获取捕获的图像路径
- python - UnicodeDecodeError:“ascii”编解码器无法解码位置 5 中的字节 0xc3:序数不在范围内(128)
- python - 如何跟踪进程的资源使用情况?
- angular - Angular Guard 和 JWT
- c - C--程序没有正确读取文件结尾
- elasticsearch - 在 ELK 中,如何搜索与另一个不匹配的日志?