如何在R语言函数调用示例中使用整洁评估(tidy evaluation)?
问题:运用整洁评估实现函数间的列参数传递
现有如下tibble数据:
library(tidyverse) d <- tibble( y1 = 10:12, y2 = 3:5, n1 = rep(100, 3), n2 = rep(100, 3) )
以及自定义运算函数:
f <- function(y1, n1, y2, n2){ log(y1/n2) - log(y2/n2) }
希望在函数g中调用f,但当前代码无法运行:
g <- function(data, y1, n1, y2, n2){ list( result_of_f = f(y1, n1, y2, n2) ) } d %>% g(y1, n1, y2, n2)
预期输出:
$result_of_f [1] 1.2039728 1.0116009 0.8754687
需要通过整洁评估实现,让g中的计算能获取data的上下文,类似with(data, f(y1, n1, y2, n2))的效果。
解决方案
可以使用tidyverse中简洁的整洁评估语法{{ }}(大括号插值),它能自动将函数参数中的列名符号在data的上下文中解析为对应的数据列。修改后的g函数如下:
g <- function(data, y1, n1, y2, n2){ list( result_of_f = f({{ y1 }}, {{ n1 }}, {{ y2 }}, {{ n2 }}) ) } # 调用测试 d %>% g(y1, n1, y2, n2)
运行后即可得到预期输出。
原理说明
{{ }}是rlang包提供的整洁评估语法,作用是将函数接收的符号参数(比如y1)在data的环境中求值,提取出对应的数据列向量,再传递给f函数。- 这种写法等价于手动捕获符号再展开的原生整洁评估写法:
g <- function(data, y1, n1, y2, n2){ y1_enq <- enquo(y1) n1_enq <- enquo(n1) y2_enq <- enquo(y2) n2_enq <- enquo(n2) list( result_of_f = f(!!y1_enq, !!n1_enq, !!y2_enq, !!n2_enq) ) }
但{{ }}是更简洁的语法糖,适合日常tidyverse开发场景。
内容的提问来源于stack exchange,提问作者Demetri Pananos
相关产品推荐
相关产品推荐

