在R中无需循环,如何对向量执行参数可变的系列重复操作?
解决方案
你要的这种"串行应用带不同参数的函数"的需求,不管是base R还是tidyverse工具集里都有现成实现,也可以自己封装成你设想的serialfunction形式。
1. Base R 原生实现:Reduce()
Reduce()是base R自带的函数,专门用来把一个函数依次累积应用到初始值和参数列表上,每次输出作为下一次的输入,完美匹配你的需求:
# 直接调用Reduce,效果和你的循环/管道嵌套完全一致 Reduce( function(current_result, current_base) log(current_result, base = current_base), x = 2:4, init = 30:32 )
2. Tidyverse 风格实现:purrr::reduce()
如果习惯用管道语法,purrr包的reduce()写法更直观,还支持公式简化:
library(purrr) # 完整写法 30:32 |> reduce(2:4, .f = function(x, base) log(x, base = base)) # 简化公式写法(.x代表上一次结果,.y代表当前参数) 30:32 |> reduce(2:4, ~ log(.x, base = .y))
3. 封装成你想要的serialfunction
如果需要完全贴合30:32 |> serialfunction(log, 2:4)的调用方式,可以自己封装一个通用函数:
serialfunction <- function(.data, .func, .params, .param_name = "base") { Reduce( function(x, p) do.call(.func, list(x, !!rlang::sym(.param_name) := p)), x = .params, init = .data ) } # 调用示例(和你想要的语法一致) 30:32 |> serialfunction(log, 2:4) # 适配其他函数/参数的示例,比如多次开方 30:32 |> serialfunction(sqrt, rep(2,3), .param_name = "exponent")
结果验证
以上所有写法的输出,和你给出的循环/管道嵌套代码结果完全相同:
# 循环输出结果 foo <- 30:32 for(anum in c(2,3,4)){ foo <- log(foo, base = anum) } foo #> [1] 0.8726697 0.8853243 0.8974656
内容的提问来源于stack exchange,提问作者s460
相关产品推荐
相关产品推荐

