• R语言
  • 编写你自己的程序包(Writing R Extensions)

今天发现丁国徽在一篇文章中提到会译<<Writing R Extensions>>,不知道他的工作进行得怎么样了?我是否有必要停止我的工作? 如果有人知道,请给我发个邮件:bravebird@126.com

谢谢.
别人会译是别人的,而你是你自己的,喜欢就做下去吧。你英语比我厉害得多了,羡慕,如果我能自己翻译英文软件的说明说就好了。
[quote]引用第4楼bravebird2008-11-22 14:54发表的“”:

今天发现丁国徽在一篇文章中提到会译<<Writing R Extensions>>,不知道他的工作进行得怎么样了?我是否有必要停止我的工作? 如果有人知道,请给我发个邮件:bravebird@126.com

谢谢.[/quote]



可以直接和他联系,看有没有合作的可能。这样可以加快翻译速度。
1.1.2 “INDEX”文件

可选文件“INDEX”包含一列包中十分有用的对象,给出了他们的名称和描述(像print之类通常不显式调用的方法可能不会包括到里面)。通常该文件是没有的,相应的信息在从源安装和创建包(参见1.3节,检查和创建包)时自动地从文件中生成的(使用tools包中的Rdindex())。

与其编辑这个文件,还不如将针对包的具体信息放到一个关于包的综述性的手册中(参见2.1.4,文档打包)或包的简介中(参见1.4,撰写包的简介)。

1.1.3 包的子目录

子目录“R”只包含R的代码。所安装的代码文件应当以一个ASCII(小写或大写)字母或数字开始,并且扩展名为“.R”,“.S”,“.q”,“.r”或“.s”。我们推荐使用“.R”,因为这个扩展名看起来还没有被其它软件使用。有可能用source()来读入文件中的代码,所以要建立R的对象必须用assignments。注意要将文件名与由该文件创建的R的对象联系起来。最理想的是,R的代码文件应当只指定R的对象,并且一定不要调用像require和options之类的有会带来额外影响的函数。在使用延迟加载的时候,如果要求创建某个对象,这个对象在载入某个包前(参见字段”Collate”)就要提前使用该包中的代码,那么在”Depends”字段中的那些包提供的用来创建该对象的函数应提供这样的机制:让那些被创建的对象不能依赖于这些包,除非通过命名空间来引入它们。(没有使用命名空间的包将会有较少的限制。)

这儿允许有两个例外:如果在R的子目录下有一个文件“sysdata.rda”(保存的R的对象的镜象),它将被延迟加载入命名空间/包的环境中,这样做是为了使用方便系统使用系统数据而不是为了让用户通过data来访问它。同时,以“.in”结尾的文件可以放到R的目录中,这样就可以通过它使用“configue”脚本一生成适合的文件。

代码文件中应只使用ASCII字符(和控制字符tab,换页符,换行符,回车符)。其它字符在可以在注释中使用,但些字符在UTF-8编码下是不可读的。在安装时有非ASCII字符的对象名,就会出错。在引号括起来的字符串中,任何字节都是可以合用的(但\uxxxx是不应被使用的)。但在一些地区,非ASCII字符串可能不能使用或显示不正常。

包中的各种函数可以被初始化和清除。对于那些没有命名空间的包,比如.First.lab和.Last.lib(关于有命名空间的包,请参见1.6.3 加载链),通常是在名为“zzz.R”的文件中定义。如果.First.lib在一个包中被定义,在包被加载和执行attach后,它们由参数libname和pkgname调用。(如果一个带着版本信息的包被安装,那么这个包的名字就包括版本信息。比如“ash_1.0.9”)。被常用来在.First.lib中调用library.dynam来读取汇编的代码:另一个用途是调用会带来额外影响的函数。如果在一个包中存在.Last.lib,那么这个包在执行detach前,它们会被调用(用一个包的全路径的参数)。没有.Last.lib函数的包是很少见的:它的一个用处就是调用library.dynam.unload来释放汇编代码。

子目录“man”应当只包含包中对象的Rd(R文档)格式的文档文件。文件名必须以ASCII(大写或小写)字母或数字开头,扩展名为“.Rd”(默认)或“.rd”。另外,文件名必须在URLs:“file://”中是有效的,这就意味着它们必需全部是ASCII码,并且不包含“%”。更多信息,参见第二章[编写R的文档]。注意,包中所有用户级的对象都应被编进去。如果一个包pkg包含用户级别的对象,但仅在内部(“internal”)使用,那么在包中应当提供一个“pkg-internal.Rd”文件,它们编入所有的这些对象,并且明确说明它们不会被用户调用。R的标准版本中的grid包可以作为例子供参考。注意那些大量使用内部对象的包,当这些对象没有被编录的时候,应当将这些对象隐藏在一个命名空间中(参见1.6 包的命名空间)。
子目录“R”和“man”可以包含与特定操作系统相关的子目录,名为“unix”或“windows”。

*****

目录“scr”中加入的可选文件“Makevars”或“Makefile”是编译后代码的源代码和头文件,当用R命令INSTALL安装一个包时,Make用来控制编译并且连接到加载到R中的共享对象。对于C,C++,FORTRAN77,Fortran 9x,Objective C和Objective C++(它们的扩展名分别为“.c”,“.cc”或“.cpp”或“.C”,“.f”,“.f90”或“.f95”,“.m”和“.mm”或“.M””)这个过程有默认的变量的规则(当R的配置被记录到“R_HOME/etcR_ARCH/Makeconf”中时这些规则就确定了)。对于C++或Fortran9x的文件,我们推荐使用“.h”作为头文件。默认的规则可以通过在文件“src/Makevars”中设置宏来改变(见1.2 使用Makevars)。注意这个机制应当通用化,使“src/Makefile”的不再需要***。如果分配了这样一个文件,要非常小心的将它通用化,让它能够在所有的R的平台上使用。它应当有一个恰当的最初目标(一般称为“all”)和(可能是空的)目标“clean”,目标“clean”将清除所有的由Make(执行R安装命令”clean”和R安装命令”preclean”)产生的文件。在Windows上专用的文件“src/Makevars.win”的优先级高于“src/Makevars”,并且必须使用文件“src/Makefile.win”。***

子目录“data”是用来存放由包产生的额外数据文件,这些数据文件可以用data()来加载。目前,数据文件可以有三种类型,其类型由扩展名决定:一般的R代码(“.R”或“.r”),表(“.tab”,“.txt”或“.csv”,文件格式请参考?data)或save()保存的镜象(“.RData”或“.rda”)。R的所有端口都使用同样的二进制(XDR)格式,并且可以读取压缩镜象。默认由save(,compress=TRUE)保存的镜像,以节省空间。注意,为了在没有加载包的情况下使用数据文件,R代码应当在数据文件中是封闭的,不要使用包中另外提供的的函数。再也不必在“data”目录中提供“00Index”文件了,相应的信息会在安装包或者创建包(参见1.3 检查并创建包)时由文档自动生成。如果你的数据文件比较在,你可能用文件在”data”子目录中使用一个“datalist”文件来加快安装过程。在该文件中,每个data()可以找到的主题占一行。如果格式为“foo”,命令data(foo)将加载数据“foo”,就用格式“foo”,如果格式为“foo:bar bah”,命令”data(foo)”将加载数据“bar”和“bah”。 ***

子目录“demo”是用来保存R的脚本文件的(通过demo()运行),它们用来演示包的一些功能。演示可以是交互的,并且不会被自动检查,所以,如果想要测试演示代码,请使用“tests”子目录下的代码。脚本文件必须以字母(大写或小写)开头,扩展名为“.R”或“.r”。如果提供了演示,那么“demo”子目录应当提供一个文件“00Index”,每个演示分别写成一行,给出演示的名称及其描述,名称和描述用空格格开。(这个索引文件是不可能自动生成的。)

子目录“inst”下的内容将被累加式地复制到包的安装目录下。“inst”的子目录将不会影响那些由R使用的目录(目前为“R”,“data”,“demo”,“exec”,“libs”,“man”,“help”,“html”,“latex”,“R-ex”,“chtml”和“Meta”)。在创建“src”后就拷贝“inst”,这样,“Makefile”就可以创建要安装的文件。注意除“INDEX”,“LICENSE”/“LICENCE”,“COPYING”和“NEWS”(从R 2.7.0开始),包的高级信息文件将不会被安装,这样用户就不会知道Windows和MacOS X的被编译了的包的信息(并且用户如果用R命令INSTALL或者从工具栏执行install.packages也看不见)。所以,你如果想要最终用户看到其它信息文件,就应当把它们放到“inst”中。
子目录“tests”是用来存放附加的具体包的测试代码,类似于R中发行版本中的具体的测试。测试代码既可以直接由一个“.R”文件来提供,也过以由“.Rin”文件中的代码来创建相应的”.R”文件(例如:通过收集包中所有的函数对象,然后用临时参数来调用它们)。运行“.R”代码的结果被写入了文件“.Rout”中。如果已经存在一个相应的“.Rout.save”文件,就将比较这两个文件,将报告它们的不同之处,并不会引起错误。目录“tests”将被拷贝到检查区域,并且测试将在这个拷贝上运行,并且将拷贝作为工作目录,还设置了参数R_LIBS以确保安装的包在测试期间能够通过library(pkg_name)加载。

子目录“exec”可以包含附加的包需要的可执行文件,典型的文件是shell, Perl 或Tcl这些解释程序的脚本。这种机制现在只用在很少的一些包中,并且依然是试验性的。

子目录“po”是用来存放那些与本地化(localization)相关的文件的。参见1.9 国际化。

1.1.4 包的封装(Package bundles)

有时将几个小的包封装成一个大的包一起发行是比较方便的。(VR就是一个例子,它包含4个包。)在类Unix操作系统和Windowx上的安装程序都能处理这样的大包。

大包的“DESCRIPTION”文件中有一个“Bundle”字段,没有“Package”字段,如下所示:

Bundle: VR

Priority: recommended

Contains: MASS class nnet spatial

Version: 7.2-36

Date: 2007-08-29

Depends: R (>= 2.4.0), grDevices, graphics, stats, utils

Suggests: lattice, nlme, survival

Author: S original by Venables & Ripley.

R port by Brian Ripley <ripley@stats.ox.ac.uk>, following earlier

work by Kurt Hornik and Albrecht Gebhardt.

Maintainer: Brian Ripley <ripley@stats.ox.ac.uk>

BundleDescription: Functions and datasets to support Venables and

Ripley, ’Modern Applied Statistics with S’ (4th edition).

License: GPL-2 | GPL-3

URL: http://www.stats.ox.ac.uk/pub/MASS4/

“Contains”字段列出了大包中包含的小包(空格分开),它们将按照它们的名字分别放到不同的子目录中。在创建和安装期间,包(后面的包指的是小包)将按指定的顺序安装。请确认列表的顺序与它们之间的依赖关系是对应的。

除了“DESCRIPTION”文件被替换为“DESCRIPTION.in”外,大包中的小包都是标准的包。在“DESCRIPTION.in”中只包含了附加到大包中文件“DESCRIPTION”的字段。比如:

Package: spatial

Description: Functions for kriging and point pattern analysis.

Title: Functions for Kriging and Point Pattern Analysis

除了“DESCRIPTION”文件和命了名的包之外,在大包中的所有文件,都将被忽略。

大包中的“DESCRIPTION”文件中的“Depends”字段将列出所有小包的从属(类似于“Imports”和“Suggests”),并且文件“DESCRIPTION.in”就不应再包含这些字段了。
1.2 配置和清理

注意节的大部分都是针对Unix的:参考后面关于R的Windows端口的评价。在安装包之前,如果你的包需要针对特定的操作系统作一些配置,你可以在包中安排一个可执行(Bourne shell)脚本文件“configure”,在运行其它程序前,R命令INSTALL将首先执行(如果有)该文件。该脚本可以由Autoconf生成。也可以由你自己写。这样就可以用来检测是否提供了非标准的程序(library),让错误的代码在安装的时候就被发现,而不是在包被编译后或者使用时才给出错误提示。总之,你可以在你的扩展包中最大限度地发挥Autoconf的作用(包括变量代换,搜索程序库等)。

在Unix及其类似的操作系统上,如果在运行R命令INSTALL时给出了选项“--clean”,那么在程序的最后一步将运行脚本(Bourne shell)程序”cleanup”。在用R命令build准备从源创建包时也是这样。可以用它来清除包的源目录树,特别是用来删除所有由“configure”创建的文件。

比如,假设我们想使用一个(C或FORTRAN)程序库foo的某些功能。我们可以用Autoconf来创建一个配置脚本,用来查找程序库,将如果找到了,就将变量HAVE_FOO设置为TRUE,如果没找到,就设为FALSE,然后将这个值写入到输出文件(用HAVE_FOO的值来替换输入文件中“@HAVE_FOO@”的实例)。例如程序库foo可以链接到函数bar(即使用”-lfoo”),可以在“configure.ac”中使用(假设是Autoconf 2.50或更新的)

AC_CHECK_LIB(foo, fun, [HAVE_FOO=TRUE], [HAVE_FOO=FALSE])

AC_SUBST(HAVE_FOO)

......

AC_CONFIG_FILES([foo.R])

AC_OUTPUT

相应的R的函数“foo.R.in”可以定义为:

foo <- function(x) {

if(!@HAVE_FOO@)

stop("Sorry, library ’foo’ is not available"))

...

如果程序库foo(和想要的功能)没找到,从该配置文件创建的R源文件“foo.R”类似

foo <- function(x) {

if(!FALSE)

stop("Sorry, library ’foo’ is not available"))

...

上面的代码有效地将该函数变为不可用。

对于那些可用或者不可用功能,可以分别使用不同的程序块。

在编译R或者你的包的时候,你很可能需要确保样同的C编译嚣和编译标识可以用在“configure”测试中。在Unix下,为了实现这个目的,你可以在“configure.ac”文件的前面部分写入下列程序段:

: ${R_HOME=‘R RHOME‘}

if test -z "${R_HOME}"; then

echo "could not determine R_HOME"

exit 1

fi

CC=‘"${R_HOME}/bin/R" CMD config CC‘

CFLAGS=‘"${R_HOME}/bin/R" CMD config CFLAGS‘

CPPFLAGS=‘"${R_HOME}/bin/R" CMD config CPPFLAGS‘

(当将脚本文件作为R命令INSTALL一部分的时候,为了能够使用正确的R的版本,有必要使用“${R_HOME}/bin/R”,而不要使用“R”)

注意本文档的早期版本推荐直接从“R_HOME/etcR_ARCH/Makeconf”获得(使用grep或sed)配置信息,这样就只能测试那些作为字面值记录在那的变量。你可以使用R命令config来获取基本配置变量的值或头文件和程序库标识,它们都是联结到R所必需的。更详细信息参考R命令config—help。(从R 2.6.0开始,也可以在Windows上运行。)

注意由R决定的FLIBS必须用来确保FORTRAN77代码能够在所有R平台上运行。不必调用(并且由此,例如,从ACX_BLAS移除)Autoconf的宏AC_F77_LIBRARY_LDFLAGS,它将重写FLIBS。(目前版本的Autoconf实际上允许一个已经存在的FLIBS来改写FORTRAN连结标识的测试。同时,目前版本的R可以检测外部的BLAS和LAPACK程序库。)
4 天 后
[quote]引用第13楼wanghl20072008-11-28 15:18发表的“”:

加油,我支持你![/quote]

这是我最大的动力。



要检查外部的BLAS程序库,可以使用官方的Autoconf宏包中的ACX_BLAS宏,如下所示:

F77=‘"${R_HOME}/bin/R" CMD config F77‘

AC_PROG_F77

FLIBS=‘"${R_HOME}/bin/R" CMD config FLIBS‘

ACX_BLAS([], AC_MSG_ERROR([could not find your BLAS library], 1))

注意像由R决定的FLIBS必须用来确保FORTRAN77代码能够在所有R平台上运行。不必调用(并且由此,例如,从ACX_BLAS移除)Autoconf的宏AC_F77_LIBRARY_LDFLAGS,它将重写FLIBS。(目前版本的Autoconf实际上允许一个已经存在的FLIBS来改写FORTRAN连结标识的测试。同时,目前版本的R可以检测外部的BLAS和LAPACK程序库。)

你应当记住配置脚本文件在Windows系统上无法正常运行(尽管简单的shell脚本可以运行,但如果是由Autoconf生成的脚本一般是不能运行的)。如果你的包是要给公众使用,请给那些使用非Unix平台的用户足够的信息,好让他们手动配置,或者提供一个能在Windows平台下使用的脚本文件“configure.win”。(那也可以放置一个可选的cleanup.win”脚本,它们都应当是可以由ash执行的脚本文件,ash是一个Bourne-style sh.的最小化版本。)

在一些极少见的情况下,配置和清理脚本文件需要知道包的安装位置。比如,在包中使用了C语言代码,并且建立了两个共享对象或DLL。通常,被R动态地加载的对象是与该附加对象相联系的。在一些操作系统中,当R动态地调用一个对象时,可以将其所依赖的其它对象的地址指定给该象。这意味着每个用户不必设置环境变量LD_LIBRARY_PATH(或其它类似的变量),而自动加载该附加对象。另一个例子是当包在安装在运行时使用的文件的时,它们的地址会在安装的时候被写入R的数据结构中(如SJava包中的Java Archive文件)。最高级的程序库目录(由“-l”参数指定的)和包的目录本身可以通过shell/环境变量R_LIBRARY_DIR和R_PACKAGE_DIR指定线安装脚本文件。另外,包的名称(如“survival”或“MASS”)也可以从shell变量R_PACKAGE_NAME获得。

1.2.1 使用“Makevars”
5 天 后
支持有时间我也加入,我以前也用过一段,最近也写了经验似然和变系数模型方面的一些东西,看有时间我也打个包。
2 个月 后
4 个月 后
1 个月 后
[quote]引用第17楼pengchy于2009-06-20 01:52发表的  :

人呢?谁来继续?

[/quote]

会继续的,感兴趣不妨加入哦!
3 年 后