漢ならコードで語れ、ということで自分のパッケージを作った

何か自分のproductがあるといいよなーと思ったので卒研で書いたコードの断片をパッケージにして公開してみました。パッケージはここに置いています。

作ったものの説明

ノンパラメトリック回帰の手法の一つであるナダラヤワトソン推定量を計算するためのパッケージです。そういうわけでnwパッケージという名前にしてみました。自分で平滑化パラメータ行列を与えてパラメータがどのような効果を持つか見てみることもできますし、クロスバリデーション関数を最小にするような平滑化パラメータ行列を計算させることもできます。内部を多少Cで書いているため、そこそこのスピードで動かすことができます。
後ろにも書いていますが

R CMD INSTALL nw_0.01.tar.gz    

とやってインストールした後

library(nw)
example(nw)

とすると上に書いたことが始まります。

今のところ用意してあるカーネル関数がエパニフニコフしかないなどしょぼいところが多いですが、とにもかくにも"自分の"パッケージを初めて作ってみたというところが今回の焦点です><。

作る過程

パッケージを作るためにはいくつか必要なディレクトリやファイルが必要ですが、Rはその雛形を作ってくれる関数があります。

package.skeleton("nw", path="~/Desktop",code_files="~/Desktop/nw.R")

これで

  • DESCRIPTION
  • R
  • man

などのファイル、ディレクトリができあがります。Rディレクトリには自分の作った関数、manディレクトリには関数に対応したヘルプファイルを.Rd形式で書きます。EmacsのメジャーモードESSを使うと見やすいですね。ちなみに今回のplot.nw関数の.Rd形式のヘルプはこんな感じになっています。TeXみたいですね、というかTeXです。

\name{plot.nw-methods}
\docType{methods}
\alias{plot.nw-methods}
\alias{plot.nw,nw-method}
\title{Plotting the result of regression with Nadaraya-Watson estimator}
\description{
  Plotting the result of regression with Nadaraya-Watson estimator in
  three dimensions.
}
\section{Methods}{
\describe{
  \item{this = "nw"}{nw object generated by 'nw' method.}
}}
\keyword{methods}
\keyword{models}

また、今回のように内部で(C|C++)を使っている場合、srcというディレクトリを作って、ソースを入れておきます。コンパイルはRをbuildするときにやってくれるので楽チンです。コンパイルした場合、それを読み込んであげる必要があります。インタラクテイブに実行しているときには必要に応じて読み込めばいいのですが、ライブラリのときにはそうもいきません。こういうことをするためのファイルとして慣習的にRディレクトリにzzz.Rというファイルを作って、.onLoad関数に

.onLoad <- function(lib, pkg) {
  library.dynam("nw", pkg, lib)
}

という感じでやるときちんと読み込めるようになります。パッケージで作った関数とRに元からある関数やオブジェクトが被ってしまう、という問題を解決したいときにはNAMESPACEファイルを使うといいです。今回のパッケージの場合

export(nw)
export(choice.optimal.h)

S3method(plot, nw)

という感じでやっています。

きちんとできているか確認

上のようなことが不足なくできているか確認するコマンドがあります。こんな感じで全部okになれば次のステップへ行けます。errorやwarningが出ていたら頑張ってつぶしていきましょう。

Users/yasuhisa/Desktop% R CMD check nw              
* checking for working pdflatex ... OK
* using log directory '/Users/yasuhisa/Desktop/nw.Rcheck'
* using R version 2.8.1 (2008-12-22)
* using session charset: UTF-8
* checking for file 'nw/DESCRIPTION' ... OK
* checking extension type ... Package
* this is package 'nw' version '0.01'
* checking package name space information ... OK
* checking package dependencies ... OK
* checking if this is a source package ... OK
* checking for executable files ... OK
* checking whether package 'nw' can be installed ... OK
* checking package directory ... OK
* checking for portable file names ... OK
* checking for sufficient/correct file permissions ... OK
* checking DESCRIPTION meta-information ... OK
* checking top-level 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 name space can be loaded with stated dependencies ... 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 cross-references ... OK
* checking for missing documentation entries ... OK
* checking for code/documentation mismatches ... OK
* checking Rd \usage sections ... OK
* checking line endings in C/C++/Fortran sources/headers ... OK
* checking line endings in Makefiles ... OK
* checking for portable use of $BLAS_LIBS ... OK
* creating nw-Ex.R ... OK
* checking examples ... OK
* creating nw-manual.tex ... OK
* checking nw-manual.tex using pdflatex ... OK

よしよし。

build

次にbuildしてtar.gzに固めていきます。Windowsだとzipに固めるらしいですが、知りません。

/Users/yasuhisa/Desktop% R CMD build nw 
* checking for file 'nw/DESCRIPTION' ... OK
* preparing 'nw':
* checking DESCRIPTION meta-information ... OK
* cleaning src
* removing junk files
* checking for LF line-endings in source and make files
* checking for empty or unneeded directories
* building 'nw_0.01.tar.gz'

この時にCのソースをよしなにコンパイルしてくれるようです。

install

下のコマンドかinstall.packages関数でインストールができます。

/Users/yasuhisa/Desktop% R CMD INSTALL nw_0.01.tar.gz    
* Installing to library '/Library/Frameworks/R.framework/Resources/library'
* Installing *source* package 'nw' ...
** libs
** arch - i386
gcc -arch i386 -std=gnu99 -I/Library/Frameworks/R.framework/Resources/include -I/Library/Frameworks/R.framework/Resources/include/i386  -I/usr/local/include    -fPIC  -g -O2 -c cross_validation.c -o cross_validation.o
gcc -arch i386 -std=gnu99 -dynamiclib -Wl,-headerpad_max_install_names -mmacosx-version-min=10.4 -undefined dynamic_lookup -single_module -multiply_defined suppress -L/usr/local/lib -o nw.so cross_validation.o   -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation
ld: warning, duplicate dylib /usr/local/lib/libgcc_s.1.dylib
** arch - ppc
gcc -arch ppc -std=gnu99 -I/Library/Frameworks/R.framework/Resources/include -I/Library/Frameworks/R.framework/Resources/include/ppc  -I/usr/local/include    -fPIC  -g -O2 -c cross_validation.c -o cross_validation.o
gcc -arch ppc -std=gnu99 -dynamiclib -Wl,-headerpad_max_install_names -mmacosx-version-min=10.4 -undefined dynamic_lookup -single_module -multiply_defined suppress -L/usr/local/lib -o nw.so cross_validation.o   -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation
ld: warning, duplicate dylib /usr/local/lib/libgcc_s.1.dylib
** R
** preparing package for lazy loading
** help
 >>> Building/Updating help pages for package 'nw'
     Formats: text html latex example 
  choice.optimal.h                  text    html    latex
  nw-package                        text    html    latex   example
  plot.nw-methods                   text    html    latex
** building package indices ...
* DONE (nw)
cp: /Library/Frameworks/R.framework/Resources/library/R.css: Permission denied

これで勝つる!!!

参考