在R工作流中编写函数与逐行解释

在R工作流中编写函数与逐行解释,r,workflow,statistics,R,Workflow,Statistics,关于在R中为统计项目开发工作流,这里已经写了很多。最流行的工作流似乎是。带有包含代码的main.R: source('load.R') source('clean.R') source('func.R') source('do.R') 这样一个源('main.R')就可以运行整个项目 问:与在load.R、clean.R和do.R中执行的逐行解释性工作被main.R调用的函数替换相比,是否有理由选择此工作流 我现在找不到链接,但我已经读到了一些东西,所以当用R编程时,人们必须克服他们想用函数调

关于在R中为统计项目开发工作流,这里已经写了很多。最流行的工作流似乎是。带有包含代码的
main.R

source('load.R')
source('clean.R')
source('func.R')
source('do.R')
这样一个
源('main.R')
就可以运行整个项目

问:与在
load.R
clean.R
do.R
中执行的逐行解释性工作被
main.R
调用的函数替换相比,是否有理由选择此工作流

我现在找不到链接,但我已经读到了一些东西,所以当用R编程时,人们必须克服他们想用函数调用来写所有东西的愿望——R应该是逐行写的解释形式

问:真的吗?为什么?

我对LCFD方法感到失望,我可能会用函数调用来编写所有内容。但在做这件事之前,我想听听美国的好朋友们的意见,看看这是不是一个好主意


编辑:我现在正在做的项目是(1)读入一组财务数据,(2)清理数据(非常复杂),(3)使用我的估计器估计与数据相关的一些数量(4)使用传统估计器估计相同的数量(5)报告结果。我的程序应该以这样一种方式编写:(1)对于不同的经验数据集,(2)对于模拟数据,或者(3)使用不同的估计值,这是轻而易举的。此外,它还应该遵循有文化的编程和可复制的研究指导原则,以便代码新手能够简单地运行程序,了解发生了什么,以及如何调整它。

我认为没有一个单一的答案。最好的办法是记住相对的优点,然后为这种情况选择一种方法

1) 函数。不使用函数的优点是,所有变量都留在工作区中,您可以在最后检查它们。如果你有问题,这可能会帮助你弄清楚发生了什么

另一方面,设计良好的函数的优点是可以对它们进行单元测试。也就是说,您可以将它们与代码的其余部分分开进行测试,从而使它们更易于测试。此外,当您使用函数时,对某些较低级别的构造进行模化,您知道一个函数的结果不会影响其他函数,除非它们被传递出去,这可能会限制一个函数的错误处理可能对另一个函数造成的损害。您可以使用R中的
debug
功能来调试函数,并且能够单步调试函数是一个优势

2) LCFD.关于是否应该使用load/clean/func/do分解,而不管它是通过
源代码还是函数完成的,这是第二个问题。无论分解是通过
源代码还是函数完成的,这种分解的问题在于,您需要运行一个分解,以便能够测试下一个分解,因此无法真正独立地测试它们。从这个角度看,这不是理想的结构

另一方面,它的优点是,如果要在不同的数据上尝试加载步骤,则可以独立于其他步骤替换加载步骤;如果要尝试不同的处理,则可以独立于加载和清理步骤替换其他步骤

3) 文件数量您所问的问题中可能隐含着第三个问题,即所有内容是否都应包含在一个或多个源文件中。将内容放在不同的源文件中的优点是,您不必查看不相关的项目。特别是,如果您的例程未被使用或与您正在查看的当前函数无关,则它们不会中断流程,因为您可以将它们安排在其他文件中

另一方面,从(a)部署的角度来看,将所有内容放在一个文件中可能有一个优势,即您可以只向某人发送单个文件,以及(b)编辑方便,因为您可以将整个程序放在单个编辑器会话中,例如,方便搜索,因为您可以使用编辑器的函数搜索整个程序,而不必确定例程所在的文件。此外,连续的撤消命令将允许您在程序的所有单元之间向后移动,并且一次保存将保存所有模块的当前状态,因为只有一个模块。(c) 速度,即如果您在慢速网络上工作,则在本地计算机中保留一个文件,然后偶尔将其写出来可能会更快,而不必往返于慢速远程计算机


注意:需要考虑的另一件事是,相对于最初的文件源,使用软件包可能更适合您的需求。

我认为在源文件中创建的任何临时内容都不会得到清理。如果我这样做:

x=matrix(runif(big^2),big,big)
z=sum(x)
作为一个文件,x挂起,虽然我不需要它。但如果我这样做:

ff=function(big){
 x = matrix(runif(big^2),big,big)
 z=sum(x)
 return(z)
}
在我的脚本中,doz=ff(big)代替了source,x矩阵超出了范围,因此得到了清理

函数可以实现整洁的可重用封装,并且不会污染外部环境。一般来说,它们没有副作用。逐行脚本可能会使用全局变量和名称,这些变量和名称与当前使用的数据集相关联,这使得它们无法再使用


我有时会一行一行地工作,但当我得到大约五行以上的代码时,我发现我真正需要的是将其转换成一个适当的可重用函数,通常情况下,我都会重复使用它。

在编写函数时,没有人提到一个重要的考虑因素:除非你一次又一次地重复某些操作,否则编写函数没有多大意义。在分析的某些部分,您将执行一次性操作,因此为它们编写函数没有多大意义。如果你必须重复一些事情
save(list=ls(), file="Cleaned.Rdata")
load("Cleaned.Rdata")
df.YYYY # Data for a certain year
demo.describe.YYYY ## Demographic data for a certain year
po.describe ## Plot option
list.describe.YYYY ## lists
f.describe ## Functions