用胶水补零
Zero-padding with glue
我想使用 glue
来完成 sprintf('%02d', x)
但我不确定是否可行。
vignette('transformers')
建议使用类似 sprintf
的转换器 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
以一种不太复杂的方式进行零填充格式?
我认为您不需要在转换程序中使用有效的 R 语法。该字符串作为字符串处理。您不需要硬核 f 或 d。例如,如果您有
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}"), res))
} else {
eval(parse(text = text, keep.source = FALSE), envir)
}
}
那你可以做
glue_fmt('{pid:02d}')
# 03
glue_fmt('{pid:0.02f}')
# 3.00
我想使用 glue
来完成 sprintf('%02d', x)
但我不确定是否可行。
vignette('transformers')
建议使用类似 sprintf
的转换器 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
以一种不太复杂的方式进行零填充格式?
我认为您不需要在转换程序中使用有效的 R 语法。该字符串作为字符串处理。您不需要硬核 f 或 d。例如,如果您有
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}"), res))
} else {
eval(parse(text = text, keep.source = FALSE), envir)
}
}
那你可以做
glue_fmt('{pid:02d}')
# 03
glue_fmt('{pid:0.02f}')
# 3.00