• Posts tagged "CRAN"

Blog Archives

miniCRAN离线安装R的依赖库

R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大。

R语言作为统计学一门语言,一直在小众领域闪耀着光芒。直到大数据的爆发,R语言变成了一门炙手可热的数据分析的利器。随着越来越多的工程背景的人的加入,R语言的社区在迅速扩大成长。现在已不仅仅是统计领域,教育,银行,电商,互联网….都在使用R语言。

要成为有理想的极客,我们不能停留在语法上,要掌握牢固的数学,概率,统计知识,同时还要有创新精神,把R语言发挥到各个领域。让我们一起动起来吧,开始R的极客理想。

关于作者:

  • 张丹(Conan), 程序员Java,R,Nodejs
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/r-install-offline

前言

最近经常去有网络隔离的机构,每次安装R语言的环境都是特别痛苦的经历。物理网络完全隔绝,不能通过互联网进行R语言的安装,只能预先下载所有软件,再进行安装。

对于有众多依赖的库,安装过程就变得很复杂了。无意中,发现了一个可以找到每个包的依赖包的库miniCRAN,让这个安装包过程,变得自动化一点。

目录

  1. 离线安装R的依赖库的过程
  2. miniCRAN介绍
  3. 5分钟上手
  4. miniCRAN包的函数介绍
  5. miniCRAN的使用方法

1. 离线安装R的依赖库的过程

对于物理网络完全被隔绝的情况,我们不能通过互联网进行R语言的安装,只能预先下载所有软件,再进行安装。

操作过程包括以下几步操作:

  1. 在有网的环境中,下载系统软件,比例 windows环境要下载对应的.net framework。
  2. 在有网的环境中,下载R语言软件。
  3. 在有网的环境中,下载第三方软件包,比如xts包。
  4. 在有网的环境中,用miniCRAN找到xts包,所有的依赖包。
  5. 在有网的环境中,下载所有的依赖包。
  6. 通过U盘或者其他的方式,复制到无网的环境中。
  7. 分别安装系统软件,R语言软件,依赖包,软件包。
  8. 重复以上过程,直到把软件都安装好。

以上操作过程中,最复杂的操作就在于找到所有的依赖包。

2. miniCRAN介绍

miniCRAN包,主要用于发现软件包的依赖关系。R语言中,每个包一般都其所依赖的扩展包,对于企业或者机构内网来说,由于防火墙或者基于安全的管理规则,不允许从互联网下载安装。那么,用户就需要从CRAN中,下载对应的软件包,一个一个安装。通过miniCRAN包,可以递归读取这些软件包的依赖关系,然后就可以下载这些依赖包了。

开发环境所使用的系统环境

  • Win10 64bit
  • R: 3.2.3 x86_64-w64-mingw32/x64 b4bit

miniCRAN包的安装比较简单,直接用install.pacakges()函数就行。


> install.packages("miniCRAN")
         binary source needs_compilation
miniCRAN  0.2.7 0.2.11             FALSE

installing the source package 'miniCRAN'

URLhttp://mirrors.tuna.tsinghua.edu.cn/CRAN/src/contrib/miniCRAN_0.2.11.tar.gz'
Content type 'application/octet-stream' length 4114313 bytes (3.9 MB)
downloaded 3.9 MB

* installing *source* package 'miniCRAN' ...
** 'miniCRAN'MD5
** R
** data
*** moving datasets to lazyload DB
** inst
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** installing vignettes
** testing if installed package can be loaded
*** arch - i386
*** arch - x64
* DONE (miniCRAN)

3. 5分钟上手

我们先做一个小的测试,分析一下chron包如果本地安装,都需要使用哪些包,会有哪些依赖关系。我们打开CRAN上面的,官方项目网页,https://cran.r-project.org/web/packages/xts/

xts唯一强依赖的包(depends)是zoo,引用R系统包methods,同时建议安装timeSeries, timeDate, tSeries, chron, fts, tis, RUnit包。

接下来,我们通过miniCRAN找到xts包的依赖关系。


> library(miniCRAN)
> tags <- "xts"
> pkgDep(tags, availPkgs = cranJuly2014)
 [1] "xts"          "zoo"          "lattice"     
 [4] "timeDate"     "quadprog"     "Hmisc"       
 [7] "survival"     "Formula"      "latticeExtra"
[10] "cluster"      "RColorBrewer" "BH"          
[13] "timeSeries"   "tseries"      "its"         
[16] "chron"        "fts"          "tis"    

画出依赖关系图。


> dg <- makeDepGraph(tags, enhances = TRUE, availPkgs = cranJuly2014)
> plot(dg, legendPosition = c(-1, 1), vertex.size = 20)

从图中,可以把整个的依赖关系看得很清楚了。

4. miniCRAN包的函数介绍

整个miniCRAN包大概有20多个函数,其中最有用的函数就是pkgDeg()和pkgAvail()。

4.1 pkgDeg()函数

pkgDeg()函数,主要对Depends,Imports和LinkLibrary执行递归检索,对Suggests执行非递归检索。


pkgDep(pkg, availPkgs, repos = getOption("repos"), type = "source",
  depends = TRUE, suggests = TRUE, enhances = FALSE,
  includeBasePkgs = FALSE, Rversion = R.version, quiet = FALSE, ...)

参数解读:

  • pkg: 包名
  • availPkgs: 所有包列表
  • repos: CRAN软件源
  • type: 下载类型,源代或二进制
  • depends: 依赖关系,包括Depends, Imports, LinkingTo
  • suggests: 建议关系
  • enhances: 增强关系
  • includeBasePkgs: 是否包括R base包
  • Rversion: R版本

4.2 pkgAvail()函数

pkgAvail()函数,是对 available.packages()函数的一个封装。如果提供了参数路径,那么该函数将尝试从本地存储库读取数据,否则尝试从repos url的CRAN镜像读取数据。


pkgAvail(repos = getOption("repos"), type = "source",
  Rversion = R.version, quiet = FALSE)

参数解读:

  • repos: CRAN软件源
  • type: 下载类型,源代或二进制
  • Rversion: R版本

这个函数在我目前测试的版本中,有一些bug,可以用available.packages()函数来解决。

5. miniCRAN的使用方法

接下来,我们详细地介绍一下,找到某包的依赖的使用方法。

5.1 定义软件源

如果我们用install.packages()函数安装过软件包,在你的本地配置中,会有当前的软件源,那么我们可以用getOption()函数,来获得本地的软件源。


> repos<-getOption("repos")
> repos
                                        CRAN 
"https://mirrors.tuna.tsinghua.edu.cn/CRAN/" 
                                   CRANextra 
        "http://www.stats.ox.ac.uk/pub/RWin" 
attr(,"RStudio")
[1] TRUE

我当前环境中配置的CRAN软件源为 https://mirrors.tuna.tsinghua.edu.cn/CRAN/ 。

5.2 获得软件源的包列表

通过软件源URL,我们需要获得软件源的包列表。


> curl<-contrib.url(repos)
> aps<-available.packages(curl)

> head(aps)
            Package       Version Priority Depends                                               Imports                                  LinkingTo
A3          "A3"          "1.0.0" NA       "R (>= 2.15.0), xtable, pbapply"                      NA                                       NA       
abbyyR      "abbyyR"      "0.5.1" NA       "R (>= 3.2.0)"                                        "httr, XML, curl, readr, plyr, progress" NA       
abc         "abc"         "2.1"   NA       "R (>= 2.10), abc.data, nnet, quantreg, MASS, locfit" NA                                       NA       
ABCanalysis "ABCanalysis" "1.2.1" NA       "R (>= 2.10)"                                         "plotrix"                                NA       
abc.data    "abc.data"    "1.0"   NA       "R (>= 2.10)"                                         NA                                       NA       
abcdeFBA    "abcdeFBA"    "0.4"   NA       "Rglpk,rgl,corrplot,lattice,R (>= 2.10)"              NA                                       NA       
            Suggests                               Enhances License              License_is_FOSS License_restricts_use OS_type Archs MD5sum
A3          "randomForest, e1071"                  NA       "GPL (>= 2)"         NA              NA                    NA      NA    NA    
abbyyR      "testthat, rmarkdown, knitr (>= 1.11)" NA       "MIT + file LICENSE" NA              NA                    NA      NA    NA    
abc         NA                                     NA       "GPL (>= 3)"         NA              NA                    NA      NA    NA    
ABCanalysis NA                                     NA       "GPL-3"              NA              NA                    NA      NA    NA    
abc.data    NA                                     NA       "GPL (>= 3)"         NA              NA                    NA      NA    NA    
abcdeFBA    "LIM,sybil"                            NA       "GPL-2"              NA              NA                    NA      NA    NA    
            NeedsCompilation File Repository                                             
A3          "no"             NA   "https://mirrors.tuna.tsinghua.edu.cn/CRAN/src/contrib"
abbyyR      "no"             NA   "https://mirrors.tuna.tsinghua.edu.cn/CRAN/src/contrib"
abc         "no"             NA   "https://mirrors.tuna.tsinghua.edu.cn/CRAN/src/contrib"
ABCanalysis "no"             NA   "https://mirrors.tuna.tsinghua.edu.cn/CRAN/src/contrib"
abc.data    "no"             NA   "https://mirrors.tuna.tsinghua.edu.cn/CRAN/src/contrib"
abcdeFBA    "no"             NA   "https://mirrors.tuna.tsinghua.edu.cn/CRAN/src/contrib"

取出xts包所对应的配置信息。


> aps[which(row.names(aps)=='xts'),]
                                                Package                                                 Version 
                                                  "xts"                                                "0.10-2" 
                                               Priority                                                 Depends 
                                                     NA                                       "zoo (>= 1.7-12)" 
                                                Imports                                               LinkingTo 
                                              "methods"                                                   "zoo" 
                                               Suggests                                                Enhances 
"timeSeries, timeDate, tseries, chron, fts, tis, RUnit"                                                      NA 
                                                License                                         License_is_FOSS 
                                           "GPL (>= 2)"                                                      NA 
                                  License_restricts_use                                                 OS_type 
                                                     NA                                                      NA 
                                                  Archs                                                  MD5sum 
                                                     NA                                                      NA 
                                       NeedsCompilation                                                    File 
                                                  "yes"                                                      NA 
                                             Repository 
"https://mirrors.tuna.tsinghua.edu.cn/CRAN/src/contrib" 

5.3 找到依赖包的列表

从所有的软件包中,找到对应软件依赖包的列表。


# 要找到xts和TTR软件的依赖包
> libs<-c("xts","TTR")
> pkgList<-pkgDep(pkg=libs,availPkgs=aps,repos=repos)
> pkgList
 [1] "xts"        "TTR"        "zoo"        "lattice"    "curl"       "timeDate"   "quadprog"  
 [8] "quantmod"   "BH"         "timeSeries" "tseries"    "chron"      "fts"        "tis"       
[15] "RUnit"     

5.4 下载所有依赖包

运行下载函数,下载所有的依赖包。


> dp<-download.packages(pkgList,"D:/workspace/R/miniCRAN/pgk",type=getOption("pkgType"))
> dp
      [,1]         [,2]                                                    
 [1,] "xts"        "D:/workspace/R/miniCRAN/pgk/xts_0.10-2.tar.gz"         
 [2,] "TTR"        "D:/workspace/R/miniCRAN/pgk/TTR_0.23-3.tar.gz"         
 [3,] "zoo"        "D:/workspace/R/miniCRAN/pgk/zoo_1.8-1.tar.gz"          
 [4,] "lattice"    "D:/workspace/R/miniCRAN/pgk/lattice_0.20-35.tar.gz"    
 [5,] "curl"       "D:/workspace/R/miniCRAN/pgk/curl_3.2.tar.gz"           
 [6,] "timeDate"   "D:/workspace/R/miniCRAN/pgk/timeDate_3043.102.tar.gz"  
 [7,] "quadprog"   "D:/workspace/R/miniCRAN/pgk/quadprog_1.5-5.tar.gz"     
 [8,] "quantmod"   "D:/workspace/R/miniCRAN/pgk/quantmod_0.4-13.tar.gz"    
 [9,] "BH"         "D:/workspace/R/miniCRAN/pgk/BH_1.66.0-1.tar.gz"        
[10,] "timeSeries" "D:/workspace/R/miniCRAN/pgk/timeSeries_3042.102.tar.gz"
[11,] "tseries"    "D:/workspace/R/miniCRAN/pgk/tseries_0.10-44.tar.gz"    
[12,] "chron"      "D:/workspace/R/miniCRAN/pgk/chron_2.3-52.tar.gz"       
[13,] "fts"        "D:/workspace/R/miniCRAN/pgk/fts_0.9.9.tar.gz"          
[14,] "tis"        "D:/workspace/R/miniCRAN/pgk/tis_1.34.tar.gz"           
[15,] "RUnit"      "D:/workspace/R/miniCRAN/pgk/RUnit_0.4.31.tar.gz"       

本地目录查看下载的文件。


> dir("D:/workspace/R/miniCRAN/pgk")
 [1] "BH_1.66.0-1.tar.gz"         "chron_2.3-52.tar.gz"        "curl_3.2.tar.gz"           
 [4] "fts_0.9.9.tar.gz"           "lattice_0.20-35.tar.gz"     "quadprog_1.5-5.tar.gz"     
 [7] "quantmod_0.4-13.tar.gz"     "RUnit_0.4.31.tar.gz"        "timeDate_3043.102.tar.gz"  
[10] "timeSeries_3042.102.tar.gz" "tis_1.34.tar.gz"            "tseries_0.10-44.tar.gz"    
[13] "TTR_0.23-3.tar.gz"          "xts_0.10-2.tar.gz"          "zoo_1.8-1.tar.gz"  

5.5 安装软件包

用R语言的函数,进行本地安装。


> install.packages(dp[,2], repos = NULL, type="source")

另外,我们也可以用命令行,进行安装。


> R CMD INSTALL D:\workspace\R\miniCRAN\pgk\zoo_1.8-1.tar.gz

通过使用miniCRAN包,就让我们找到依赖包的这事情,变得简单多了。再通过批量的离线下载,和批量的安装,就可以让我们的操作更有效率。不然,一个一包的安装,真是要把人给逼疯了!

虽然本文讲了通用的方法,但对于有一些包安装过程中,还需要从网上再下载其他的包,还需要具体问题具体分析,手动安装依赖包的过程,确实是无比复杂的。

转载请注明出处:
http://blog.fens.me/r-install-offline

打赏作者

发布gridgame游戏包

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-game-gridgame/

gridgame

前言

为了能发布自己的游戏包,我们已经储备了很多的基础知识,包括 R语言面向对象编程、R包开发编程、R语言游戏编程 等,最后一步就到综合运用的时候了。按CRAN的R包发布的要求,把所有代码和文档串起来,就是我们要发布的gridgame游戏包。

目录

  1. 知识储备
  2. gridgame包开发
  3. gridgame包发布

1. 知识储备

在综合运用所有知识前,先回顾一下,我们都需要掌握哪些知识,1)R语言编程的基础是必需,2)游戏的算法主要是对矩阵的操作,线性代数最好也要掌握,3)游戏操作需要有界面,虽然不需要太好看,但我们也要有能力用代码画出游戏界面来,4)游戏的框架封装,对于相同类型的游戏,如果第二款游戏能延续第一款游戏的结构,不仅能简化开发节约时间,还能降低游戏技术门槛,就需要用面向对象的思维模式对游戏框架进行封装。

1.1 基础知识

上面列出的4个主要知识点,我都做技术准备,针对不同问题,参考不同文章就可以解决:

1.2 给R包起名

技术准备一切就绪,先给项目起个名字吧!

其实,起名也是有讲究的,不能太随便,虽然CRAN上面没有叫game包,但我们直接用game做为项目名字,也不是很好。如何起名最好先问问Google,找一个没有太多重名的关键字作为名字。

直接用google搜索 game 有 1,100,000,000 条结果,r game 有1,680,000,000条结果。我连0都数不过来了!和这么多搜索结果去竞争关键字,是我们在推广过程中不可逾越的鸿沟。

rgame-google

所以,换个名字让我们从小成长,找一个热度不是那么高的关键字,作为项目名字。gridgame就是一个不错的选择,既能表现游戏的特征,从推广角度又没有特别强大的竞争对手,一下子压力全无,倍感轻松!

gridgame-google

做好了各种准备工作,下面就是把gridgame包搞定了!

2. gridgame包开发

按照 在巨人的肩膀前行 催化R包开发 文章中介绍的标准化的开发流程,进行R包的开发。

本文的系统环境

  • Win7 64bit
  • R version 3.0.3 x86_64-w64-mingw32/x64 (64-bit)
  • Rtools31.exe
  • basic-miktex-2.9.5105.exe

由于有gridgame包开发的游戏都是基于Window平台的,而且我不打算支持Linux平台运行,所以我们的选择的R包开发环境,也应该是Window平台。后文中会介绍,为什么不支持Linux平台运行,R的版本最好也升级到3.0.3。(坑很多的,要一点一点填!)

2.1 构建工程

为了简化工作量,提高开发效率,我将按照devtools包的开发流程进行操作。

首先,打开一个项目目录,然后创建项目骨架。


~ cd /home/conan/R
~ R    

# 加载开发工具包
> library(devtools)
> library(roxygen2)
Loading required package: digest
> library(testthat)

# 创建项目骨架
> create(paste(getwd(),"/gridgame",sep=""))
Creating package gridgame in /home/conan/R
No DESCRIPTION found. Creating default:

Package: gridgame
Title:
Description:
Version: 0.1
Authors@R: # getOptions('devtools.desc.author')
Depends: R (>= 3.0.1)
License: # getOptions('devtools.desc.license')
LazyData: true

# 重置当前目录
> setwd(paste(getwd(),"/gridgame",sep=""))

# 查看项目骨架生成的文件
> dir(full.names=TRUE)
[1] "./DESCRIPTION" "./man"         "./R"

2.2 编写代码和文档

1). 编辑DESCRIPTION文件,增加项目的描述信息。


~ vi /home/conan/R/gridgame/DESCRIPTION

Package: gridgame
Type: Package
Title: A game framework for R
Version: 0.0.1
Date: 2014-07-23
Authors@R: c(person("Dan", "Zhang", email = "bsspirit@gmail.com", role
    =c("aut", "cre")))
Maintainer: Dan Zhang 
Description: This package provides a general-purpose game framework for grid game in R. The package includes 2 games about snake and 2048. You can run the function snake() or g2048() to startup the game. These games are only running on Window platform.
Depends:
    R (>= 3.0.1)
Imports:
    methods
License: GPL-3
URL: http://onbook.me/#/project/gridgame
BugReports: https://github.com/bsspirit/gridgame/issues
OS_type: windows
Collate:
    'game.R'
    '2048.R'
    'package.R'
    'snake.R'

DESCRIPTION文件中,有两个地方需要注意:

  • Imports: methods,由于我们用的是RC类型,系统默认会用methods包中的函数进行解析,必需在这里显示声明。
  • OS_type: windows,由于我们只仅支持Window系统运行,因此在后面上传到CRAN检查时,必需要指明支持的系统。同时,也是由于加了这个属性,再到Linux中执行R CMD check 过程的时候会自动失败,因此要求我们只能在windows系统中进行打包和发布的操作了。

2). 复制我们已经完成的3个R文件到 /home/conan/R/gridgame/R 目录下面。


~ ls -l
-rw-rw-r-- 1 conan conan 5030  7月 23 17:23 2048.R
-rw-rw-r-- 1 conan conan 2151  7月 23 17:18 game.R
-rw-rw-r-- 1 conan conan 5204  7月 23 17:23 snake.R

我们需要对代码进行再整理,都是检查失败错误。

  • 1. 去掉2048.R和snake.R代码中source()函数对game.R文件的引用。
  • 2. 去掉代码中所有中文注释,只能是ASCII码支持的字符。
  • 3. 在代码中增加Window平台检查,非Window则禁止运行,通过 .Platform$OS.type==’windows’ 代码,判断运行时的系统环境。
  • 4. 增加package.R文件,用于加载methods包的配置信息,#’ @import methods。
  • 5. 去掉代码中启动函数,启动交给用户来操作。

2.3 调试程序

在Windows系统开发环境中,通过load_all()函数加载程序包,然后运行一个snake()函数 或者 g2048()函数,一切正常。


# 加载程序包
> load_all(getwd())
Loading gridgame

# 启动snake游戏
> snake()

# 启动2048游戏
> g2048()

我们写的游戏程序,都是在window7下开发的,运行一切正常,那么为什么不支持在Linux系统中运行呢? 主要原因是 Linux和Window7有不同的图形设备输出。windows系统中,输出设备是通过.net框架来支持的;而Linux系统中的输出设备是X11()显示驱动支持,或者通过在Linux系统中加载第三方的tk设备支持,R语言通过tkrplot包来实现调用。


~ sudo apt-get install tk-dev
> install.packages("tkrplot")

Windows系统和Linux系统对于运行GUI程序是有区别的,无法统一用一套代码来完成。有人会说,每个地方都增加系统类型的判断条件,就能可实现了。

当然情况并不是这么简单,除了输出设备的问题以外,Linux上面还会遇到字体的问题,字库不全将导致字符加载失败的错误。下面的问题,Linux系统中没有helvetica的60号字体。


Error in text.default(0.5, 0.7, label = name, cex = 5) : 
  X11 font -adobe-helvetica-%s-%s-*-*-%d-*-*-*-*-*-*-*, face 1 at size 60 could not be loaded

虽然在Linux Ubuntu环境中,我尝试了安装所有字体库,仍然无法解决大号字体的加载问题。所以,我决定最终将不支持Linux平台。


~ sudo apt-get install xfont-100dpi xfont-75dpi xfont-cyrillic xfont-*

2.4 单元测试

在inst/test目录下面,我们分别针对不同的文件,创建单元测试类。

  • test-game.R, 对game.R的函数进行单元测试
  • test-snake.R,对snake.R的函数进行单元测试
  • test-2048.R,对2048.R的函数进行单元测试

以test-game.R为例,打开test-game.R文件


~ vi inst/test/test-game.R

context("game")

test_that("Initial the construct function of Game class", {
  name<-"R"
  width<-height<-10
  
  game<-Game$new()
  game$initFields(name=name,width=width,height=height)
  expect_that(game$name,equals(name))
  expect_that(game$width,equals(width))
  expect_that(game$height,equals(height))
})

执行单元测试代码。


> test(getwd())
Testing gridgame
Loading gridgame
game : ...

2.5 撰写文档

R包开发中最繁琐的一个过程,就是撰写文档,Latex的格式文档。幸好有人发明了roxygen2包,通过简单的注释规则来生成Latex文档。

我们用roxygen2包,来生成man/*.Rd的文档文件,对RC类型的程序,其实就可以偷点懒了,只是在类的定义上,增加注释就行了。RC类中方法的注释,就没强制的检查了。多写少写就看开发者的心情了。如果是S3的编程方式或者纯函数式的包,那么写文档也是一件很辛苦的工程呢。当然,文件不能出现中文字符,不然check过程的时候,还是会有警告发生的。

以snake.R文件中注释为例,我们只写setRefClass的注释 和 snake<-function(){}的注释就行了,Snake类的内部方法就省略了。


~ vi snake.R

#' Snake game class
#' @include game.R
Snake<-setRefClass("Snake",contains="Game",
   ...
)

#' Snake game function
#'
#' @export
snake<-function(){
  game<-Snake$new()
  game$initFields()
  game$run()
}

通过代码中的注释生成Latex文件。


> document(getwd())
Updating gridgame documentation
Loading gridgame
Writing G2048-class.Rd
Writing g2048.Rd
Writing Game-class.Rd
Writing Snake-class.Rd
Writing snake.Rd

打开snake.Rd文件,看看生成的内容。


~ vi man/snake.Rd

% Generated by roxygen2 (4.0.1): do not edit by hand
\name{snake}
\alias{snake}
\title{Snake game function}
\usage{
snake()
}
\description{
Snake game function
}

这一步的操作过程,其实也不是一帆风顺的。在引用roxygen2 包的时候,我同样遇到的问题了。
在Window环境中,roxygen2包 依赖于R 3.0.2以上的版本,R 3.0.1版本的R程序装不上roxygen2包。github有对这个强依赖问题的描述:https://github.com/klutometis/roxygen/issues/163

所以,上文中指定的R 3.0.3的版本环境,是实践检验出来的。

2.6 程序检查

程序检查,这一步其实是所有操作过程最容易出错的,而且还搞不定。R的打包的检查真的很严格啊!!

在Windows平台中开发R包,要装额外装两个软件 Rtools(http://cran.us.r-project.org/bin/windows/Rtools/) 和 MikTeX (http://www.miktex.org/download),不仅版本要和R语言环境对上,还要配置环境变量。MikTeX在调用过程中,还会遇到文件找不到,pdflatex.exe运行的错误 等等。

比如,其中的一个常见错误:


* checking PDF version of manual ... WARNING
LaTeX errors when creating PDF version.
This typically indicates Rd problems.
LaTeX errors found:
!pdfTeX error: pdflatex.EXE (file ts1-zi4r): Font ts1-zi4r at 540 not found
 ==> Fatal error occurred, no output PDF file produced!
* checking PDF version of manual without hyperrefs or index ... ERROR

解决方法,运行下面的命令。


~ updmap 
~ initexmf --update-fndb
~ initexmf --edit-config-file updmap

# 在文件中增加一行
Map zi4.map 

~ initexmf --mkmaps

最后,如果经过9*9=81难,终于修成正果,一路OK的完成了!


> check(getwd())
Updating gridgame documentation
Loading gridgame
Writing NAMESPACE
Writing G2048-class.Rd
Writing g2048.Rd
Writing Game-class.Rd
Writing Snake-class.Rd
Writing snake.Rd
"C:/PROGRA~1/R/R-30~1.3/bin/x64/R" --vanilla CMD build  \
  "D:\workspace\R\app\gridgame" --no-manual --no-resave-data

* checking for file 'D:\workspace\R\app\gridgame/DESCRIPTION' ... OK
* preparing 'gridgame':
* checking DESCRIPTION meta-information ... OK
* checking for LF line-endings in source and make files
* checking for empty or unneeded directories
* building 'gridgame_0.0.1.tar.gz'

"C:/PROGRA~1/R/R-30~1.3/bin/x64/R" --vanilla CMD check  \
  "C:\Users\ADMINI~1\AppData\Local\Temp\RtmponOeAc/gridgame_0.0.1.tar.gz"  \
  --timings

* using log directory 'C:/Users/ADMINI~1/AppData/Local/Temp/RtmponOeAc/gridgame.Rcheck'
* using R version 3.0.3 (2014-03-06)
* using platform: x86_64-w64-mingw32 (64-bit)
* using session charset: ASCII
* checking for file 'gridgame/DESCRIPTION' ... OK
* checking extension type ... Package
* this is package 'gridgame' version '0.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 whether package 'gridgame' 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 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

在执行check过程中,你的项目里可能会有其他的文件,检查也过不去的。你可新建一个文件.Rbuildignore,通过这个文件配置,可以忽略不希望参与打包的文件。


~ vi .Rbuildignore

.gitignore
dist
^.*\.Rproj$
^\.Rproj\.user$
README*
NEWS*
FAQ*

这样一些帮助文件,就能躲避检查了。

2.7 程序打包

在检查通过以后,我们就可以自由地打包了,用build命令。

我们可以选择2种打包方式,源代码打包和二进打包。

默认是给源代码打包。


> build()
"C:/PROGRA~1/R/R-30~1.3/bin/x64/R" --vanilla CMD build  \
  "D:\workspace\R\app\gridgame" --no-manual --no-resave-data

* checking for file 'D:\workspace\R\app\gridgame/DESCRIPTION' ... OK
* preparing 'gridgame':
* checking DESCRIPTION meta-information ... OK
* checking for LF line-endings in source and make files
* checking for empty or unneeded directories
* building 'gridgame_0.0.2.tar.gz'

[1] "D:/workspace/R/app/gridgame_0.0.2.tar.gz"

二进制打包


> build(binary=TRUE)
"C:/PROGRA~1/R/R-30~1.3/bin/x64/R" --vanilla CMD INSTALL  \
  "D:\workspace\R\app\gridgame" --build

* installing to library 'C:/Users/Administrator/AppData/Local/Temp/RtmpI3hhpp'
* installing *source* package 'gridgame' ...
** R
** inst
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
*** arch - i386
*** arch - x64
* MD5 sums
packaged installation of 'gridgame' as gridgame_0.0.2.zip
* DONE (gridgame)
[1] "D:/workspace/R/app/gridgame_0.0.2.zip"

这两个文件都可以用出来发布项目,用户下载后可以直接进行安装。


# 安装命令
~ R CMD INSTALL gridgame_0.0.2.tar.gz
* installing to library 'C:/Users/Administrator/R/win-library/3.0'
* installing *source* package 'gridgame' ...
** R
** inst
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
*** arch - i386
*** arch - x64
* DONE (gridgame)

3. gridgame包发布

最后一步,就是把我的好不容易开发的包,发布到资源库。有3个地方可以发布。

  • CRAN:R的官方发布平台
  • R-Forge:R-Forge发布平台
  • RForge:RForge发布平台
  • Github:个人开源发布平台

3.1 Github:个人的开源发布平台

在Github上发布是最容易的,只要把项目代码上传到Github就完成了,都不需要做check()检查。基于Github的包管理工具是devtools包,我把gridgame项目已上传到Github, 项目地址是:https://github.com/bsspirit/gridgame,用户可以下面两种方式,直接从Github安装gridgame项目。

方法一:使用devtools包,二进制安装。


library(devtools)
install_github("gridgame","bsspirit")

方法二:通过源代码安装。


git clone https://github.com/bsspirit/gridgame.git
R CMD BUILD gridgame
R CMD INSTALL gridgame_*.tar.gz

3.2 R-Forge:R-Forge发布平台

在R-Forge(https://r-forge.r-project.org/)发布,就比较麻烦了,你需要先注册一个账号,https://r-forge.r-project.org/account/register.php,登陆后,再新建一个项目,需要等72小时审核才能通过。

在R-Forge中,gridgame项目管理界面截图
rfroge1

然后,通过SVN把项目的源代码提交上去。我用习惯了Git进行版本管理,再用回SVN感觉好老土啊!

在RForge提交代码,并运行通过以后,你会有项目介绍页:http://gridgame.r-forge.r-project.org/,别个会看到介绍,下载你的包。

rfroge2

用户可以直接查看项目信息 http://gridgame.r-forge.r-project.org/,也可以在线查看项目源代码,https://r-forge.r-project.org/scm/viewvc.php/?root=gridgame,R-Froge平台会每天自动打包一次。

3.3 RForge:RForge发布平台

此RForge(http://rforge.net/)非R-Froge,竟然两个名字如此之近似,第一次用的人肯定会混的。首先注册RForge账号,同时注册一个要发布的项目。gridgame项目,我已经上传到Github了,这边能直接导入Github项目,就非常方便了。

rfroge

通过RForge源下载gridgame包,可以直接用install.packages()函数。


install.packages('gridgame', repos = 'http://rforge.net')  # 未发布成功,请先用Github的方案

3.4 CRAN发布:R的官方发布平台

这4个发布平台,CRAN是最全威的、是官方的,也不是那么容易发布的,有很严格的审查机制。CRAN发布条款:http://cran.r-project.org/web/packages/policies.html

我们明白政策后,通过 http://cran.r-project.org/submit.html 提交项目,大概要等待48小时审查。可能我这个包的问题比较严重6个小时内有就了回复。

  • 第一次不合格:没有标出只支持Window平台,对应DESCRIPTION文件中OS_type: windows。(当然,他是不会告诉你怎么改的,找自己Google找)
  • 第二次不合格:Linux平台R CMD check出错。(加了OS_type后,Linux执行当然会出错了,老外似乎也晕了。)
  • 第三次不合格:为什么Linux不能用,为什么用.Platform$OS.type的代码检查,getGraphicsEvent在没有GUI的环境中怎么办,文档不全,对game framework的定义不清楚。(费了好大劲的解释,把这几篇文章的设计理念,写了封总结的邮件。)
  • 第四次不合格:这次Uwe Ligges的态度很强硬,必须把Rd写完整,必须支持至少2个平台,必须对getGraphicsEvent进行检查,必须处理OS.type的代码问题,没有商量的余地,不搞定就不发包。(我真是悲剧了,看来发布项目,又要延迟一周了。)

下面是,提交项目到CRAN过程。

第一步:填写用户基本信息,并上传打好的tar.gz包
cran1

第二步:核对DESCRIPTION文件中的描述,与网页自动解析的内容是否一致。
cran2

第三步:等待审核。
cran3

第一次不合格,老外回复的邮件:


On 25/07/2014 04:24, Dan Zhang wrote:
> [This was generated from CRAN.R-project.org/submit.html]
>
> The following package was uploaded to CRAN:
> ===========================================
>
> Package Information:
> Package: gridgame
> Version: 0.0.1
> Title: A game framework for R
> Author(s): Dan Zhang [aut, cre]
> Maintainer: Dan Zhang 
> Depends: R (>= 3.0.1)
> Description: This package provides a general-purpose game framework for
 
'This package provides' is redundant.
 
>    grid game in R. The package includes 2 games about snake and
>    2048. You can run the function snake() or g2048() to startup
>    the game. These games are only running on Window platform.
 
Eh?  The CRAN policies do not allow such a package, and you have not
marked this as Windows-only.
> License: GPL-3
> Imports: methods
>
>
> The maintainer confirms that he or she
> has read and agrees to the CRAN policies.
>
> Submitter's comment: This package provides a general-purpose game
>    framework for grid game in R. The package includes 2
>    games about snake and 2048. You can run the function
>    snake() or g2048() to startup the game. These games
>    are only running on Window platform.
>

--
Brian D. Ripley,                  ripley@stats.ox.ac.uk
Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595

经过多次的对决和修改,终于把包成功发布到了CRAN。

同学们可以直接下载使用了。


# 从CRAN下载gridgame包
install.packages('gridgame')  # 未发布成功,请先用Github的方案

# 加载gridgame包
library(gridgame)

# 启动贪食蛇游戏
snake()

# 启动2048游戏
g2048()

到CRAN上发布一个R包,真是不一件轻松的事情啊。坚持,修改,打磨,再坚持,虽然过程很痛苦,但是软件质量最终得到了保证,这就是CRAN严格审查的意义。

转载请注明出处:
http://blog.fens.me/r-game-gridgame/

打赏作者