如何确保模拟结果和论文中的结果始终保持同步?


34

在我的一篇论文中,我列出了一些数字结果以及一些数字。我想做的是确保论文中的数值结果始终与代码一致。现在,我只是将模拟结果的数值结果直接复制到纸张中,这非常简单且技术含量低,但容易出错,因为我可能会错误地复制结果,或者忘记将纸张结果与代码输出。

有没有一种很好的方法可以使我在论文中引用的数值结果与我的代码生成的结果保持同步?(在这里,我认为执行代码很容易且实用,只要我想更新论文即可。)这些数值结果不一定适合表格形式。有时,手稿中有表格,但更常见的是,我在方程式中将仿真参数列为数字。例如:

y=(y1,,yn)

我想替换初始条件y 的元素y用实际参数我在模拟中使用了实际参数,该模拟对常微分方程组进行了数值积分。使用一个表来处理一次性数据(例如本例)似乎是多余的,而且墨水过多。

我认为数字是一种更简单的情况:只要“构建”文档(从LaTeX源,Markdown,RST等),就可以通过执行代码来开始构建过程。但是,如果人们有更好的建议可以使模拟生成的图形与我的论文保持同步,那么我很乐意听到它们。

Answers:


14

正如一些评论所建议的那样,这种方法在R社区中早已建立Sweave并发展了knitr。显然,这种方法目前具有特定于语言的缺点,但其优点是经常在学术论文中使用。

在实际出版物中使用Sweave

  • 杂志的生物统计学鼓励这些意见,并把一个风筝标志字母“R”的学术论文,其中重现性编辑器已经能够运行的代码和数据,并得到了这些结果。
  • 基本上,R-Journal中的所有出版物都基于Sweave。

当然,更常见的是,Sweave / knitr用户只将最终输出提交给大多数期刊,并确信这些方法确实可以复制结果。同样,sweave通常用于创建用于专业演讲等的幻灯片。

有用的功能

为了在实践中有用,这种系统应具有某些功能。随着大量用户的使用,其中许多人已经发展成熟knitr。一些要点:

  • 正在缓存。以诸如markdown或Latex之类的格式编写,必须对其进行编译才能查看输出,这使得当无法缓存结果时,无法包括其中的代码。knitr实际上,聪明的缓存实际上使调试密集型代码比使用pure容易得多R,因为不必重新运行成功的块。

  • 切换代码显示。在正式出版物中,可能不希望任何基础代码在输出中可见。同时,当您希望读者确切看到您正在键入的内容时,以输出格式显示生成结果的(格式正确,语法突出显示)的代码通常很有价值。

  • 社区。与自制解决方案相比,这种方法最引人注目的优势是熟悉该模型并试图对其进行改进的人员数量。

  • knitr网页演示中可以找到许多其他功能的漂亮示例,包括“轻量级发布”或在网络上共享的工具。这些功能中的许多功能有助于使该方法与人的一般工作流程更加兼容,而不是仅在撰写稿件时要做的事情。

历史脚注。

顾名思义,它扎根于Knuth的“文学编程”,但重点却大不相同,因为文学编程专注于连接软件代码和文档(在R社区中,角色由扮演Roxygen,其根源可追溯至)的不同分支。 “识字编程树”)。

超越

原则上,我们可能会向动态文档提出更多要求,例如读者具有更改输入和查看输出的能力,而无需编辑和重新编译整个文档(例如,使用交互式在线平台)。 XDynDocs可能是朝这个方向迈出的一步。

其他方法

  • 可能希望关注dexy.it
  • 用一种稍微不同的方法:越来越多的经济学论文托管与http://www.runmycode.org/上的出版物关联的代码,这些代码将在云上重新运行分析,并允许自定义输入参数或自定义输入数据。

卡尔,我一直关注您的网站已有一段时间,而您使用knitr的方法是我提出问题的灵感之一。我也一直关注dexy一段时间,因为Zed Shaw使用它来构建他的书《如何以困难的方式学习Python》的源代码(请参阅git repo)。与其他有素的编程方法相反,我喜欢dexy的是,代码和文本是松散耦合的,可以合理使用调试器。
Geoff Oxberry 2012年

杰夫,很酷,感谢您的评论!安娜·纳尔逊(Anna Nelson)也非常相信去耦。R用户可以使用代码外部化或新spin()功能在knitr中完成解耦。我个人认为,格雷格·威尔逊(Greg Wilson)对识字编程的抱怨过时了。我曾经用noweb经历过同样的糟糕经历,但是在现代工具中根本不存在复杂的调试。对于识字的CI,请使用氧气。借助缓存和环境处理,Knitr比R更易于调试。
cboettig 2012年

20

您需要的是“可执行文件”的Elsivier挑战。尽管尝试了许多方法,但没有一种方法能像作者建议的那样令人信服。以下是一些使用的技术示例。

马达加斯加计划(Madagascar Project)采用您的方法,在制作脚本内运行模拟,以同时生成图形和纸张。

IPython Notebook提供了一个文档,您可以在阅读该文档时执行该文档,并制作出令人心动的图形。(我已经看到了单词插件,Mathematica和以相同方式使用的许多其他解决方案)

VisTrails使用面向服务的体系结构方法,并提供“ ”或“工作流”管理器。基本上,您注册钩子以进行编码,然后设计可重现您的工作的工作流程或实验。它已用于许多类型的代码,甚至是HPC集群。使用这种方法,您将可以重播实验。

那里有大量此类解决方案,但我印象深刻的是其中的三个。这是一个艰巨的问题,我相信我们真的还没有解决。我们甚至无法让人们随他们的论文一起发布他们的代码,我们如何期望他们重现结果= P


同样,sweave并不是我使用的东西,但是在概念上很有趣。
dmckee

当我听一位作者的演讲时,马达加斯加计划似乎很有趣。我实际上并没有尝试使用它。

@dmckee:我知道谁曾与sweave和良好的成功的人knitr。出于格雷格·威尔逊(Greg Wilson)在Software Carpentry上给出的相同原因,我对识字编程方法持怀疑态度:纸张和代码过于紧密地耦合在一起,这使得很难在代码上运行调试器(并且可能会打样)文本)。
Geoff Oxberry 2012年

我为此目的使用了Sweave,它工作得非常好,并且可以与Lyx兼容。组织模式甚至更好,并支持大多数通用语言。
David LeBauer 2012年

13

在使用其他人的解决方案来解决这个问题上,我并没有取得很大的成功。我通常只希望一些简单的东西对我有用,并能完成工作。为此,我通常尝试编写一个python脚本,该脚本负责运行所有结果,解析输出以及构建图形/表格。

我编写代码以生成包含某些文本格式结果的数据文件。您可以通过先测试输出文件的存在来避免在脚本中重新运行这些结果(例如,在python中使用os.path.isfile())。如果要重新运行结果,只需删除数据文件。如果数据文件存在,那么我将运行这些文件的解析器。为此,用于正则表达式的python模块非常有用(重新)。

然后从解析的输出中创建图或表。对于乳胶中的表格,您可以编写代码以将表格生成到单独的文件中(我使用.tbl扩展名),然后将其包含在乳胶文件中。他们的关键是要使用1个python脚本。如果我有很多人,那我以后会怀疑是哪个,他们做什么。如果这个描述太含糊,我可以给你举一些例子。


1
我已经为数字做过这种事情。但是,在我写的论文中,表格将是一种不自然的格式来表示数据。通常,我真的只是想将ODE的初始条件包括在内(实际上,像4-6个数字一样,用逗号隔开),或者将整个数字矩阵包含在等式的右侧。我喜欢你的餐桌想法。对于我提到的那些情况,我觉得将它们重新格式化为表格是不自然的,并且我希望以更自然的格式包含数据。
Geoff Oxberry 2012年

内森,您介意发布示例吗?除了将文本文件提交到git中并使用git管理结果外,我使用相同的方法。然后,我有了Python脚本来生成图/表。每个图或表都有一个脚本。
昂德里杰·塞蒂克

您还可以使用以下命令将Shell脚本的输出直接通过管道传递到Latex \input{|"path-to-script.py"}。我认为您最好将所有参数放在单个python(或您喜欢的任何语言)文件中,然后使用命令行参数像一样访问它\input{|"path-to-script.py param-name"}。在这种情况下,您可以将param文件包含在其他脚本中以运行模拟。但是,这会使编译速度变慢,并具有其他一些负面影响。
氦气2012年


7

在我看来,更重要的是确保您能弄清楚如何在一个月或一年内从头开始重新生成所有结果(例如,当裁判员要求您添加或修改某些内容时)。为此,我要做的是包括一个文本文件,其中包含有关如何重现所有结果的非常详细的说明。最好是让其他人(例如合著者)尝试一下以进行测试。我建议您还将这些说明(以及所有代码)提供给裁判和读者。

这是一个示例(实际上是我的合著者阿隆·艾哈迈迪亚(Aron Ahmadia)准备的)。


我以前已经这样做过(出于我自己的理智),而且值得庆幸的是,当我的顾问要求我重新生成并重新检查结果时,它才奏效。从那以后,我转为仅转储脚本的源代码,该脚本将所有内容运行到草稿的附录中,因此就在那,我知道我做了什么,我可以单击一个按钮来获取所有数字和数字。
Geoff Oxberry 2012年

该脚本目前不执行任何安装,因为它只是一个MATLAB脚本。在功能文档中,它列出了对第三方程序包的依赖关系。相应地,这些第三方软件包都具有有关如何安装它们的清晰文档(并且值得庆幸的是,它们也得到了积极的支持,拥有出色的开发人员和活跃的邮件列表)。
Geoff Oxberry

6

Emacs的orgmode与Babel结合实现了这一目标。Babel可以执行来自各种编程和脚本语言的代码片段,例如,它可以打开包含模拟数据的文件,并将其放入orgmode表中,然后可以导出为LaTeX(以及许多其他格式)。习惯组织模式中的所有关键组合需要花费相当长的时间,但是一旦运行,一切都会自动进行。


我喜欢组织模式;我用它来勾勒轮廓。我没有和Babel一起使用过。我必须尝试一下。
Geoff Oxberry 2012年

这是2012年1月J. Stat的出色概述。软件jstatsoft.org/v46/i03/paper
David LeBauer 2012年

我写了一个教程,展示了如何将LaTeX模板从《欧洲物理期刊A》(EPJ A)转换成组织模式文件。
Melioratus

4

如果运行所有代码都很便宜,则可以执行以下低技术操作:

您可以使用带格式的字符串将文档模板化,以便它们看起来像这样

"we observed a %(fractional_improvement)s increase in ..."

有看起来像这样的python脚本

results = {"alpha"                  : run_alpha_computation(...),
           "fractional_improvement" : run_fi_computation(...), 
           ...}

然后做这样的事情

for fn in filenames:
    file = open(fn);      s = file.read();       file.close()
    file = open(fn, 'w'); file.write(s%results); file.close()

然后,您可以将其包装在Makefile中。


当我写这个问题时,我的第一个想法是一个类似于您所提出的解决方案。我最初想到的是诸如使用宏预处理器之类的技术含量较低的技术,但是Python可能是一种更好的方法(并且当然更具可读性),然后构建系统可以处理结果的增量再生。
Geoff Oxberry 2012年

确实,这只是python服务器页面之类的非常基本的实现。自动生成内容的想法已经在网络社区中流行了一段时间。很高兴看到它迁移到学术界。
MRocklin

同意 Jinja2可用于执行您建议的操作。实际上,这就是dexy的功能,但是它带有很多很酷的过滤器,它们还可以处理语法突出显示和其他杂项任务。
Geoff Oxberry 2012年

4

如果您使用的是LaTeX,则技术含量较低的解决方案是让您的代码吐出一个文件(或者使用脚本从代码输出中进行过滤),该文件包含以下几行代码:

\newcommand{\myresults1}{<value>}

然后,您可以使用\input命令将该文件添加到文档中,并使用定义的命令放置值。


2

我为爱思唯尔工作。我的公司已开始在期刊问题中使用Collage框架(为响应Executable Paper Grand Challenge而开发),以使作者能够在其文章中发布大块可执行代码。此功能使读者可以更轻松地复制文章中报告的结果,并将已出版的材料重新用于自己的研究。Collage支持多种开源和专有软件;可以在此处的参考视频和Collage Authoring Environment网站中找到更多信息。


第二个链接是错误的事情。
David Ketcheson

@Hylke Koers:您是说要放置此链接:Collage.elsevier.com吗?
保罗

@Paul:我进行了修改;最初的第二个链接是Collage Google Group。也许更好的链接应该是Collage本身,但我的重点是尝试(主要)保留帖子的良好意图,同时删除使之听起来很促销的部分。随时根据需要编辑帖子。
Geoff Oxberry 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.