查看原文
其他

左手用R右手Python系列之——字符串格式化进阶

杜雨 R语言中文社区 2019-04-22


作者简介Introduction

杜雨,EasyCharts团队成员,R语言中文社区专栏作者,兴趣方向为:Excel商务图表,R语言数据可视化,地理信息数据可视化。

个人公众号:数据小魔方(微信ID:datamofang) ,“数据小魔方”创始人。 


精彩集锦

那些年倒腾的R语言学习笔记,全都在这里了~

左手用R右手Python系列之——表格数据抓取之道

左手用R右手Python系列——循环中的错误异常规避

左手用R右手Python系列——异常捕获与容错处理

左手用R右手Python系列——任务进度管理

左手用R右手Python——CSS网页解析实战

左手用R右手Python系列17——CSS表达式与网页解析

关于R语言字符串格式化之前无论是专题还是案例教程中均有所涉及,今日这一篇之所以重提是因为又找到了一个很好用的字符串格式化包。

这个包的语法源于Python风格,这样可以让那些从Python迁移过来的R语言学习者无需额外的记忆负担,即可平稳掌握R语言中的字符串格式化语法。

提到字符串格式化语法,我们一定能想到paste/pasteo函数,或者str_c函数,这两个函数的用法差不多,都是通过字符串与变量之间的拼接完成字符串格式化任务,但是问题是R语言中的字符处理并不想Python中那么灵活(仅靠“+”即可拼接字符),当一个字符串中需要插入多个变量时,拼接任务变得异常复杂。

好在R语言中保留了sprintf函数,这个源自C语言家族的字符串格式化函数,在左手用R右手Python系列推送文章中,曾经就这个问题专门写过一篇,但是这个sprintf函数使用起来并不是特别方便,特别是同类格式需要重复定义,同样的问题在Python的语法中也存在。

左右用R右手Python系列——字符串格式化输出

但是Python中有另外一套字符串格式化无法,使用format函数和{}来定义,最近发现R语言中的pystr包,也模仿着Python中的这一模式定义了一套风格一致的函数,所以现在在R语言中使用字符串格式化多了一个更加高效的途径。

项目主页:

#https://github.com/Ironholds/pystr
devtools::install_github("nicolewhite/pystr")

备注:(如果下载失败,可以尝试先将zip文件下载到本地,然后使用菜单式命令进行安装!)

library(pystr)

顺序参数:

sprintf("Hello %s, my name is %s.", "World", "RainDu")
#'Hello World, my name is RainDu.'
pystr_format("Hello {1}, my name is {2}.", "World", "RainDu")
#'Hello World, my name is RainDu.'

以上两句等价。

以上方法在Python中应该写成如下两种形式:

print("Hello %s, my name is %s." % ("World", "RainDu"))
#Hello World, my name is RainDu.
print("Hello {0}, my name is {1}.".format("World", "RainDu"))
#Hello World, my name is RainDu.

在设置顺序参数时,pystr_format函数的优越之处在于,它真正实现了右侧待插入字符参数的批量化,即如果右侧传入的字符串参数如果有多个,你可以直接传入命名的向量或者列表。

pystr_format("Hello {thing}, my name is {name}.", thing="World", name="RainDu")pystr_format("Hello {thing}, my name is {name}.", c(thing="World", name="RainDu"))pystr_format("Hello {thing}, my name is {name}.", list(thing="World", name="RainDu"))
#'Hello World, my name is RainDu.'

以上三句等价,风格与Python中str.format风格严格保持一致。

此时左侧的插入位置仅需输入右侧的对应名称即可,左侧顺序与右侧命名序列顺序无须严格一致(因为有名称可以索引)。

当然以上三句第一句看起来不是很友好,右侧参数是单个传入的,第二句第三个比较符合使用习惯。

那么命名关键字参数在Python中写法是这样的。

print("Hello {thing}, my name is {name}.".format(thing = "World",name = "RainDu"))Hello World, my name is RainDu.my_cars <- data.frame(car=rownames(mtcars), mtcars)pystr_format("The {car} gets {mpg} mpg (hwy) despite having {cyl} cylinders.", my_cars)


借助R语言中函数强大的向量化功能,pystr_format函数可以很容易的实现批量化插入特定字符。

supers <- data.frame(             first=c("Bruce", "Hal", "Clark", "Diana"),             last=c("Wayne", "Jordan", "Kent", "Prince"),             is=c("Batman", "Green Lantern", "Superman", "Wonder Woman")             )pystr_format("{first} {last} is really {is} but you shouldn't call them {first} in public.", supers)

而同样的功能要想在Python中实现,则要么借助循环,要么借助列表表达式或者高阶函数(结合lmanda表达式)。

supers = {
            "first":["Bruce", "Hal", "Clark", "Diana"],
            "last":["Wayne", "Jordan", "Kent", "Prince"],
            "the":["Batman", "Green Lantern", "Superman", "Wonder Woman"]           }

使用普通的循环格式化:

strword = []for first,last,the in zip(supers["first"],supers["last"],supers["the"]):    print("{0:s} {1:s} is really {2:s} but you shouldn't call them {1:s} in public.".format(first,last,the))    strword.append("{0:s} {1:s} is really {2:s} but you shouldn't call them {1:s} in public.".format(first,last,the))Bruce Wayne is really Batman but you shouldn't call them Wayne in public.Hal Jordan is really Green Lantern but you shouldn't call them Jordan in public.Clark Kent is really Superman but you shouldn't call them Kent in public.Diana Prince is really Wonder Woman but you shouldn't call them Prince in public.

使用列表表达式进行格式化:

supers["strword"] = ["{0:s} {1:s} is really {2:s} but you shouldn't call them {1:s} in public.".format(first,last,the) for first,last,the in zip(supers["first"],supers["last"],supers["the"])]{'first': ['Bruce', 'Hal', 'Clark', 'Diana'],
'last': ['Wayne', 'Jordan', 'Kent', 'Prince'],
'strword': ["Bruce Wayne is really Batman but you shouldn't call them Wayne in public.",  "Hal Jordan is really Green Lantern but you shouldn't call them Jordan in public.",  "Clark Kent is really Superman but you shouldn't call them Kent in public.",  "Diana Prince is really Wonder Woman but you shouldn't call them Prince in public."], 'the': ['Batman', 'Green Lantern', 'Superman', 'Wonder Woman']}

使用高阶函数+匿名函数进行格式化

func = lambda x,y,z:"{0:s} {1:s} is really {2:s} but you shouldn't call them {0:s} in public.".format(x,y,z)supers["strword2"] = list(map(func,supers["first"],supers["last"],supers["the"]))

以上便是在R语言中使用Python风格字符串格式化输出函数的主要内容,除此之外,pystr包内还内只有很多其他常见的字符串格式化函数,很多功能在stringr包内都能找到原型,这里仅以字符串格式化输出为例,其他的感兴趣可以自行了解,不再赘述。


如果你想要深入的去学ggplot2,但是又苦于平时学习、工作太忙木有时间研究浩如烟海的源文档,那也没关系,本小编最近花了不少功夫,把我自己学习ggplot2过程中的一些心得体会、学习经验、仿入坑指南精心整理,现已成功上线了R语言ggplot2可视化的视频课程,由天善智能独家发行,希望这门课程可以给你的R语言数据可视化学习带来更加丰富的体验。

相关课程推荐

体系全面,最具调性!R语言可视化&商务图表实战课程:


点击“阅读原文”开启新姿势

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存