Dan*_*ein 157 r conventions code-organization project-organization package
当我承担任何复杂的R项目时,我的脚本会很快变得混乱.
我可以采用哪些做法,以便我的代码永远乐于与之合作?我在考虑类似的事情
基本上,组织大型R脚本的经验法则是什么?
Dir*_*tel 69
标准答案是使用包 - 请参阅Writing R Extensions手册以及Web上的不同教程.
它给你
R CMD check
只是运行source()
代码适用于非常短的代码片段.其他所有内容都应该在一个包中 - 即使您不打算发布它,因为您可以编写内部存储库的内部包.
至于"如何编辑"部分,R Internals手册在第6节中具有优秀的R编码标准.否则,我倾向于在Emacs的ESS模式中使用默认值.
更新2008年8月13日: David Smith刚刚发布了关于Google R风格指南的博文.
Bre*_*nor 50
我喜欢在自己的文件中添加不同的功能.
但我不喜欢R的包装系统.它很难使用.
我更喜欢轻量级的替代方法,将文件的函数放在一个环境中(所有其他语言都称之为"命名空间")并附加它.例如,我创建了一个'util'组函数,如下所示:
util = new.env()
util$bgrep = function [...]
util$timeit = function [...]
while("util" %in% search())
detach("util")
attach(util)
Run Code Online (Sandbox Code Playgroud)
这都在文件util.R中.当您获取它时,您将获得环境'util'以便您可以调用util$bgrep()
等等; 但此外,这个attach()
电话使它如此公正,bgrep()
并且直接进行了这样的工作.如果你没有将所有这些函数放在他们自己的环境中,他们会污染解释器的顶级命名空间(ls()
显示的那个).
我试图模拟Python的系统,其中每个文件都是一个模块.那会更好,但这似乎没问题.
ars*_*ars 33
这可能听起来有点明显,特别是如果你是一个程序员,但这就是我如何考虑逻辑和物理代码单元.
我不知道这是不是你的情况,但是当我在R工作时,我很少开始考虑大型复杂程序.我通常从一个脚本开始,将代码分成逻辑上可分离的单元,通常使用函数.数据操作和可视化代码被放置在它们自己的函数等中.并且这些函数被组合在文件的一个部分中(顶部的数据操作,然后是可视化等).最终,您需要考虑如何使您更容易维护脚本并降低缺陷率.
你的功能如何细/粗粒度会有所不同,并且有各种经验法则:例如15行代码,或者"一个函数应该负责执行一个由其名称标识的任务",等等.你的里程会有所不同.由于R不支持call-by-reference,因此当我涉及传递数据帧或类似结构时,我通常会使我的函数太精细.但是,当我第一次开始使用R时,这可能会对一些愚蠢的性能错误进行过度补偿.
何时将逻辑单元提取到自己的物理单元(如源文件和更大的分组包)?我有两个案例.首先,如果文件太大并且在逻辑上不相关的单元之间滚动是一个烦恼.其次,如果我有其他程序可以重用的功能.我通常首先将一些分组单元(比如数据操作函数)放入一个单独的文件中.然后我可以从任何其他脚本中获取此文件.
如果您要部署您的功能,那么您需要开始考虑包.我不会出于各种原因在生产中部署R代码或由其他人重复使用(简要说明:org culture更喜欢其他语言,对性能的担忧,GPL等).此外,我倾向于不断改进并添加到我的源文件集合中,当我进行更改时,我宁愿不处理包.因此,您应该查看其他与软件包相关的答案,例如Dirk's,了解有关此方面的更多详细信息.
最后,我认为你的问题不一定特别适用于R.我真的建议阅读Steve McConnell的Code Complete,其中包含了很多关于此类问题和编码实践的智慧.
gap*_*ppy 15
我的简明回答:
我相信R越来越多地用于生产,因此对可重用代码的需求比以前更大.我发现解释器比以前更强大.毫无疑问,R比C慢100-300倍,但通常瓶颈集中在几行代码上,可以委托给C/C++.我认为将R在数据处理和统计分析方面的优势委托给另一种语言是错误的.在这些情况下,性能损失很低,在任何情况下都值得节省开发工作.如果单独执行时间,我们都会编写汇编程序.
hat*_*rix 11
我一直想知道如何编写包但没有投入时间.对于我的每个迷你项目,我将所有低级函数保存在一个名为"functions /"的文件夹中,并将它们发送到我明确创建的单独命名空间中.
以下代码行将在搜索路径上创建名为"myfuncs"的环境(如果它尚不存在)(使用attach),并使用我的'functions /'目录中.r文件中包含的函数填充它(使用sys.source).我通常将这些行放在我的主脚本的顶部,用于"用户界面",从中调用高级函数(调用低级函数).
if( length(grep("^myfuncs$",search()))==0 )
attach("myfuncs",pos=2)
for( f in list.files("functions","\\.r$",full=TRUE) )
sys.source(f,pos.to.env(grep("^myfuncs$",search())))
Run Code Online (Sandbox Code Playgroud)
当您进行更改时,您始终可以使用相同的行重新获取它,或使用类似的内容
evalq(f <- function(x) x * 2, pos.to.env(grep("^myfuncs$",search())))
Run Code Online (Sandbox Code Playgroud)
评估您创建的环境中的添加/修改.
我知道这是kludgey,但避免过于正式(但如果你有机会我鼓励包系统 - 希望我将来会以这种方式迁移).
至于编码惯例,这是我唯一看到的关于美学的东西(我喜欢它们并且松散地遵循但我不会在R中使用过多的花括号):
http://www1.maths.lth.se/help/R/RCC/
关于使用[,drop = FALSE]和< - 作为赋值运算符在useR的各种演示文稿(通常是主题演讲)中建议,还有其他"约定"!会议,但我不认为这些都是严格的(虽然[,drop = FALSE]对于你不确定你期望的输入的程序是有用的).
算我另一个人赞成包裹.我承认在编写手册页和小插图时非常差,直到我必须(即被释放),但它是一个真正方便的方法来捆绑源母公司.另外,如果你认真对待维护你的代码,那么Dirk带来的所有观点都会进入plya.
归档时间: |
|
查看次数: |
24658 次 |
最近记录: |