【问题标题】:Zero-padding with glue用胶水补零
【发布时间】: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_transformerf 是硬编码的,因为02d.2f 本身不是有效的R 语法。我想我们可以创建glue_fmtdglue_fmtf 或添加一个参数来提供'd''f',但这已经使glue_fmt 的便利性因素比普通的sprintf 更加紧张。

这仍然无法克服 R 解析器的基本约束——一旦02 被视为 R 代码,解析器将删除前导 0。

所以,我被困住了——是否可以使用glue 以一种不太复杂的方式进行零填充格式?

【问题讨论】:

    标签: r r-glue


    【解决方案1】:

    我认为您不需要在变压器中使用有效的 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-13
      • 2018-06-01
      • 2012-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-09
      • 1970-01-01
      相关资源
      最近更新 更多