如何在R原生管道|>中实现步骤的条件式求值?
如何在R原生管道
|>中实现步骤的条件式求值? 我们知道使用magrittr的%>%管道时,可以通过传入{}表达式实现条件式步骤,但直接将该写法迁移到R原生管道|>中会触发报错。以下是问题示例:
library(dplyr) do_thing = TRUE # magrittr语法可正常运行 x <- iris %>% { if (do_thing) mutate(., Sepal.Length = Sepal.Length + 100) else . } |> select(Sepal.Length) # 原生管道直接用{}会报错 # 错误信息:Error in { : function '{' not supported in RHS call of a pipe x <- iris |> { if (do_thing) mutate(_, Sepal.Length = Sepal.Length + 100) else _ } |> select(Sepal.Length)
解决方法
方法1:用identity()包裹条件表达式
原生管道要求右侧是合法的函数调用,将条件表达式放入identity()中即可满足要求:
x <- iris |> identity({ if (do_thing) mutate(_, Sepal.Length = Sepal.Length + 100) else _ }) |> select(Sepal.Length)
方法2:封装条件逻辑为单独函数
把条件判断逻辑封装成独立函数,既符合原生管道的调用规则,也能提升代码可读性:
conditional_mutate <- function(data, do_thing) { if (do_thing) { mutate(data, Sepal.Length = Sepal.Length + 100) } else { data } } x <- iris |> conditional_mutate(do_thing = do_thing) |> select(Sepal.Length)
方法3:使用匿名函数包裹条件逻辑
针对简单逻辑,可直接用匿名函数包裹条件表达式(R 4.1+支持\(.)写法,旧版本替换为function(.)即可):
x <- iris |> (\(.) if (do_thing) mutate(., Sepal.Length = Sepal.Length + 100) else .)() |> select(Sepal.Length)
内容的提问来源于stack exchange,提问作者Lief Esbenshade
相关产品推荐
相关产品推荐

