You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

函数内使用rlang与tidyeval的最佳实践及字符串引用对象解法

用tidyeval实现通过字符串名称获取对象内容

问题场景

现有两个tibble对象t1和t2,希望通过它们的字符串名称,在purrr::map调用中获取对象内容:

library(tidyverse)

t1 <- tribble(
  ~name,
  "foo"
)

t2 <- t1

使用基础R的get()可以实现需求:

ls() %>% 
  map(~get(.x))

但尝试的几种tidyeval写法仅返回对象名称,无法获取内容:

# 仅返回字符串名称
ls() %>% map(~{{.x}})

# 返回捕获的表达式,非对象内容
ls() %>% map(~enquo(.x))

# 返回符号对象,未被求值
ls() %>% map(~sym(.x))

原因解析

  • {{.x}}:用于注入表达式,但.x本身是字符串,注入后仍为字符串,不会解析为对象
  • enquo(.x):捕获当前环境中的变量表达式,这里捕获的是字符串变量.x本身,而非对应的对象
  • sym(.x):仅将字符串转换为符号(对象的名称标识),但符号未被求值,不会返回对象内容

正确的tidyeval实现

tidyeval的核心是处理符号与表达式的求值,需要先将字符串转为符号,再对符号进行求值:

方法1:使用sym() + eval_tidy()

ls() %>% 
  map(~rlang::eval_tidy(sym(.x)))

方法2:使用parse_expr() + eval_tidy()(适用于更复杂的表达式)

ls() %>% 
  map(~rlang::eval_tidy(rlang::parse_expr(.x)))

说明

get()是基础R中直接通过字符串获取对象的方法,而tidyeval的思路是先将字符串转换为可被求值的符号/表达式,再完成求值,这更符合tidyeval处理元编程的逻辑。

内容的提问来源于stack exchange,提问作者tomw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 22:57:18