基于purrr对向量递归应用函数:求指定Reduce代码的等价实现
用purrr实现等价于带
right=T的Reduce逻辑 没问题!先拆解下你原来的代码到底在执行什么逻辑,再给你对应的purrr正确实现~
首先,你的原代码逻辑是这样的:
fl <- list(sin, cos, cos, sqrt) x <- seq(0, 1, length.out = 10) Reduce(function(f, ...) f(...), fl, x, right = T)
因为right=TRUE,这段代码是从右往左依次调用函数列表里的函数:先把x传给sqrt,得到的结果传给下一个cos,再传给前一个cos,最后传给sin,等价于手动写sin(cos(cos(sqrt(x))))。
你之前用reduce或accumulate没成功,大概率是因为默认的reduce是从左往右处理,顺序完全反了;而且purrr里专门有对应Reduce(right=T)的函数——reduce_right,这才是我们需要的。
正确的purrr等价实现
先加载purrr包,然后用reduce_right配合公式语法就能搞定:
library(purrr) fl <- list(sin, cos, cos, sqrt) x <- seq(0, 1, length.out = 10) # 核心实现:用reduce_right从右往左处理函数列表 purrr_result <- reduce_right(fl, ~ .y(.x), .init = x)
代码解释
reduce_right:和Reduce(right=T)逻辑一致,从函数列表的最右端开始处理(先取sqrt,再cos,再cos,最后sin)。~ .y(.x):purrr的公式简写语法,这里.x代表当前的计算结果,.y代表当前取到的函数。每次执行就是把当前结果传给下一个函数,完美对应原代码里的function(f, ...) f(...)逻辑。.init = x:指定初始值为x,和原代码里的Reduce第三个参数一致。
验证结果是否一致
你可以用all.equal()对比原代码和purrr代码的结果,确认完全等价:
original_result <- Reduce(function(f, ...) f(...), fl, x, right = T) all.equal(original_result, purrr_result) # 会返回TRUE,说明结果完全一致
如果需要保留中间步骤
如果你想看到每一步的计算结果(类似accumulate的作用),可以用accumulate_right:
# 保留从初始值到最终结果的所有中间步骤 accum_steps <- accumulate_right(fl, ~ .y(.x), .init = x) # accum_steps的元素依次是:x, sqrt(x), cos(sqrt(x)), cos(cos(sqrt(x))), sin(cos(cos(sqrt(x))))
内容的提问来源于stack exchange,提问作者r.user.05apr
相关产品推荐
相关产品推荐

