是否有 R 等效于 python 的字符串“格式”函数?
Posted
技术标签:
【中文标题】是否有 R 等效于 python 的字符串“格式”函数?【英文标题】:Is there an R equivalent of python's string `format` function? 【发布时间】:2017-11-29 11:46:33 【问题描述】:在 python 中有一个很好的函数 (str .format
) 可以很容易地将字符串中的变量(编码为 variable
)替换为存储在 dict 中的值(使用变量名命名的值)。像这样:
vars=dict(animal="shark", verb="ate", noun="fish")
string="Sammy the animal verb a noun."
print(string.format(**vars))
鲨鱼萨米吃了一条鱼。
R
中最简单的解决方案是什么?是否有一个内置的等效 2 参数函数,它接受一个字符串,其中变量编码 相同
方式并将它们替换为来自命名list
的命名值?
如果 R 中没有内置函数,那么发布的包中是否有内置函数?
如果已发布的包中没有,你会用什么来编写?
规则:字符串是用编码为“variable”的变量提供给您的。变量必须编码为list
。我会用我的定制版本来回答,但会接受比我做得更好的答案。
【问题讨论】:
我会非常自信地伸出脖子说“不”。未内置在基础 R 中。附加包中可能存在与此完全相同的内容。有 类似 的东西可以进行变量替换(例如 brew 包),但您希望使用这种 name 语法精确编码的格式,是吗? 是的;该字符串已经为以 python 为中心的分析而构建,因此我无法更改变量的编码方式。brew
使用 <%=
和 %>
作为标记。如果您不希望字符串中出现<%=
或在任何地方转义了
,则用它们替换
和
会起作用。
我不知道 R 中格式函数的任何等效项,但是您有一个 printf C 函数的等效项,它允许您放置要打印的内容和变量列表。见rdocumentation.org/packages/R.utils/versions/2.5.0/topics/…
sprintf()
是核心包中最接近的。它不使用命名替换组,但可以做索引组:sprintf("%1$s %1$s %2$s %3$s", "a", "b", "c")
【参考方案1】:
由于我找不到具有这种功能的内置甚至包,因此我尝试自行开发。我的功能依赖于stringi
包。这是我想出的:
strformat = function(str, vals)
vars = stringi::stri_match_all(str, regex = "\\.*?\\", vectorize_all = FALSE)[[1]][,1]
x = str
for (i in seq_along(names(vals)))
varName = names(vals)[i]
varCode = paste0("", varName, "")
x = stringi::stri_replace_all_fixed(x, varCode, vals[[varName]], vectorize_all = TRUE)
return(x)
例子:
> str = "Sammy the animal verb a noun."
> vals = list(animal="shark", verb="ate", noun="fish")
> strformat(str, vals)
[1] "Sammy the shark ate a fish."
【讨论】:
【参考方案2】:这是一个将 和
转换为
<%=
和%>
的函数,然后使用brew
包(您需要安装)中的brew
:
form = function(s,...)
s = gsub("\\", "%>", gsub("\\","<%=",s))
e = as.environment(list(...))
parent.env(e)=.GlobalEnv
brew(text=s, envir=e)
测试:
> form("Sammy the animal verb a noun.", animal = "shark", verb="made", noun="car")
Sammy the shark made a car.
> form("Sammy the animal verb a noun.", animal = "shark", verb="made", noun="truck")
Sammy the shark made a truck.
如果格式字符串中有任何 没有标记变量替换,或者它有
<%=
或任何其他brew
语法标记,它将失败。
【讨论】:
这比我的版本更简洁——但我认为如果它接受变量的list
会更有用
在这种情况下尝试form = function(s,L)
和e = as.environment(L)
(未经测试)。我的基础是 python 的字符串格式方法,它实际上并不需要一个字典,而是一个参数列表(你可以用星号转换它,就像 OP 现在在编辑中所做的那样!【参考方案3】:
我找到了另一个解决方案:来自 tidyverse 的胶水包: https://github.com/tidyverse/glue
一个例子:
library(glue)
animal <- "shark"
verb <- "ate"
noun <- "fish"
string="Sammy the animal verb a noun."
glue(string)
Sammy the shark ate a fish.
如果你坚持有变量列表,你可以这样做:
l <- list(animal = "shark", verb = "ate", noun = "fish")
do.call(glue, c(string , l))
Sammy the shark ate a fish.
问候
帕维尔
【讨论】:
最好使用with
:with(l, glue(string))
。【参考方案4】:
stringr
包几乎在函数 str_interp
中有一个完全替换。它只需要一点调整:
fmt = function(str, vals)
# str_interp requires variables encoded like $var, so we substitute
# the var syntax here.
str = stringr::str_replace_all(str, "\\", "$")
stringr::str_interp(str, vals)
【讨论】:
错误示例...传入“str”和“vals”,引用“x”和“args”。 修复了 args 以便它们匹配【参考方案5】:library(glue)
list2env(list(animal="shark", verb="ate", noun="fish"),.GlobalEnv)
string="Sammy the animal verb a noun."
glue(string)
Sammy the shark ate a fish.
【讨论】:
以上是关于是否有 R 等效于 python 的字符串“格式”函数?的主要内容,如果未能解决你的问题,请参考以下文章
是否有 Python 等效于正则表达式的 Perl "/x" 修饰符?
R 等效于 python 的 os.getpid() 用于并行处理
R 中是不是有类似于 Python 的 % 的字符串格式化运算符?