sprintf格式字符串:按名称引用?

hat*_*rix 10 r

在Python中,您可以按名称指定字符串格式(这当然是一个愚蠢的例子):

parameters = {'label':'months', 'april':4,'may':5,'june':6}
formatstring = '%(label)s: %(april)d %(may)d %(june)d'
outputstring = formatstring % parameters
Run Code Online (Sandbox Code Playgroud)

(formatstring % parameters符号是与do.call(sprintf,c(formatstring,as.list(parameters)))R 等效的Python )

输出字符串为" months: 4, 5, 6".参数存储为键值对(可以称为各种语言的字典,哈希表或命名列表).字符串格式%(text)s允许您引用text应在该插槽中格式化的字典项().

R中有没有相同的东西,或者你找到了一个好的解决方法?

G. *_*eck 13

1.尝试gsubfn使用gsubfn包:

library(gsubfn)
parameters <- list(label = "months", april = 4, may = 5, june = 6)

gsubfn("\\w+", parameters, "label: april, may, june")
Run Code Online (Sandbox Code Playgroud)

2.或尝试fn$使用相同的包装:

with(parameters, fn$identity("$label: $april, $may, $june"))
Run Code Online (Sandbox Code Playgroud)

3.这是一个简短的中缀函数,它将格式字符串和参数列表转换为a sprintf然后运行它:

library(gsubfn)
`%format%` <- function(fmt, list) {
    pat <- "%\\(([^)]*)\\)"
    fmt2 <- gsub(pat, "%", fmt)
    list2 <- list[strapplyc(fmt, pat)[[1]]]
    do.call("sprintf", c(fmt2, list2))
}
Run Code Online (Sandbox Code Playgroud)

像这样使用它:

> '%(label)s: %(april)d %(may)d %(june)d' %format% parameters
[1] "months: 4 5 6"
Run Code Online (Sandbox Code Playgroud)


Nea*_*ltz 6

尽管这并未内置到sprintfR 正在使用的系统函数中(请参阅man printf参考资料 系统文档),但通过将命名引用替换为其各自的位置,在 R 中实现此类功能非常容易 -

sprintf_named <- function(fmt, ...) {
  args <- list(...)
  argn <- names(args)
  if(is.null(argn)) return(sprintf(fmt, ...))

  for(i in seq_along(args)) {
    if(argn[i] == "") next;
    fmt <- gsub(sprintf("%%{%s}", argn[i]), sprintf("%%%d$", i), fmt, fixed = TRUE)
  }

  do.call(sprintf, append(args, fmt, 0))
}
Run Code Online (Sandbox Code Playgroud)

这是一个用法示例:

sprintf_named("%{HIA}s!! %{RYLAH}s", RYLAH="Rock You Like a Hurricane", HIA="Here I Am")
## [1] "Here I Am!! Rock You Like a Hurricane"
Run Code Online (Sandbox Code Playgroud)

我们还可以将其设为中缀:

`%format%` <- function(left, right) do.call(sprintf_named, append(right, left, 0))

"%{b}s %{a}s" %format% list(a='ya', b='boo')
## [1] "boo ya"
Run Code Online (Sandbox Code Playgroud)