R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大。
R语言作为统计学一门语言,一直在小众领域闪耀着光芒。直到大数据的爆发,R语言变成了一门炙手可热的数据分析的利器。随着越来越多的工程背景的人的加入,R语言的社区在迅速扩大成长。现在已不仅仅是统计领域,教育,银行,电商,互联网….都在使用R语言。
要成为有理想的极客,我们不能停留在语法上,要掌握牢固的数学,概率,统计知识,同时还要有创新精神,把R语言发挥到各个领域。让我们一起动起来吧,开始R的极客理想。
关于作者:
- 张丹(Conan), 程序员Java,R,PHP,Javascript
- weibo:@Conan_Z
- blog: http://blog.fens.me
- email: bsspirit@gmail.com
转载请注明出处:
http://blog.fens.me/r-package-faster/
前言
在 开发自己的R包sayHello 一文中,我们看到了如何从底层,按照R语言的标准构建一个R语言的扩展包。但实施过程确实复杂,会让很多的统计学工作者望而却步。如果能有一种比较简单方式,简化开发过程,那该多好啊!
我们是幸运的,Hadley Wickham(ggplot2,plyr的作者)已经帮我们梳理出了一套开发流程。站在巨人的肩膀上,看得更高,走得更远。
目录
- 开发流程介绍
- 编写功能代码
- 调试程序
- 单元测试
- 撰写文档
- 程序打包
- 程序发布
1. 开发流程介绍
站在巨人的肩膀,开发R包我们有3个武器:devtools, roxygen2, testthat
- devtools:让开发变得简单,各种开发小工具的合集,非常实用。
- roxygen2:通过注释的方式,生成文档,远离Latex的烦恼。
- testthat:单元测试,让R包稳定、健壮,减少升级的痛苦。
标准化的开发流程:
- 编写功能代码
- 调试程序
- 单元测试
- 撰写文档
- 程序打包
2. 编写功能代码
1). 安装程序包:devtools, roxygen2, testthat
#依赖库
~ sudo apt-get install libcurl4-openssl-dev
~ sudo apt-get install libxml2-dev
#请使用root权限启动R
~ sudo R
> install.packages("devtools")
> install.packages("roxygen2")
> install.packages("testthat")
> library(devtools)
> library(roxygen2)
> library(testthat)
#查看
> search()
[1] ".GlobalEnv" "package:testthat" "package:roxygen2"
[4] "package:digest" "package:stats" "package:graphics"
[7] "package:grDevices" "package:utils" "package:datasets"
[10] "package:methods" "Autoloads" "package:base"
构建工程chinaWeather
创建骨架,代替package.skeleton()
> setwd("/home/conan/R")
> create("/home/conan/R/chinaWeather")
Creating package chinaWeather in /home/conan/R
No DESCRIPTION found. Creating default:
Package: chinaWeather
Title:
Description:
Version: 0.1
Authors@R: # getOptions('devtools.desc.author')
Depends: R (>= 3.0.1)
License: # getOptions('devtools.desc.license')
LazyData: true
> setwd("/home/conan/R/chinaWeather")
> dir()
[1] "DESCRIPTION" "man" "R"
编辑DESCRIPTION文件
~ vi /home/conan/R/chinaWeather/DESCRIPTION
Package: chinaWeather
Type: Package
Title: a visualized package for china Weather
Description: a visualized package for china Weather
Author: Dan Zhang
Maintainer: Dan Zhang
Version: 0.1
Depends: R (>= 3.0.1)
License: GPL-2
LazyData: true
Date: 2013-08-05
增加函数文件chinaWeather.R
~ vi /home/conan/R/chinaWeather/R/chinaWeather.R
#define a filename from current date
filename<-function(date=Sys.time()){
paste(format(date, "%Y%m%d"),".csv",sep="")
}
3. 调试程序
加载程序包到R中
> load_all("/home/conan/R/chinaWeather")
Loading chinaWeather
> filename
function(date=Sys.time()){
paste(format(date, "%Y%m%d"),".csv",sep="")
}
> filename()
[1] "20130805.csv"
> day<-as.Date("20110701",format="%Y%m%d")
> filename(day)
[1] "20110701.csv"
4. 单元测试
编写单元测试代码
~ mkdir /home/conan/R/chinaWeather/inst/tests
~ vi /home/conan/R/chinaWeather/inst/tests/test.chinaWeather.R
library(testthat)
context("filename: current of date")
test_that("filename is current of date", {
daystr<-paste(format(Sys.Date(), "%Y%m%d"),".csv",sep="")
expect_that(filename(), equals(daystr))
day<-as.Date("20110701",format="%Y%m%d")
expect_that(filename(day), equals("20110701.csv"))
})
运行单元测试
#单个文件的单元测试
> source("/home/conan/R/chinaWeather/inst/tests/test.chinaWeather.R")
> test_file("/home/conan/R/chinaWeather/inst/tests/test.chinaWeather.R")
filename: current of date : ..
#对目录下所有文件的单元测试
> test_dir("/home/conan/R/chinaWeather/inst/tests/",reporter = "summary")
filename: current of date : ..
#自动单元测试
> src<-"/home/conan/R/chinaWeather/R/"
> test<-"/home/conan/R/chinaWeather/inst/tests/"
> auto_test(src,test)
filename: current of date : ..
#对package执行测试
> test("/home/conan/R/chinaWeather")
Testing chinaWeather
Loading chinaWeather
filename: current of date : ..
完成单元测试!下面开始撰写文档。
5. 撰写文档
这里撰写文档,使用源代码注释的方式,然后生成latex,再生成doc。比起原始的直接写latex要容易的多。
打开源代码文件:chinaWeather.R
~ vi /home/conan/R/chinaWeather/R/chinaWeather.R
#' Define a filename from current date.
#'
#' @param date input a date type
#' @return character a file name
#' @keywords filename
#' @export
#' @examples
#' filename()
#' filename(as.Date("20110701",format="%Y%m%d"))
filename<-function(date=Sys.time()){
paste(format(date, "%Y%m%d"),".csv",sep="")
}
生成latex文档
> library(roxygen2)
Loading required package: digest
> roxygenize("/home/conan/R/chinaWeather")
Updating collate directive in /home/conan/R/chinaWeather/DESCRIPTION
Updating namespace directives
Writing chinaWeather.Rd
Writing filename.Rd
查看生成的latex文件
~ cat /home/conan/R/chinaWeather/man/filename.Rd
\name{filename}
\alias{filename}
\title{Define a filename from current date.}
\usage{
filename(date = Sys.time())
}
\arguments{
\item{date}{input a date type}
}
\value{
character a file name
}
\description{
Define a filename from current date.
}
\examples{
filename()
filename(as.Date("20110701",format="\%Y\%m\%d"))
}
\keyword{filename}
6. 程序打包
详细的打包解释,请参考:开发自己的R包sayHello
对上面程序过程,更简化操作可以用如下3条命令
> load_all("/home/conan/R/chinaWeather")
> test("/home/conan/R/chinaWeather")
> document("/home/conan/R/chinaWeather")
程序检查
> check("/home/conan/R/chinaWeather")
Updating chinaWeather documentation
Loading chinaWeather
'/usr/lib/R/bin/R' --vanilla CMD build '/home/conan/R/chinaWeather' \
--no-manual --no-resave-data
* checking for file '/home/conan/R/chinaWeather/DESCRIPTION' ... OK
* preparing 'chinaWeather':
* checking DESCRIPTION meta-information ... OK
* checking for LF line-endings in source and make files
* checking for empty or unneeded directories
* building 'chinaWeather_0.1.tar.gz'
'/usr/lib/R/bin/R' --vanilla CMD check \
'/tmp/RtmpM5NdJp/chinaWeather_0.1.tar.gz' --timings
* using log directory '/tmp/RtmpM5NdJp/chinaWeather.Rcheck'
* using R version 3.0.1 (2013-05-16)
* using platform: x86_64-pc-linux-gnu (64-bit)
* using session charset: ASCII
* checking for file 'chinaWeather/DESCRIPTION' ... OK
* checking extension type ... Package
* this is package 'chinaWeather' version '0.1'
* checking package namespace information ... OK
* checking package dependencies ... OK
* checking if this is a source package ... OK
* checking if there is a namespace ... OK
* checking for executable files ... OK
* checking for hidden files and directories ... OK
* checking for portable file names ... OK
* checking for sufficient/correct file permissions ... OK
* checking whether package 'chinaWeather' can be installed ... OK
* checking installed package size ... OK
* checking package directory ... OK
* checking DESCRIPTION meta-information ... OK
* checking top-level files ... OK
* checking for left-over files ... OK
* checking index information ... OK
* checking package subdirectories ... OK
* checking R files for non-ASCII characters ... OK
* checking R files for syntax errors ... OK
* checking whether the package can be loaded ... OK
* checking whether the package can be loaded with stated dependencies ... OK
* checking whether the package can be unloaded cleanly ... OK
* checking whether the namespace can be loaded with stated dependencies ... OK
* checking whether the namespace can be unloaded cleanly ... OK
* checking loading without being on the library search path ... OK
* checking for unstated dependencies in R code ... OK
* checking S3 generic/method consistency ... OK
* checking replacement functions ... OK
* checking foreign function calls ... OK
* checking R code for possible problems ... OK
* checking Rd files ... OK
* checking Rd metadata ... OK
* checking Rd cross-references ... OK
* checking for missing documentation entries ... OK
* checking for code/documentation mismatches ... OK
* checking Rd \usage sections ... OK
* checking Rd contents ... OK
* checking for unstated dependencies in examples ... OK
* checking examples ... OK
* checking PDF version of manual ... OK
Checking chinaWeather with devtools
Checking for any extra files in built .tar.gz file... OK
查检通过.
注:请安装
sudo apt-get install texlive-full
7. 程序发布
我们把写的程序发布到github上面,然后通过devtools,我可以方便的把程序从github下载安装。
在github创建一个新的资源库:chinaWeather
https://github.com/bsspirit/chinaWeather
提交本地代码到github
~ cd /home/conan/R/chinaWeather
~ git init
~ git add .
~ git commit -m 'init commit'
~ git remote add origin https://github.com/bsspirit/chinaWeather
~ git push -u origin master
To https://github.com/bsspirit/chinaWeather
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
通过devtools下载,并安装代码。
现在我的chinaWeather包,已经在github上面发布了,如果其他的同学想使用可以下面命令安装。
> library(devtools)
> install_github("chinaWeather","bsspirit")
Installing github repo(s) chinaWeather/master from bsspirit
Downloading chinaWeather.zip from https://github.com/bsspirit/chinaWeather/archive/master.zip
Installing package from /tmp/RtmpSaXYcA/chinaWeather.zip
Installing chinaWeather
'/usr/lib/R/bin/R' --vanilla CMD INSTALL \
'/tmp/RtmpSaXYcA/chinaWeather-master' \
--library='/home/conan/R/x86_64-pc-linux-gnu-library/3.0' \
--with-keep.source --install-tests
* installing *source* package 'chinaWeather' ...
** R
** inst
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
* DONE (chinaWeather)
#测试包
> library(chinaWeather)
> filename()
[1] "20130805.csv"
#查看文档
> ?filename
filename package:chinaWeather R Documentation
Define a filename from current date.
Description:
Define a filename from current date.
Usage:
filename(date = Sys.time())
Arguments:
date: input a date type
Value:
character a file name
Examples:
filename()
filename(as.Date("20110701",format="%Y%m%d"))
我们完成了,开发R包的全部流程。依赖于devtools, roxygen2, testthat三个包,真是事半功倍,比起完全手动操作提高效率了很多!!
希望更多的朋友,可以站在巨人的肩膀前行,创造让人惊叹的成果来!!
您好,有些问题请教:1,为什么要传到github,然后又下载下来?2,除了这个流程还有没有更详细的资料呢?现在是知道怎么做,但是不知道为什么要这样做啊!谢谢!邮箱:xiaofeng.0007@gmail.com
1. github可以方便的管理代码.
2. 对于开发者来说,你要想发布自己的包,要放到CRAN上面,这是个慢长和复杂的过程。对于R的用户来说,可以直接从github下载你的包。简化了发布过程,你不觉得很方便么。
3. 这个流程是目前我知道的最方便的流程了。如果提交到CRAN,代码规范,包结构, 都去google吧,都有答案的。
谢谢,在linux上做了一遍,最后还是遇到个问题:为什么library后用不了?但是查看?filename却有结果呢?百思不得其解,check都没问题的,难道是build时有问题?
你下载的是最新的版本吗?
你这个问题,一般是NAMESPACE文件中,没有写export(filename)造成的。
参考项目地址
https://github.com/bsspirit/chinaWeather
谢谢,一针见血啊,已经可以运行!不过又有新的问题了,再次麻烦你了:1,什么时候用S3method()?是因为默认的methods不行?对于methods概念比较模糊。2,useDynLib作用是载入共享对象?为什么么不可以用import()?3,最开始构建工程的时候为什么么用create(),这个相比于package.skeleton()好像没有什么优势啊?4,关于Hadley Wickham打包的文章一直没找到,能发个链接?
1. S3和S4,建议自己构造的对象都用S4的。S3是遗留的问题。目前,这方面的介绍文章很少。
有两个官方文档需要自己阅读:
Writing R Extensions
Building Packages in R
2. useDynLib,主要用于加载其他语言的动态库。比如像rJava需要加载jri.dll(jri.so)
3. devtools是为了简化R包开发流程的工具包。如果你用这个包,最好按照他规定的流程去开发。他规定的这个流程,我们没必要打破,再画轮造车。
4. package.skeleton()仅仅是生成几个文件,没有对开发流程做任何的标准化。自己也可以创建这几个文件。完全没什么用。
5. Hadley Wickham的文章,都出自devtools这个项目,我写的博客,大部分是基于自己的体会,没有任何翻译。
https://github.com/hadley/devtools
谢谢大神的耐心指导!真心感谢,谢谢!!希望在CRAN上能早日看到您的包!
🙂
没找到转载的按钮啊?怎么转载你这篇文章?
没有转载按钮,如果转载就是复制+粘贴。
嗯,好的,你的文章写得非常好,希望能够转载,不过复制+粘贴后排版有点问题!
你好,如果R包依赖的不是其它R包,而是网络上的软件怎么办?是不是要configuration,还是只要在SystemRequirements说明就可以呢?
这个情况,我不太清楚。
你可参考一下谢益挥的animation包的实现写法。
animation::saveGIF需要依赖于ImageMagick或者GraphicsMagick。
谢大的包需要用户自行安装。我想自动安装的,昨天找到了个包也可以实现类似的功能。但是尝试了很久都不知道怎么自动加载那个依赖包,Depends和import都不行啊!
自动安装,估计R语言很难实现吧,是不是对R语言要求太高了。
这个应该是有的,要不然开发出来的R包有依赖关系的话,不就不能用了?我以前加载的包,可没有手动去下载那依赖包的!
发现原因了,之前是我这边有点问题。只要在Depends中说明,install后library()就会自动加载依赖包。。
依赖R包,在Depends配置好就行了。
我以为你是想自动安装第三方软件呢,”网络上的软件”!
之前在51cto上看到一篇报道:“2014最值得学习的语言—必须是R”。应该是您的杰作吧,写得很精辟!!让我对R充满信心啊!
过奖了,学好R是很有用的。
又来麻烦下你了,请部下:打包后有什么好方法进行调试吗?我是重新加载原代码来调试的,比较麻烦。可不可加载R包后,也可以进去调试呢?
似乎没有什么其他方法,只能通过源代码的方式调试。
好的,谢谢!晚安……
在linux下怎么打包成zip格式?
R CMD INSTALL –build test.tar.gz和R CMD build –binary test都不行啊???
我不记得是否支持打包到zip,通用的是tar.gz;等我有时间时,再查一下。
好的,谢了!
[…] R包开发编程:开发自己的R包sayHello, 在巨人的肩膀前行 催化R包开发 […]
[…] devtools的详细安装说明和使用,请参考文章:在巨人的肩膀前行 催化R包开发 […]
[…] R语言性能可视化lineprof | 粉丝日志 on 在巨人的肩膀前行 催化R包开发 […]
你好。如果要把用R做的模型打包怎么办呢?我现在是把模型保存成RData格式的文件,每次load一下这个文件,如果打包该怎么处理呢?谢谢
打包时,把数据文件变成 *.rda 的格式,用户library包时,会自动装载这些数据。
参考这篇文章中的实现
http://blog.fens.me/r-package-chinaweather/
[…] 如果想要安装开发版本,可以使用devtools来进行安装,devtools的介绍请参考文章:在巨人的肩膀前行 催化R包开发 […]