R语言中使用pmap传入三个参数但仅遍历其中两个的解决方案
解决方法:固定
pmap中的单一参数或用partial简化调用 你遇到的核心问题是希望在调用power_fcn时,让.l参数保持固定值,而不是和.x、.y一起被遍历。其实有几种简洁的方式可以实现你的需求:
方法1:利用purrr::partial()预绑定固定参数
最直观的方式是用partial()把power_fcn的.l参数预先固定为你需要的值,生成一个只需要.x和.y的新函数,再用map2_dfr来处理两个可变参数:
library(purrr) library(tibble) library(pwr) library(tidyr) # 你的原始函数 power_fcn <- function(.x, .y, .l){ tmp <- pwr.t.test(n = .x, d = NULL, power = 0.8, sig.level = .y, type = .l, alternative = "two.sided") tibble(n_per_arm = .x, power = tmp$power, sig_level = tmp$sig.level, test = tmp$alternative, type = tmp$type, cohens_d = tmp$d) } # 生成输入数据框 d1 <- crossing(n = seq(100, 500, by = 100), alpha = c(0.05, 0.005)) # 预绑定type为"two.sample",生成新函数 power_fcn_twosample <- partial(power_fcn, .l = "two.sample") # 用map2_dfr调用,只需传递n和alpha power_df_twosample <- map2_dfr(d1$n, d1$alpha, power_fcn_twosample) # 同样处理paired类型 power_fcn_paired <- partial(power_fcn, .l = "paired") power_df_paired <- map2_dfr(d1$n, d1$alpha, power_fcn_paired)
这种方式的好处是逻辑清晰:把固定不变的参数提前绑定,剩下的可变参数用map2(对应两个参数)来处理,完全避免了参数遍历的混淆。
方法2:显式传递重复的固定参数值
如果你更倾向于继续使用pmap_dfr,可以把.l参数包装成一个和.x/.y长度相同的重复向量,这样每个函数调用都会收到相同的.l值:
# 生成two.sample的结果 power_df_twosample <- pmap_dfr( .x = list( .x = d1$n, .y = d1$alpha, .l = rep("two.sample", nrow(d1)) # 显式重复固定值 ), .f = power_fcn ) # 生成paired的结果 power_df_paired <- pmap_dfr( .x = list( .x = d1$n, .y = d1$alpha, .l = rep("paired", nrow(d1)) ), .f = power_fcn )
其实你最初的写法(直接传.l = "two.sample")也能工作——因为R会自动循环补齐长度较短的向量,每个调用都会收到相同的.l值。但显式重复的方式更清晰,避免了依赖隐式的循环补齐规则。
额外提示:一次性生成两种类型的结果(可选)
如果你之后需要合并两个结果,也可以用crossing包含type参数,一次性生成所有组合,再按type拆分:
# 包含type的输入数据框 d2 <- crossing(n = seq(100, 500, by = 100), alpha = c(0.05, 0.005), type = c("two.sample", "paired")) # 一次性生成所有结果 power_df_all <- pmap_dfr( .x = list(.x = d2$n, .y = d2$alpha, .l = d2$type), .f = power_fcn ) # 按type拆分得到两个数据框 power_df_twosample <- filter(power_df_all, type == "two.sample") power_df_paired <- filter(power_df_all, type == "paired")
这种方式适合需要同时处理多种type的场景,不过完全符合你"分开调用"需求的还是前两种方法。
内容的提问来源于stack exchange,提问作者C.Robin
相关产品推荐
相关产品推荐

