上回我抱怨没有现成的函数直接把 .R 脚本直接转换成 .Rmd 文档,于是自作聪明写了一个,结果很快 yihui 就留言说,有啊,knitr::spin()
就可以。我就去研究了一下这个函数,发现比我写的那个要漂亮得多。
<p dir="auto">我的心情很复杂。
<p dir="auto">话说诗仙李白当年游山玩水,看见什么就写什么,留下的诗篇个个照耀千古。有一天,他来到了黄鹤楼,照例诗兴大发,正待提笔,突然看见了墙上有前辈崔颢题写的一首七律:
<blockquote>
<p dir="auto">昔人已乘黄鹤去,此地空余黄鹤楼。
<p dir="auto">黄鹤一去不复返,白云千载空悠悠。
<p dir="auto">晴川历历汉阳树,芳草萋萋鹦鹉洲。
<p dir="auto">日暮乡关何处是,烟波江上使人愁。
<p dir="auto">李白又惊又喜,提笔想写,却发现根本写不出来。又好笑又好气,李白终于憋出了四句:
<blockquote>
<p dir="auto">一拳捶碎黄鹤楼,一脚踢翻鹦鹉洲。
<p dir="auto">眼前有景道不得,崔颢题诗在上头。
<p dir="auto">嗯,就是那种拳打脚踢的冲动。
<p dir="auto">我常常懊恼没有时间做调研,如果事先找到巨人,再爬到他肩上会看得有多远。现在,巨人来了,我打算爬上去看一看。
<h2><code>knitr::spin()的巨人之肩
<p dir="auto"><code>knitr::spin() 的<a href="https://yihui.name/knitr/demo/stitch/" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">官方文档 给出了一个<a href="https://github.com/yihui/knitr/blob/master/inst/examples/knitr-spin.R" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">示例,详细介绍了用 markdown 的逻辑来写 .R 代码的策略,而这个示例本身就是个可以转换成 .Rmd 文档的 .R 脚本。转换规则有六条:
<table>
<thead>
<tr>
<th>.R 脚本书写规则
<th><code>spin(.R脚本)得到的 .Rmd 文档
<tbody>
<tr>
<td>1. "<code>#' " 开头的注释行
<td>成为正文文字
<tr>
<td>2. "<code>#+" 开头的注释行
<td>成为代码块的选项(chunk options)
<tr>
<td>3. 双重花括号(如<code>{{mean(x)}})
<td>成为行内代码(如<code>`r mean(x)`)
<tr>
<td>4. 代码行
<td>前后添加一对连续的三个反引号,成为代码块
<tr>
<td>5. "<code>#" 开头的普通注释行
<td>保留不变,成为代码块里的注释
<tr>
<td>6. <code># /* 与 <code># */ 之间的部分
<td>跳过,不进入 .Rmd
<p dir="auto">只要按上表的第一列规则写 .R 代码,就可以一键转换成 .Rmd 文档。这个规则高明在哪里呢?
<ol>
<li>完全没有破坏 R 代码的基本规则。
<li>常用的格式基本都囊括了。
<li>照这个规则写的 R 代码赏心悦目。
<li>够简单。前三条规则可以称为“约法三章”。照这三条来写注释就行了,第 4 第 5 条不用管,第 6 条很少用。
<p dir="auto">我用这个规则写了一个脚本,成功转换,欢喜得紧。
<p dir="auto">然而,唯一的不完美在于:章节标题。
<h2><code>mindr::r2rmd():将 .R 脚本转换成 .Rmd 文档
<p dir="auto">我常常用 RStudio 的快捷键 ctrl + shift + r 在 .R 脚本里生成下面这样格式的章节标签:
<pre><code># Section label ------------
<p dir="auto">这样的话,在 RStudio 里会以大纲视图来显示章节标签,方便跳转。大纲视图在两处显示,即下图的右侧栏和底部按钮:
<p dir="auto"><img src="https://images.hive.blog/768x0/https://cdn.steemitimages.com/DQmaUZ5poerko6956f4j6FvEAmzo2GRdb231aQ8GxmpBKUD/outline.jpg" alt="outline.jpg" srcset="https://images.hive.blog/768x0/https://cdn.steemitimages.com/DQmaUZ5poerko6956f4j6FvEAmzo2GRdb231aQ8GxmpBKUD/outline.jpg 1x, https://images.hive.blog/1536x0/https://cdn.steemitimages.com/DQmaUZ5poerko6956f4j6FvEAmzo2GRdb231aQ8GxmpBKUD/outline.jpg 2x" /><br />
<p dir="auto">很容易联想到,这个标签相当于 .Rmd 里的章节标题。如果在 .R 向 .Rmd 转换的时候,能把这个映射过去就好了。
<p dir="auto">这好办,在 <code>knitr::spin() 的基础上,我新写了个 <code>mindr::r2rmd() 函数,支持下面这条规则:
<table>
<thead>
<tr>
<th>.R 脚本书写规则
<th><code>spin(.R脚本)得到的 .Rmd 文档
<tbody>
<tr>
<td>7. "<code>#= " 开头的注释行
<td>成为章节标题
<p dir="auto">例如,<code>#= ## Section 1.1 ---- 经过 <code>mindr::r2rmd()转换后,去掉了头尾,得到的是<code>## Section 1.1。
<p dir="auto">也许有人会问:为啥不直接用约法三章的第一条,<code>#' ## Section 1.1 ----来写章节标签呢?少一条规则不更好吗?
<p dir="auto">我原先也是这么想的,后来发现,<code>#' 开头的章节标签在RStudio 是不会以大纲视图来显示的。
<p dir="auto">这个问题我觉得可以择吉日提交给 RStudio。目前暂时按规则 7 行事吧。
<p dir="auto">这里有一个<a href="https://github.com/pzhaonet/mindr/blob/master/inst/examples/r/r2rmd.R" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">按上述 7 条规则写的 .R 脚本示例。
<h2><code>mindr::rmd2r(): 将 .Rmd 文档转换成 .R 脚本
<p dir="auto">上回说过,<code>knitr::purl() 可以将 .Rmd 文档转换成 .R 脚本。乍一看以为它和 <code>knitr::spin()互为反函数,但是仔细一看,并非如此,例如 chunk options 和 {{code}} 就没按原来的格式还原回去。现在,一个 .R 脚本经过上面的 <code>mindr::r2rmd() 一折腾,得到的 .Rmd 更是没法原样转换回到原来的 .R 脚本了。
<p dir="auto">怎么办?我新写了个 <code>mindr::rmd2r()函数。它跟 <code>mindr::r2rmd() 互为逆操作,目前看算是比较严格的互换:
<table>
<thead>
<tr>
<th>.Rmd 文档格式
<th><code>r2rmd(.Rmd文档)得到的 .R 脚本
<tbody>
<tr>
<td>1. 正文文字
<td>成为"<code>#' " 开头的注释行
<tr>
<td>2. 代码块的选项(chunk options)
<td>成为"<code>#+" 开头的注释行
<tr>
<td>3. 行内代码(如<code>`r mean(x)`)
<td>成为双重花括号(如<code>{{mean(x)}})
<tr>
<td>4. 代码块
<td>成为代码行
<tr>
<td>5. 代码块里的注释
<td>成为 "<code>#" 开头的普通注释行
<tr>
<td>6. <code><!-- 和<code>-->包围的内容
<td>忽略,不进入 .R 脚本
<tr>
<td>7. 章节标题
<td>成为 "<code>#=" 开头、"<code>----"结尾的章节标签
<p dir="auto">跟前面的表格算是一一对应。
<p dir="auto">这样一来,一对儿 .R 脚本和 .Rmd 文档,只需维护其中任意一个,就能直接更新到另一个里了。
<h2><code>mindr::r2mm()和<code>mindr::mm2r():.R 脚本和思维导图的相互转换
<p dir="auto">上面说的,纯属狗拿耗子多管闲事。mindr 本来是做思维导图的。
<p dir="auto">不过,既然我们按上面表格约定的规则来写 .R 脚本,那么先<code>mindr::r2rmd()再<code>mindr::md2mm(),两步就可以把脚本里的大纲提取出来,生成思维导图了。我把这两步打了个包,新写了函数叫 <code>r2mm(),直接从 .R 脚本生成思维导图。当然,反过来就是 <code>mm2r(),从思维导图来创建一个 .R 脚本,以符合上面约定的规则。
<p dir="auto">天下终于太平了。
<p dir="auto"><img src="https://images.hive.blog/768x0/https://github.com/pzhaonet/mindr/raw/master/showcase/mindr_concept_1.1.8.png" srcset="https://images.hive.blog/768x0/https://github.com/pzhaonet/mindr/raw/master/showcase/mindr_concept_1.1.8.png 1x, https://images.hive.blog/1536x0/https://github.com/pzhaonet/mindr/raw/master/showcase/mindr_concept_1.1.8.png 2x" /><br />
<br /><center><hr /><em>Posted from my blog with <a href="https://wordpress.org/plugins/steempress/" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">SteemPress<span> : <a href="http://dapengde.com/archives/19803" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">http://dapengde.com/archives/19803<hr />
不明觉厉
累觉不爱
啊!你搞了这么多人在你下面,运动得过来吗?@teamcn-shop,来个套套吧!
Posted using Partiko iOS
@julian2013给您叫了一份外卖!
超高质越南牛肉Pho
吃饱了吗?跟我猜拳吧! 石头,剪刀,布~由 @kidsreturn 小兔子 迎着飓风 开着轮船给您送来
如果您对我的服务满意,请不要吝啬您的点赞~