强大的企业R应用程序的功能

使用R的人都清楚地知道该语言最初是作为交互式工作的工具而设计的。 自然地,对于本领域的人来说,方便基于控制台的逐步应用的方法被证明不适合为最终用户创建应用。 能够在发生错误时立即进行详细诊断,查看所有变量和跟踪,手动执行代码元素(可能部分更改变量)的能力-当R应用程序在企业环境中处于脱机状态时,所有这些功能将不可用。 (我们说R,基本上是指Shiny Web应用程序)。


但是,并非一切都那么糟糕。 R环境(软件包和方法)已经发展到许多非常简单的技巧可以优雅地解决确保用户应用程序的稳定性和可靠性的问题。 下面将描述其中的一些。


它是以前出版物的延续。


任务的难度是什么?


经常使用R的主要任务是多样化的数据处理。 而且,即使是经过全面测试的经过调试的算法,也经过测试全面证明,并得到充分记录,如果在输入中获取弯曲的数据,它很容易崩溃并给出该死的东西。


数据可以从其他信息系统以及从用户输入。 而且,如果在第一种情况下可以要求遵守API并对信息流的稳定性施加非常严格的限制,那么在第二种情况下就无法幸免。 一个人可能会犯错并打错文件,然后写错。 99%的用户在工作中使用Excel,并且更喜欢使用Excel,大量页面和狡猾的格式来关闭系统。 在这种情况下,任务变得更加复杂。 从机器的角度来看,即使是视觉有效的文档也可能看起来完全是废话。 日期分散(非常著名的故事“ Excel的设计师认为1900年是was年,但事实并非如此 )”。 数值存储为文本和排版。 看不见的单元格和隐藏的公式……等等。 原则上,不可能预见所有可能的耙齿-没有足够的想象力。 在弯曲来源的各种联接中,仅使记录增加一倍是值得的。


作为额外的考虑,我们将采取以下措施:


  1. 出色的文档“使用R进行数据清理简介”描述了初步数据准备过程。 对于进一步的步骤,我们选择了验证的两个阶段:技术阶段和逻辑阶段。


    • 技术验证是为了验证数据源的正确性。 结构,类型,定量指标。
    • 逻辑验证可以是多阶段的,可以在计算过程中进行,包括检查某些数据元素或其组合是否符合各种逻辑要求。

  2. 用户界面开发中的基本规则之一是在出现用户错误时形成最完整的诊断。 也就是说,如果用户已经上传了文件,则必须尽可能地检查文件的正确性,并给出所有错误的完整摘要(建议您解释出什么错误),并且在出现第一个问题时不会出现“输入错误”这样的消息值@行528493,位置17”,并要求下载一个修复了此错误的新文件。 这种方法使您可以显着减少迭代次数,以形成正确的源并提高最终结果的质量。

验证技术和方法


让我们从头开始。 有许多用于逻辑验证的软件包。 在我们的实践中,我们决定采用以下方法。


  1. 已经是经典的dplyr 。 在简单的情况下,方便地绘制管道并进行一系列检查和最终结果分析是很方便的。
  2. 用于检查技术上正确的对象是否符合给定规则的validate包。

为了进行技术验证,我们重点关注以下方法:


  1. checkmate软件包具有多种快速功能,可进行各种技术检查。
  2. 明确地进行工作,例外情况包括“高级R.调试,条件处理和防御性编程”“高级R.超越异常处理:条件和重新启动” ,以便一步完成全部验证,并确保应用程序的稳定性。
  3. 使用purr包装器处理异常。 在管道内使用时非常有用。

在分解为功能的代码中,防御性编程的重要元素是检查功能的输入和输出参数。 对于具有动态类型的语言,类型检查必须独立进行。 对于基本类型,checkmate软件包是理想的,尤其是其qtest \ qassert 。 为了检查data.frame停止了以下构造(检查名称和类型)。 合并名称和类型的技巧可以减少检查中的行数。


 ff <- function(dataframe1, dataframe2){ #        calledFun <- deparse(as.list(sys.call())[[1]]) tic("Calculating XYZ") #       (class,   typeof,  Date ) list(dataframe1=c("name :: character", "val :: numeric", "ship_date :: Date"), dataframe2=c("out :: character", "label :: character")) %>% purrr::iwalk(~{ flog.info(glue::glue("Function {calledFun}: checking '{.y}' parameter with expected structure '{collapse(.x, sep=', ')}'")) rlang::eval_bare(rlang::sym(.y)) %>% assertDataFrame(min.rows=1, min.cols=length(.x)) %>% {assertSetEqual(.x, stri_join(names(.), map_chr(., class), sep=" :: "), .var.name=.y)} # {assertSubset(.x, stri_join(names(.), map_chr(., typeof), sep=" :: "))} }) … } 

作为类型检查功能的一部分,您可以根据期望的数据选择适合自己口味的方法。 之所以选择class是因为它将日期作为Date而不是数字(内部表示)。 在“对R.'mode'和'class'和'typeof'的事物类型进行全面调查是不够的”对话框中,将详细讨论确定数据类型的问题。


assertSetEqualassertSubset的原因是清除了匹配的列或足够的最小值。


对于实际任务,如此小的设置完全可以满足大多数需求。


先前的帖子-R作为系统管理员的救生圈

Source: https://habr.com/ru/post/zh-CN413865/


All Articles