更准确地说,我仍然不明白有人如何从研究论文转到例如 R 包。
就像生活中的很多事情一样,有时最困难的部分才刚刚开始。很多人为失败做好了准备,只是,好吧,认为他们没有做好足够的准备并且会失败,所以他们甚至在尝试之前就已经放弃了。
话虽如此,你必须至少知道一点才能开始。在基于论文编写 R 包的上下文中,您不一定需要熟悉主题背后的数学或理论才能开始。您可能会发现编写包的过程实际上有助于加深您最终想要拥有的理解,并且随着时间的推移,您将对反映这一点的包进行更改。实际上,我有一个非常健壮、用户友好的 R 包,我就是在这种情况下开始的。我有很多编程经验,我认识的一个人有他一直在开发的这个不平凡的理论,但没有能力在一个包中正确实现,所以他让我帮忙。数学和理论的细节对我来说大多是陌生的,因为我的专长在其他地方。我没有' 那时甚至不知道创建 R 包的细节。但是现在,在完成了创建包的过程之后,我什至能够对理论及其应用做出自己的贡献和进步。
首先,您需要做的是考虑用户可能想要的包中的内容。这篇论文提出了哪些潜在用户会发现有用的信息?这确实需要至少对论文完成的内容有一个高层次的理解;大概,如果您不知道论文的内容,您就不会尝试为论文编写包。因此,列出用户想要的东西。现在将这些项目分配给函数名称,而不用担心这些函数内部如何工作的细节。例如,您可能有一个执行核心统计分析的函数,一个计算置信区间的函数,一个计算方差的函数,还有一个执行基本可视化的函数。
接下来,这些功能需要哪些最基本的输入?可能有很多小东西对功能的便利性、调整或灵活性有用,但这些还不重要。重要的是让基本功能运行起来;您可以稍后返回并处理更精细的细节,以免它们现在让您不知所措。
现在,这些函数返回的值是什么?换句话说,用户期望或发现在结果方面最有用的是什么?其中一部分可能最终会被前面关于输入的观点塑造或塑造。如果你有一个函数建立在另一个函数的结果之上,那么一个函数的输入将成为另一个函数的输出。因此,根据具体情况,您可能有一个函数返回简单的东西,如数字或向量,而您可能有另一个函数返回复杂的东西,如列表或类对象。
一旦你有了一个你想要的函数列表,它们需要什么输入,以及它们产生什么,你现在就拥有了一个基本骨架包所需的东西。因此,通过创建一堆空函数开始编码。或者也许只是让他们打印一些东西。如果您以前从未编写过软件包,那么现在是尝试构建和安装它(在您的计算机上本地)以确保它工作的好时机。在您工作时,定期构建、安装、加载和测试您的包,以确保一切都按照您的想法进行。
最后,通过骨架包设置,您现在可以开始深入研究数学/理论细节。你的函数可以作为指导来帮助你分解这个任务,这样你就不会试图通过一次专注于所有事情来压倒自己。只专注于一件事,并努力让函数的基础知识运行起来。此时您绝对不应该担心性能。其他事情也一样,比如带有输入数据的奇怪的极端情况。您应该专注于以尽可能简单的方式实现事物。一旦一切都在运行并且您对一切都有更好的感觉,那么您就可以重新访问。
最终,您将更深入地了解您正在尝试使用您的包完成什么。您可能会发现自己意识到您需要一些以前没有想到的功能,或者可能需要组合您的几个功能。你甚至可能回过头来意识到有一种完全不同的做事方式更好。对于我的包,v0.1.0(本质上是一个测试版)和 v1.0.0(第一个生产版本)是不同的。我从头开始完全重写了 v1.0.0 的包。v0.1.0 非常适合学习,不仅是数学和理论,还有我的框架决策作为用户和包维护者的感受。事实证明,这对双方来说都是笨重且令人不快的,并且值得投资进行全面检修。所以不要担心马上让它变得完美;花点时间在预发布阶段进行尝试,最好让一些潜在用户有机会尝试并提供反馈。我无法告诉你其他人的真实世界数据多久会暴露你从未考虑过的奇怪的极端情况......
一些额外的提示:
- 技术债务:有时会有多种方式来完成一项任务。在发布您的包之前,您需要提前考虑这些选择的含义,因为如果您只是采取简单的方法,您可能会发现以后要花费大量时间来解决问题。最好在发布之前处理好这一点,因为您希望避免在用户开始使用包后破坏他们的东西。有大量关于“技术债务”的文章。花一些时间阅读其中的一些。
- 维护负担:如果你打算创建一个 R 包,请致力于维护它。我在科学软件中看到的一个大问题是,许多人将软件/软件包作为出版物的一次性任务发布,然后让它腐烂,当软件出现问题时,这最终会花费其他人大量的时间和精力为他们。希望你不是其中之一。为此,您必须了解您在设计包装时的选择将如何影响您以后的时间承诺。您添加的每一件小事都是一件可能会破坏的事情,需要测试,需要对用户的支持等,从而导致花费更多时间来维护您的包,而不是您想做的其他事情。因此,请谨慎对待添加的内容和从功能列表中删除的内容;如果您尝试添加人们想要的每一个方便的小东西,那么您以后会后悔的。考虑你的包需要哪些外部包也是如此;您添加的每个依赖项都是另一个人在他们的包中进行的更改以破坏您的包的机会。
- 要发布 R 包,请将其放在 CRAN 上。我无法告诉你有多少次我查看了非 CRAN 包的 GitHub 存储库(带有经过同行评审的出版物),只是为了发现 CRAN 的“烦人”政策可以防止的基本缺陷。说真的,我查看的一个包改变了许多其他常见包隐式依赖的多个默认 R 行为。只需加载包,它就可以完全改变其他包的行为,这种方式完全静默,结果变化不明显,并且只能通过重新启动 R 轻松修复(并且永远不会再次加载包)。CRAN 包中明确禁止此包用于执行此操作的命令。如果作者试图发布到 CRAN,他们会抓住它(或者他们确实尝试过并决定它不是
- 使用自动化测试(对于 R,请参阅“testthat”包)。这确实应该是任何软件包的要求。不幸的是,仅仅因为一个包有单元测试并不意味着它做得很好。弄清楚如何做好它可能是一种艺术形式。
- 良好的文档是必要的。而且我不仅仅指典型的 R 函数引用。我希望大多数人都能从各种解释概念和举例的教程/小插曲中受益。尝试写这些实际上将有助于您自己对数学和理论的理解,或者至少让您对所学内容充满信心。对于 R,我建议为此查看“pkgdown”包;它可以帮助您为您的包构建一个网站,该网站作为包的 GitHub 存储库的一部分托管。
一些告别的话:如果您要为科学家编写软件,请记住责任的重要性。如果你真的全身心投入并且做对了,你可以对许多人更有效地进行研究的能力产生巨大的影响。但是,如果你半途而废或懒于维护它,你可能会搞砸很多人,并花费他们大量的时间、精力和潜在的金钱。无论哪种方式,你都有可能对科学产生巨大的影响,而你通常只呆在你自己的小研究泡沫中就可能不会产生这种影响。