eval_tidy()支持普通函数但不兼容tidyverse函数,求dplyr子流水线条件执行方案
解决dplyr流水线中条件执行子流水线的问题
修正后的函数实现
ifff <- function(.data, IF, then) { # 捕获带环境的子流水线表达式 thn <- rlang::enquo(then) if (IF) { # 将子流水线注入到.data的数据流中执行 rlang::inject(.data %>% !!thn) } else { .data } }
测试验证
df <- data.frame(A = 1:3,B = 2:4) # 普通函数场景(原代码已支持) df %>% ifff(TRUE, mean(A)) #> [1] 2 # 单个tidyverse函数场景(修复后支持) df %>% ifff(TRUE, group_by(A)) #> # A tibble: 3 × 2 #> # Groups: A [3] #> A B #> <int> <int> #> 1 1 2 #> 2 2 3 #> 3 3 4 # 完整子流水线场景(最终期望功能) df %>% ifff(TRUE, group_by(A) %>% summarise(C = mean(B))) #> # A tibble: 3 × 2 #> A C #> <int> <dbl> #> 1 1 2 #> 2 2 3 #> 3 3 4
问题原因与修复逻辑
- 原代码使用
rlang::enexpr()仅捕获裸表达式,丢失了变量的上下文环境,且未将.data作为tidyverse函数的第一个参数传递,导致group_by(A)这类函数无法找到数据来源。 - 改用
rlang::enquo()捕获带环境的quosure,确保子流水线中的变量能正确映射到.data的列。 - 通过
rlang::inject()将子流水线表达式注入到.data %>% ...的结构中,让整个子流水线以输入的.data为起点执行,完全符合tidyverse的数据流规则。
内容的提问来源于stack exchange,提问作者Felix Schweigkofler
相关产品推荐
相关产品推荐

