【发布时间】:2020-12-23 03:10:08
【问题描述】:
我想使用glue 来完成sprintf('%02d', x),但我不确定这是否可行。
vignette('transformers') 建议使用sprintf-alike 转换器sprintf_transformer 和“前端”包装器glue_fmt,如下所示:
sprintf_transformer <- function(text, envir) {
m <- regexpr(":.+$", text)
if (m != -1) {
format <- substring(regmatches(text, m), 2)
regmatches(text, m) <- ""
res <- eval(parse(text = text, keep.source = FALSE), envir)
do.call(sprintf, list(glue("%{format}f"), res))
} else {
eval(parse(text = text, keep.source = FALSE), envir)
}
}
glue_fmt <- function(..., .envir = parent.frame()) {
glue(..., .transformer = sprintf_transformer, .envir = .envir)
}
然后举一个简单的例子:
glue_fmt("π = {pi:.2}")
#> π = 3.14
这似乎依赖于惰性求值来将调用 pi:.2(这是有效的 R 语法)拆分为对 sprintf:sprintf('%.2f', pi) 的调用。
但是在我看来,这对于 0 填充的情况是不可能的,因为 R 解析器将消除任何前导 0:
pid = as.integer(pi)
glue_fmt('{pid:02}')
# 3.000000
# vs desired
sprintf('%02d', pid)
# [1] "03"
查看sprintf_transformer,f 是硬编码的,因为02d 和.2f 本身不是有效的R 语法。我想我们可以创建glue_fmtd 和glue_fmtf 或添加一个参数来提供'd' 或'f',但这已经使glue_fmt 的便利性因素比普通的sprintf 更加紧张。
这仍然无法克服 R 解析器的基本约束——一旦02 被视为 R 代码,解析器将删除前导 0。
所以,我被困住了——是否可以使用glue 以一种不太复杂的方式进行零填充格式?
【问题讨论】: