AI 技术讲座精选:如何创建 R 包并将其发布在 CRAN / GitHub 上?

前 言

大多数受欢迎的编程语言都有个共同点——他们都是“开源”。开源是一种分散的开发模式,它基于社区参与。社区成员推动这种编程语言的发展,所得成果向所有人开放。

这些开源语言(如 R、C++、,C#、Java、PHP、Python 和 Ruby 等)不断发展和创新的主要原因就是社区参与。在数据科学中,R 就是最受欢迎的语言之一。它受欢迎的主要原因就是数据科学社区 R 语言使用者的不断贡献和支持。他们贡献的包形成了 R 编程语言的基础。

虽然大家在社区内共享了许多关于如何使用 R 解决问题的教程,但是却较少关注开源的发展。就我而言,创建包并将它反馈给社区意义重大。这是我开始回报社区的方法,而且我知道这仅仅是开始。

为了帮助社区进一步发展壮大,我决定写一篇关于如何创建包并将包发布在开源 R 社区的教程。而且,我们将创建一个包并将它贡献给这个开源社区。

目 录

  1. 什么是 R 包?
  2. 我开始创建 R 包的原因是?
  3. 创建包的好处和挑战
  4. 必要条件
  5. 开始创建你的第一个包
  6. 发布包
  7. 向 CRAN 做贡献后的体验
  8. 附加提示
  9. Additional resources

1. 什么是 R 包?

R 包就是一个可重复使用的 R 函数,附带有关如何使用的标准、简要说明文档。有时,包还附带简单的数据。

直至今日,CRAN 上有 10000多个包,大部分包依赖于其他某些 R 包。这表示大部分包是依据其他某些包的功能而创建的。

例如,我创建的一个名为 ensembleR 的包主要依赖 caret 包以及另外一些用于运行例子和创建 vignette 的包:e1071, ipred, knitr, rmarkdown。

通过这张介绍 R 中最常使用的程序包库的信息图,你可以明白 R 包的重要性:

2. 我开始创建 R 包的原因是?

之前在一个 Analytics Vidhya 竞赛中,我试图集成多个模型。我发现 R 中没有一个用于集成的易用开源包。

当时我就决定要借此机会创建一个简单的包,使人们用几行代码就能进行集成(堆叠)。因此,我创建了一个名为 ensembleR 的包,你可以在 CRAN 上找到它。这个包使人们能够在 R 中创建多个模型的集成。欲了解更多关于在 R 中集成的信息,请阅读此内容:https://www.analyticsvidhya.com/blog/2017/02/introduction-to-ensembling-along-with-implementation-in-r/

这个包能够创建数百万个特殊集合(堆叠模型),借助一行代码就可使用所有这些集合给出预测。CRAN 上这个包的版本仍是其发布版本。你可在此找到关于如何使用此包的更多信息:https://cran.r-project.org/web/packages/ensembleR/vignettes/Introduction_to_ensembleR.html

创建 R 包的过程既有趣又富有挑战性,尤其是在首次创建时。我开始学的是创建包的基本结构和流程。

当我编码完包后,我就学会了如何将它发布在 CRAN 上共享给其他社区成员。将包发布在 CRAN 上是最难的一步,因为为了维持 CRAN 上包的质量和稳定性,要对包进行大量的严格测试。

在本文中,我将向你介绍从零开始创建包和将包公开发布在 CRAN 和 GitHub 上的整个流程。

3. 创建 R 包的好处和挑战

创建 R 包的好处有:

  • 实施新的、未被利用的构想。
  • 开发出有用的功能帮助其他程序员。
  • 获得社区认可。
  • 为不断发展的开源社区做贡献。
  • 充实你的履历。

在创建包的过程中还会遇到一些挑战:

  • 不断解决用户可能报告的程序错误以及完成维护工作。
  • 将包提交至像 CRAN 之类的主要仓库时需通过严格的质量测试。
  • 不断进行更新。如果包的维护人员在 CRAN 上的更新活动不活跃,他的包就会被遗弃。

4. 必要条件

在开始编写包之前,你应该熟悉几个必要条件。这些必要条件是:

  • 熟悉基本 R 编程。
  • 基本理解 R 中的功能和循环。
  • 了解 GitHub 的工作原理。
  • 你还须确保你已安装以下几个包:quantmod、xts、roxygen2 和 devtools。

5. 从零开始编写你的第一个包

现在让我们开始创建一个简单的包。在这个包内,我们将创建一个函数,该函数可使用简单的逻辑回归预测给定股票代号在明天的股价变动。十分简单。让我们开始吧!

  1. 通过 File > New Project 路径创建新项目。
  1. 你可选择一个现有目录或者选择创建一个新目录。然后选择项目类型为 R 包。
  1. 之后你再为你的包选择一个合适的名称。我将其命名为 StockPredictoR。在给你的包命名时,你可以使用全部小写(如 predictoR)或者我们在这使用的驼峰式大小写。我建议你在给包命名时不要使用下划线。还有,选择合适的子目录存储该项目。
  1. 这一步将在该目录中创建以下文件。所有代码将存储在 R 文件夹中,而手册和说明文件将储存在主文件夹中。
  1. 在 R studio 打开 DESCRIPTION 文件,编辑内容以最好地匹配对包的描述。然后保存。这就是我在编写这个包时的步骤。
  1. 如果你的包使用其他一些包的功能,你应该再添加另一名为 Imports 的字段。例如这个包,我将使用 quantmod、stats 和 xts 包的功能。须另外添加两个字段:Depends and Suggest。当你使用 Imports and Depends 时,你提醒用户必须安装这些包来确保你创建的包顺利运行。Imports 和 Depends 的唯一区别在于,Depends 加载和附带包函数,而 Import 仅加载包函数。你应几乎始终使用 Imports 来避免任何函数名伪装的问题。Suggests 包含运行例子或生成文档时可能需要的库。这个包最后的描述文件如下所示:
  1. 进入 R 文件夹,你会发现已生成 hello.R script。打开 hello.R script。
  1. 现在你需要 hello.R script 的内容替换为: #' @title #' #' @description #' #' @param #' #' @return #' #' @examples #' #' @export 在这里, ‘title’字段将包含包的名称。 ‘description 字段包含对此包功能的详细描述。 ‘param’字段将包含包内函数所使用的参数。如果有多个参数,你可以使用多个‘param’ 字段分别详细标明每个参数。 在‘return’字段你须标明你的函数将返回的对象。 ‘examples’字段将包含 R 包内函数的示例。 ‘export’字段将包含终端用户要进入的函数名称。你可选择不提及函数名称来隐藏代码中某些你不想公开的函数。
  2. 我将所有这些字段填写为:
  1. 现在来编写真正预测给定股票代号的股价波动的函数。必须在 export 字段下的 hello.R 文件中编写这个‘stock_predict’函数。这是在完成编写此函数后的 hello.R 文件: #' @title Predicts Stock PriceMovement for Given Stock Symbol #' #' @description This package predictswhether the stock price at tommorow's market close would be higher or lowercompared to today's closing place. #' #' @param symbol #' #' @return NULL #' #' @examples stock_predict('AAPL') #' #' @export stock_predict stock_predict<-function(symbol) { #To ignore the warnings during usage options(warn=-1) options("getSymbols.warning4.0"=FALSE) #Importing price data for the givensymbol data<-data.frame(xts::as.xts(get(quantmod::getSymbols(symbol)))) #Assighning the column names colnames(data) <-c("data.Open","data.High","data.Low","data.Close","data.Volume","data.Adjusted") #Creating lag and lead features ofprice column. data <-xts::xts(data,order.by=as.Date(rownames(data))) data <- as.data.frame(merge(data,lm1=stats::lag(data[,'data.Adjusted'],c(-1,1,3,5,10)))) #Extracting features from Date data$Date<-as.Date(rownames(data)) data$Day_of_month<-as.integer(format(as.Date(data$Date),"%d")) data$Month_of_year<-as.integer(format(as.Date(data$Date),"%m")) data$Year<-as.integer(format(as.Date(data$Date),"%y")) data$Day_of_week<-as.factor(weekdays(data$Date)) #Naming variables for reference today <- 'data.Adjusted' tommorow <- 'data.Adjusted.5' #Creating outcome data$up_down <-as.factor(ifelse(data[,tommorow] > data[,today], 1, 0)) #Creating train and test sets train<-data[stats::complete.cases(data),] test<-data[nrow(data),] #Training model model<-stats::glm(up_down~data.Open+data.High+data.Low+data.Close+ data.Volume+data.Adjusted+data.Adjusted.1+ data.Adjusted.2+data.Adjusted.3+data.Adjusted.4+ Day_of_month+Month_of_year+Year+Day_of_week, family=binomial(link='logit'),data=train) #Making Predictions pred<-as.numeric(stats::predict(model,test[,c('data.Open','data.High','data.Low','data.Close','data.Volume','data.Adjusted','data.Adjusted.1','data.Adjusted.2','data.Adjusted.3','data.Adjusted.4','Day_of_month','Month_of_year','Year','Day_of_week')],type= 'response')) #Printing results print("Probability of Stockprice going up tommorow:") print(pred) }
  2. 太棒了!你快编写完你的第一个包了。现在,确保你的测试模块已设置正确以模拟 CRAN 检查,进入 Build > Configure Build Tools 路径。

现在检查 “Generatedocumentation with Roxygen”选项,并在 Check Package space 下放入“–as-cran”来模拟 CRAN 检查和测试包的操作。

  1. 在进行下一步之前,我建议你进入 R 文件夹,将 hello.R 重命名为 StockPredictoR.R。
  2. 打开 name space 文件,确认其是否显示:export(stock_predict)。如果显示的内容不同,你应使其修改得类似如下:
  1. 我们现在已完成编写。你仅需进入 Build > Clean and Rebuild 途径。点击这个将创建包并在当前环境下加载这个包。
  1. 让我们是运行这个指定的例子,观察 Apple 股票明天的收盘价格高于今天收盘价格的几率。
  1. 现在使用我们刚刚创建的包得出谷歌股票明天的收盘价格高于今天收盘价格的几率。

6. 发布包

当你成功创建一个 R 包时,你将乐于将其分享给其他人,以使他们也能用到你包内的函数。在发布包的过程中会用到两大平台:CRAN 和 GitHub.

6.1 在 CRAN 上发布你的包

将包发布在 CRAN 上是较难的一步,因为在成功发布前要对包进行大量的严格测试。除了通过这些测试,你需要给出关于包的运行的详尽描述。这些描述将存储在 vignettes 文件夹中,你可在主项目目录中创建该文件夹。

当你已确认你的包在本地模拟测试中运行良好并且正常记录后,你需要进入Build > Build Source Package 路径创建源码包。

在创建完源码包后,你可提交在此(https://cran.r-project.org/submit.html)提交在 CRAN 上发布此包的申请。

6.2 在 GitHub 上发布你的包

一般而言,在 GitHub 上发布你的包更为容易。在 GitHub 上发布包最简单的方法是创建一个新的仓库,然后将主文件夹(在本例中为 StockPredictor)的内容上传至该仓库。我在此完成了同一步骤。

现在,任何人都可以使用以下命令安装并使用这个包:

devtools::install_github(“sauravkaushik8/SamplePackage”)

7. 向 CRAN 做贡献后的体验

我无法表达出将包发布在 CRAN 后的感受。这个包的可用性对外部世界可能无足轻重,但是这无关紧要。对于我而言,我知道我已开始使我最喜爱的工具变得更强。

在完成在 CRAN 上的发表后,我意识到这次发表为我带来了以下好处:

  • 我开始深深感激在 CRAN 上发布包之前进行的质量检查。
  • 创建这个包并将它发布在 CRAN 上帮助我进一步认识了 R 社区,尤其是获得了那些使用我包的人的认可。
  • 这个经历充实了我的履历,如果你也在想办法充实你的履历,我极力推荐你对开源做些贡献。
  • 这个包帮助我在几项数据科学竞赛中表现优异,同时我希望它能帮助到其他社区成员。

8. 附加提示

我希望你在创建你的第一个包时会发现这篇文章有所帮助。根据我的经验,我希望给你提出一些有用建议:

  • 如果你想创建你自己的 R 包,你应确保自己确认以下三点:
  • 它能给全球 R 社区带来什么价值?
  • 其他的包是否和你的包拥有一样的功能?
  • 即使存在这样一个包,那么我的仍能为社区贡献一个新功能或者使相同功能更加容易。
  • 在你创建自己的包之前,我建议你从上述几步开始。当你熟练掌握流程后,你就可以轻松在编写函数方面达到较高水平,并且能够从 GitHub 上发布的多种包中学习代码。
  • 如果你的包在 CRAN 上成功发布,之后你需要确保不断更新你的包,以修正某些程序错误和/或添加新功能。如果在特定时段内你未对包进行更新,CRAN 会遗弃你的包。

9. 附加资源

  • R Packages by Hadley Wickham http://r-pkgs.had.co.nz/
  • Creating R packages by CRAN https://cran.r-project.org/doc/contrib/Leisch-CreatingPackages.pdf
  • Writing R extensions https://cran.r-project.org/doc/manuals/r-release/R-exts.html

尾 注

我相信,本文将帮助你理解从零开始创建 R 包的流程。通过学习此教程,你现在将已获得创建 R 包的亲身体验。这些包构成了 R 编程语言的基础,我非常希望你能对 R 语言的发展做出自己的贡献。

本文作者 Saurav Kaushik 是数据科学爱好者,还有一年他就从新德里 MAIT 毕业了,喜欢使用机器学习和分析来解决复杂的数据问题。

本文由 AI100 编译,转载需得到本公众号同意。


编译:AI100

原文链接:https://www.analyticsvidhya.com/blog/2017/03/create-packages-r-cran-github/


原文发布于微信公众号 - AI科技大本营(rgznai100)

原文发表时间:2017-03-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序员互动联盟

【专业技术第一讲】进程的一生

学习编程,进程跳不过去,好多初学者可以向背教科书一样说出进程和线程的区别,但是很少能真正的理解进程整个运行过程。搞清楚进程的运行机制,进程运行的各个阶段也并不是...

3696
来自专栏陈帅的专栏

网络延迟与带宽性能专项测试

代理、VPN作为两种古老的数通网络安全解决方案,在当今移动互联网时代,伴随着游戏网络加速、WiFi安全性等用户硬性需求,再次焕发青春。

1.9K0
来自专栏WeTest质量开放平台团队的专栏

UPA性能分析工具使用详解

自从WeTest宣布与Unity官方共同推出Unity性能分析工具UPA(Unity Performance Analysis)以来(Hi,我们和Unity合作...

1262
来自专栏AI研习社

人工智能开始玩《星际争霸2》 我们对它的研究环境进行了测试

本文原作者洪水宋,杜克,原文载于作者的知乎专栏 - 智能单元。 8月10号,DeepMind联合暴雪发布了星际争霸2人工智能研究环境SC2LE,从而使人工智能的...

4035
来自专栏工科狗和生物喵

《实时软件控制设计》MATLAB-PIL测试报告基于Qemu Cortex-M 3的环境

正文之前 首先,跟助教说声抱歉,我们组因为一些因素没有按时完成PIL的测试,还要申请延期。另外也感谢助教的催促,让我们能够在今天下午就完成PIL测试,也算是为本...

4068
来自专栏数据和云

Oracle Database 18c 的10大新特性一览

在 2017 Oracle OpenWorld大会上,关于 Oracle 18c 的一系列新特性已经被披露出来,借助分散在各个会场的公开分享主题和内容、OOW提...

55911
来自专栏恰同学骚年

操作系统核心原理-6.外存管理(上)磁盘基础

  计算机是处理数据的机器,而数据就需要有地方存放。在计算机中,可供数据存放的地方并不太多,除了内存之外,最主要的存储数据的媒介就是磁盘。对于大多数计算机领域的...

1541
来自专栏java思维导图

思维导图学 Maven

作者:被称为L的男人 原文链接地址:http://www.jianshu.com/p/ccdcb60ef7d3 说明 一直在用 Mindjet MindMana...

3815
来自专栏互联网高可用架构

谷歌大数据的三驾马车资料下载

2894
来自专栏GopherCoder

专栏:006:实战爬取博客

1702

扫码关注云+社区

领取腾讯云代金券