r - 如何评估嵌套函数中的胶水表达式?
问题描述
我正在尝试嵌套一个将两个字符串粘合在一起的函数,该函数使用组合字符串来命名数据框的列。但是,问题似乎是胶水表达式没有足够早地评估为字符串。我可以(并且应该)在将表达式作为参数传递给另一个函数之前强制对其进行评估吗?
library(tidyverse)
# define inner function
add_prefix <- function(string) {
x <- glue::glue("prefix_{string}")
return(as.character(x))
}
# define outer function
mod_mtcars <- function(df, name) {
df %>%
mutate({{ name }} := mpg ^ 2)
}
mod_mtcars(mtcars, add_prefix("foo"))
#> Error: The LHS of `:=` must be a string or a symbol
# alternative outer function with explicit enquoting
mod_mtcars2 <- function(df, name) {
name <- ensym(name)
df %>%
mutate(!!name := mpg ^ 2)
}
mod_mtcars2(mtcars, add_prefix("foo"))
#> Error: Only strings can be converted to symbols
由reprex 包于 2021-10-30 创建(v2.0.1)
解决方案
首先,胶合字符串语法现在比直接在 LHS 中包含更受欢迎。所以更"{{ var }}" := expr
喜欢{{ var }} := expr
. 在 rlang 的未来版本(明年)中,我们将可以在=
. 到那时,:=
将几乎被取代。在添加胶水支撑之前,我们允许在 LHS 上:=
进行注射。!!
其次,您的问题是您正在使用{{
而不是简单的注入。{{
用于注入作为参数提供的表达式,而不是表达式的值。使用普通的胶水插值"{"
来注入值:
mod_mtcars <- function(df, name) {
df %>%
mutate("{name}" := mpg ^ 2)
}
PS:你的!!
版本有类似的问题。因为您ensym()
在参数上使用了,所以您正在解析作为参数提供的表达式而不是使用值。但是ensym()
要求表达式是一个简单的名称,并且您提供了完整的计算,从而导致错误。你可以像这样修复它:
mod_mtcars2 <- function(df, name) {
df %>%
mutate(!!name := mpg ^ 2)
}
但是现在首选胶合语法。
推荐阅读
- performance - 只有一个参数函数有效吗?哈斯克尔
- javascript - 如何在父组件中的 fetch 调用的数据传递给它之前停止加载 React 子组件
- javascript - 选定人员的 Discord JS 命令
- python - 反向分组链表
- python - 将多个条件 groupby + sort + sum 应用于熊猫数据框行
- azure - 能否使用 DevOps 工件查询检索 Azure DevOps Wiki?
- node.js - 使用 arrayFilters 的 mongoDB 更新不起作用
- spring - spring webflux如何调用微服务获取数据
- python - Scipy引发错误,TypeError:+的不支持的操作数类型:'float'和'dict'但是变量是float
- python - 通过输入的位置重新排列可变大小的列表