R语言如何封装eval(parse(text=))为兼容data.table的函数
兼容data.table场景的eval(parse())简化封装方案
直接在外层套普通函数之所以无法兼容data.table,核心原因是自定义函数会改变表达式的默认求值环境,导致data.table无法在自身的帧环境里定位更新逻辑,要么报对象找不到的错误,要么触发意外的整表复制警告。
正确的封装需要显式把求值环境指向调用发生的父级上下文,完全复刻原生eval(parse(text=))的作用域查找逻辑,实现代码如下:
eval2 <- function(text, .env = parent.frame()) { eval(parse(text = text), envir = .env) }
用法验证
针对动态创建data.table列的场景,直接替换原有三层嵌套写法即可,行为和原生写法完全一致,不会触发不必要复制的警告:
library(data.table) library(glue) dt <- data.table(a = c(1, 1, 1, 1), foo_col = c('a', 'b', 'X', 'asd')) cur_col <- 'foo_col2' # 简化后调用 dt[, eval2(glue('{cur_col} := c(3, 3, 3, 3)'))] # 普通场景也可直接使用,返回结果和eval(parse(text='5+5'))完全相同 eval2('5+5')
特性说明
- 无额外性能损耗,和原生嵌套写法的执行效率、求值逻辑完全对齐
- 兼容所有data.table在j位置的表达式写法,包括按条件更新、分组计算、多步操作拼接等动态文本场景
- 不需要修改原有glue拼接字符串的逻辑,直接把拼接完成的表达式文本传入即可
- 不会出现
(cur_col) :=写法触发的整表意外复制警告,适合高频动态列操作的场景
内容的提问来源于stack exchange,提问作者Avraam
相关产品推荐
相关产品推荐

