R中的编码实践:不同风格的优缺点是什么?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了R中的编码实践:不同风格的优缺点是什么?相关的知识,希望对你有一定的参考价值。

最近关于使用require与::的问题引发了关于在R中编程时使用哪种编程风格的问题,以及它们的优点/缺点。浏览源代码或在网上浏览,您会看到许多不同的样式显示。

我的代码中的主要趋势:

  • 重度矢量化我使用索引(和嵌套索引)玩了很多,这有时会产生相当模糊的代码,但通常比其他解决方案快得多。例如:x[x < 5] <- 0而不是x <- ifelse(x < 5, x, 0)
  • 我倾向于嵌套函数以避免使用我需要清理的临时对象来重载内存。特别是对于操纵大型数据集的函数,这可能是一个真正的负担。例如:y <- cbind(x,as.numeric(factor(x)))而不是y <- as.numeric(factor(x)) ; z <- cbind(x,y)
  • 我编写了很多自定义函数,即使我只在例如一次使用代码。一个sapply。我相信它可以让它更容易阅读,而不会产生可以保持躺着的物体。
  • 我不惜一切代价避免循环,因为我认为矢量化更清洁(更快)

然而,我注意到对此的看法不同,有些人倾向于背弃他们所谓的“Perl”编程方式(甚至是“Lisp”,所有这些括号都在我的代码中飞来飞去。我不知道虽然走得那么远。

您认为R中的良好编码实践是什么?

您的编程风格是什么,您如何看待它的优缺点?

答案

我所做的将取决于我编写代码的原因。如果我正在为我的研究(日常工作)编写数据分析脚本,我想要一些有效的东西,但几个月甚至几年后都是可读和可理解的。我不太关心计算时间。使用lapply等进行矢量化。可以导致混淆,我想避免。

在这种情况下,如果lapply让我跳过箍来构造适当的匿名函数,我会使用循环进行重复过程。我会在你的第一颗子弹中使用ifelse(),因为至少在我看来,这个调用的意图比子集+替换版本更容易理解。通过我的数据分析,我更关心的是让事情变得正确,而不是计算时间 - 当我不能在办公室工作时,总会有周末和夜晚。

对于你的其他子弹;我倾向于不内联/嵌套调用,除非它们非常微不足道。如果我明确地说明了这些步骤,我发现代码更容易阅读,因此不太可能包含错误。

我一直在编写自定义函数,特别是如果我要在循环或类似函数中重复调用函数的代码。这样我就将代码从主数据分析脚本中封装到它自己的.R文件中,这有助于保持分析的意图与分析的完成方式不同。如果该功能有用,我可以将其用于其他项目等。

如果我正在编写一个包的代码,我可能会以与我的数据分析(熟悉度)相同的态度开始,以获得我所知道的工作,然后只有在我想改进计算时间时才进行优化。

我试图避免做的一件事是,当我编码时,无论我编码什么,都太聪明了。最终,我从来没有像我想象的那样聪明,如果我保持简单,那么如果我想要聪明的话,我往往不会像往常那样经常摔倒在脸上。

另一答案

我为各种代码块编写函数(在独立的.R文件中),这些代码在概念上做了一件事。这使事情变得简短而甜蜜。我发现调试有点容易,因为traceback()会给你哪个函数产生错误。

我也倾向于避免循环,除非绝对必要。如果我使用for()循环,我觉得有点脏。 :)我努力做所有矢量化或应用系列。这并不总是最好的做法,特别是如果您需要向另一个不熟练应用或矢量化的人解释代码。

关于使用require::,我倾向于使用两者。如果我只需要某个软件包中的一个函数,我可以通过::使用它,但如果我需要多个函数,我会加载整个软件包。如果包之间的函数名称存在冲突,我会尝试记住并使用::

我试图为我想要实现的每项任务找到一个函数。我相信在我之前的某个人已经想到了它并且创造了一个比我能想到的任何东西都更好的功能。这有时是有效的,有时不是那么多。

我尝试编写代码以便能够理解它。这意味着我会进行很多评论并构建代码块,以便它们能够以某种方式遵循我想要实现的目标。我经常在函数进展时覆盖对象。我认为这保持了任务的透明度,特别是如果你稍后在函数中引用这些对象。当计算时间超过我的耐心时,我会想到速度。如果一个函数需要很长时间才能完成,我开始浏览SO,我看是否可以改进它。

我发现一个好的语法编辑器,代码折叠和语法着色(我使用Eclipse + StatET)给我带来了很多麻烦。

基于VitoshKa的帖子,我补充说我使用大写词(sensu Java)作为函数名称,并使用fullstop.delimited作为变量。我看到我可以有另一种函数参数样式。

另一答案

命名约定对于代码的可读性非常重要。受R的S4内部风格的启发,我使用的是:

  • camelCase用于全局函数和对象(如doSomething,getXyyy,upperLimit)
  • 函数以动词开头
  • 未导出,辅助函数始终以“。”开头。
  • 局部变量和函数都是小写字母和“_”语法(do_something,get_xyyy),它可以很容易地区分本地变量和全局变量,从而导致更清晰的代码。
另一答案

对于数据杂耍,我尝试尽可能多地使用SQL,至少对于GROUP BY平均值这样的基本内容。我很喜欢R,但有时候你会发现你的研究策略还不够好,无法找到隐藏在另一个包中的另一个功能。对于我的情况,SQL方言没有太大差异,代码非常透明。大多数情况下,阈值(何时开始使用R语法)相当直观。例如

require(Rmysql)
# selection of variables alongside conditions in SQL is really transparent
# even if conditional variables are not part of the selection
statement = "SELECT id,v1,v2,v3,v4,v5 FROM mytable
             WHERE this=5
             AND that != 6" 
mydf <- dbGetQuery(con,statement)
# some simple things get really tricky (at least in MySQL), but simple in R
# standard deviation of table rows
dframe$rowsd <- sd(t(dframe))

因此,我认为这是一种很好的做法,并且建议在大多数用例中使用SQL数据库作为数据。我也在研究TSdbi并在关系数据库中保存时间序列,但还不能真正判断它。

以上是关于R中的编码实践:不同风格的优缺点是什么?的主要内容,如果未能解决你的问题,请参考以下文章

人际沟通风格介绍一

PSR-2 编码风格规范

AutoIt 最佳实践/编码风格

来自 Google 的 R 语言编码风格指南

react+eslint+pretty+escode配置(react编码风格统一)

PHP PSR-2 代码风格规范 (中文版)