使用purrr::partial()创建函数工厂时如何打印函数输入
问题解决:用purrr的map()和partial()创建带输入配置打印的函数列表
你当前的代码中,print(.x)和print(.y)是在创建函数列表的阶段(也就是map2迭代过程中)执行的,而不是在调用生成的函数时执行。这就是为什么调用rnorm_lst$n50_mean500()时没有打印配置信息的原因——打印逻辑没有被包含到最终返回的partial函数中。
原代码
library(tidyverse) # 生成任意序列 n_vec <- seq(5,100,5) mean_vec <- seq(50,1000,50) # 创建预配置输入的函数列表 rnorm_lst <- map2( .x=n_vec ,.y=mean_vec ,.f=\(.x,.y){ # 期望调用函数时打印输入配置,但实际在创建阶段就执行了 print(.x) print(.y) # 用partial包装rnorm out <- partial(rnorm,n=.x,mean=.y) return(out) } ) # 为函数命名 names_lst <- paste0("n",n_vec,"_","mean",mean_vec) names(rnorm_lst) <- names_lst # 调用函数测试 rnorm_lst$n50_mean500()
修正方案
需要把打印逻辑和rnorm的调用逻辑封装到同一个函数中,确保调用函数时先打印配置,再执行随机数生成。可以直接返回一个包含打印步骤的匿名函数,无需依赖partial(如果坚持用partial也可以把它包进去):
library(tidyverse) n_vec <- seq(5,100,5) mean_vec <- seq(50,1000,50) rnorm_lst <- map2( .x = n_vec, .y = mean_vec, .f = \(.x, .y) { # 返回一个新函数,包含打印配置和执行rnorm的逻辑 function(sd = 1) { # 保留sd作为可选参数,和原rnorm一致 cat("当前函数配置:n =", .x, ",mean =", .y, "\n") # 直接调用rnorm,或者用partial包装后调用都可以 rnorm(n = .x, mean = .y, sd = sd) } } ) names_lst <- paste0("n",n_vec,"_","mean",mean_vec) names(rnorm_lst) <- names_lst # 测试调用,此时会先打印配置,再返回结果 rnorm_lst$n50_mean500() # 也可以指定sd参数 rnorm_lst$n50_mean500(sd = 10)
说明
- 修正后的代码中,map2迭代时返回的是一个新的匿名函数,这个函数内部包含了打印配置的逻辑和调用rnorm的逻辑。
- 保留了
sd作为可选参数,和原生rnorm的接口保持一致,增强灵活性。 - 使用
cat代替print可以输出更整洁的配置信息,也可以根据需求换成message函数(适合提示类信息)。
内容的提问来源于stack exchange,提问作者alejandro_hagan
相关产品推荐
相关产品推荐

