R语言purrr包reduce函数结合sprintf报错问题咨询
问题:使用purrr::reduce结合sprintf处理多参数时报错
需求
想要生成包含多个占位符的格式化字符串:
"Name and ID: %s Authors: %s Date of revision: %s"
尝试用reduce循环传递参数完成格式化。
尝试的代码与错误
执行以下代码:
library(purrr) reduce(as.list(letters[1:3]), sprintf, fmt="%s %s %s")
运行后抛出错误:
Error in fn(out, elt, ...) : too few arguments
预期结果
期望输出:
[1] "a b c"
对比验证
处理2个参数的类似代码可正常运行:
reduce(as.list(letters[1:2]), sprintf, fmt="%s %s")
输出符合预期:
[1] "a b"
环境信息
> sessionInfo() > R version 4.3.2 (2023-10-31 ucrt) > Platform: x86_64-w64-mingw32/x64 (64-bit) > Running under: Windows 10 x64 (build 19045) Matrix products: default locale: [1] LC_COLLATE=English_United States.utf8 LC_CTYPE=English_United States.utf8 LC_MONETARY=English_United States.utf8 [4] LC_NUMERIC=C LC_TIME=English_United States.utf8 time zone: Europe/Paris tzcode source: internal attached base packages: [1] stats graphics grDevices utils datasets methods base other attached packages: [1] purrr_1.0.2 loaded via a namespace (and not attached): [1] compiler_4.3.2 magrittr_2.0.3 cli_3.6.2 tools_4.3.2 rstudioapi_0.15.0 vctrs_0.6.5 lifecycle_1.0.4 rlang_1.1.3
问题原因
reduce的执行逻辑是逐步累积计算:
- 处理2个参数时,第一次调用直接把
letters[1]和letters[2]传入sprintf,fmt="%s %s"刚好匹配2个参数,执行成功。 - 处理3个参数时,第一次调用会用前两个元素
"a"和"b"调用sprintf,但fmt="%s %s %s"需要3个参数,此时仅传入2个,导致参数不足报错。
解决方案
方案1:使用do.call直接传递所有参数(推荐)
do.call可将参数列表一次性传递给sprintf,完美匹配多占位符的格式化需求:
# 带标签的格式化 do.call(sprintf, args = c(fmt = "Name and ID: %s Authors: %s Date of revision: %s", as.list(letters[1:3])))
输出:
[1] "Name and ID: a Authors: b Date of revision: c"
如果仅需简单拼接:
do.call(sprintf, args = c(fmt = "%s %s %s", as.list(letters[1:3])))
输出:
[1] "a b c"
方案2:用reduce拼接字符串(无需多占位符格式)
如果只是要将多个元素用空格拼接,直接用reduce结合paste更简单:
reduce(as.list(letters[1:3]), paste, sep = " ")
输出:
[1] "a b c"
内容的提问来源于stack exchange,提问作者Jan-Magnus Økland
相关产品推荐
相关产品推荐

