S4 クラスとメソッド入門
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
]
開始行:
COLOR(magenta){SIZE(18){R の S4 クラス、メソッド入門}} C...
//COLOR(red){SIZE(18){只今作業中!}}~
以下では、R のクラスとメソッドについて簡単に説明する。R ...
COLOR(blue){クラス(class)}とはある構造を持つデータの集ま...
S 言語第四版に関する原典は [[データによるプログラミング:h...
//しばらくの間修正・追加等はコメント経由でお願いします。
-例えば、e1071パッケージにあるsvmのオンラインヘルプ中のS3...
#comment
~
~
COLOR(blue){SIZE(20){目次}}
#contents
~
~
*COLOR(magenta){SIZE(18){R の S3 クラスとメソッド}} [#ife...
**COLOR(magenta){SIZE(16){S3クラスは本質的にオブジェクト...
S3クラスは本質的にオブジェクトのCOLOR(blue){クラス属性(cl...
***COLOR(magenta){SIZE(16){例: S3 クラス、総称的関数、メ...
> x <- lm(1:10~rnorm(10)) # 簡単な単回帰。クラス属性 ...
> class(x) # クラス属性
[1] "lm"
> summary(x) # 総称的関数 summary の適用。実際はメソッ...
Call:
lm(formula = 1:10 ~ rnorm(10))
Residuals:
Min 1Q Median 3Q Max
-4.3527 -2.2764 0.1823 2.4843 4.5825
(...以下略...)
**COLOR(magenta){SIZE(16){S3メソッドの仕組み}} [#kc7dfc58]
総称的関数はクラス属性文字列(だけ?)を頼りに、適当なメソッ...
***COLOR(magenta){SIZE(16){例:総称的関数 plot の(S3)メソ...
> methods(plot)
[1] plot.Date* plot.HoltWinters* plot.POSIXct*
[4] plot.POSIXlt* plot.TukeyHSD plot.acf*
.........................................................
[31] plot.ts plot.tskernel*
Non-visible functions are asterisked
**COLOR(magenta){SIZE(16){S3クラスの「いい加減さ」}} [#k3...
S3 クラス属性は「勝手に」与えることができる。
***COLOR(magenta){SIZE(16){例: S3 クラス属性は「勝手に」...
> y <- runif(10)
> class(y) <- "lm" # 騙す(線形回帰オブジェクトにする)
> class(y) # 騙された
[1] "lm"
> print(y) # 無意味な出力(しかしエラーにな...
Call:
NULL
No coefficients
**COLOR(magenta){SIZE(16){S3クラスの整合性チェック機能}} ...
S3クラスにも多少のCOLOR(blue){整合性チェック機能}がある。...
***COLOR(magenta){SIZE(16){例:S3クラスの強制変換。行列ク...
> x <- matrix(1:4, 2, 2)
> class(x)
[1] "matrix" # 行列クラス
> class(x) <- "numeric" # 騙す(困った挙げ句に白旗)
警告メッセージ: 強制変換により NA が生成されました
# 文字列クラスを行列クラスに変更
> y <- "matrix"
> class(x)
[1] "character" # 文字列クラス
> class(y) <- "matrix" # 騙す(さすがに苦情)
エラー:次元属性が長さ 2 でないかぎり(0 でした)、
行列にクラスを設定するのは不正です
*COLOR(magenta){SIZE(18){R の S4 クラス}} [#h39bd201]
S4 クラスの定義には、それが含むべきデータであるCOLOR(blue...
新しいクラスは COLOR(red){setClass} 関数で定義する。名前...
***COLOR(magenta){SIZE(16){例:名前付きスロット id (文字...
> setClass("numWithId", representation(id = "character"),
contains = "numeric")
[1] "numWithId"
> isClass("numWithId" # クラスかどうか検査。isClass(num...
[1] TRUE
> getClass("numWithId") # クラス定義を見る
Slots:
Name: .Data id # 名前無しスロットは...
Class: numeric character
Extends:
Class "numeric", from data part
Class "vector", by class "numeric"
***COLOR(magenta){SIZE(16){例:クラス "numWithId" のオブ...
# e <- new("numWithId", id = "3 random numbers", runif(3...
> ( e <- new("numWithId", runif(3), id = "3 random numbe...
An object of class "numWithId"
[1] 0.8540727 0.1615458 0.8514492 # 名前無し数値スロット
Slot "id": # 名前付き文字列スロ...
[1] "3 random random numbers"
# クラス定義は既定でパッケージ(環境) 「.GlobalEnv」 に登...
# 名前なしスロットは隠し名「.Data」を持つ
> str(e)
Formal class 'numWithId' [package ".GlobalEnv"] with 2 s...
..@ .Data: num [1:3] 0.854 0.162 0.851
..@ id : chr "3 random numbers"
***COLOR(magenta){SIZE(16){例: 二つの名前付きスロットを持...
> setClass("numWithId2", representation(id="character", ...
[1] "numWithId2"
> e2 <- new("numWithId2", id="3 sequence", num=1:3)
> e2
An object of class "numWithId2"
Slot "id": # 名前付き文字列スロット
[1] "3 sequence"
Slot "num": # 名前付き数値スロット
[1] 1 2 3
> str(e2)
Formal class 'numWithId2' [package ".GlobalEnv"] with 2 ...
..@ id : chr "3 sequence"
..@ num: int [1:3] 1 2 3
**COLOR(magenta){SIZE(16){スロットの中身を抜き出す}} [#qd...
名前付きスロットの中身を抜き出すには「COLOR(red){@ 演算子...
COLOR(red){e @ .Data}, COLOR(red){e @ ".Data"}, COLOR(red...
等とする。
***COLOR(magenta){SIZE(16){例: スロットの中身を取り出す}}...
> e2 @ id # id スロットの中身を取り...
[1] "3 sequence"
> e2 @ num # num スロットの中身を取り...
[1] 1 2 3
> slot(e2, "id") # 専用 slot 関数もある (slot(e2, id) ...
[1] "3 sequence"
**COLOR(magenta){SIZE(16){スロットへの付値}} [#tb45a3bd]
スロットには適正なオブジェクトを付値できる。不適正な値で...
***COLOR(magenta){SIZE(16){例: スロットへの代入}} [#ua0c7...
> ( e2@num <- rnorm(4) )
[1] -0.37293172 0.08139447 1.77335648 -0.54012836
# 数値スロットに行列を代入しようとする
> ( e2 <- new("numWithId", id="3 sequence", num=matrix(1...
以下にエラー validObject(.Object) : invalid class "numWi...
invalid object for slot "num" in class "numWithId":
got class "matrix", should be or extend class "numeric"
***COLOR(magenta){SIZE(16){例: 行列クラスをスロットに持つ...
> setClass("matWithId3", representation(id="character", ...
[1] "matWithId3"
> ( e3 <- new("matWithId3", id="2x2 matrix", mat=matrix(...
An object of class "matWithId3"
Slot "id":
[1] "2x2 matrix"
Slot "mat":
[,1] [,2]
[1,] 1 3
[2,] 2 4
> e3@"mat"' # スロット mat の中身。slot(e3, "mat") ...
[,1] [,2]
[1,] 1 3
[2,] 2 4
> e3@mat[1,2] # 当然行列操作が可能
[1] 3
***COLOR(magenta){SIZE(16){例: 指定されたクラス以外のクラ...
> setClass("numWithId", representation(id = "character")...
[1] "numWithId"
> setClass("bar", representation(id = "character"), cont...
[1] "bar"
> ebar <- new("bar", id = "abc", "def") # クラス "bar" ...
> e <- new("numWithId", id = "abc", ebar) # 名前無しス...
Warning message:
強制変換により NA が生成されました # エラーにはならない...
**COLOR(magenta){SIZE(16){クラスの拡張}} [#ueebc51b]
「COLOR(red){contains 欄}」を用いて既にあるクラスをCOLOR(...
拡張されたクラスは「COLOR(blue){下位クラス(sub-class)}」...
***COLOR(magenta){SIZE(16){例: 数値クラスを拡張するクラス...
> setClass("numWithId4", representation(id = "character"...
[1] "numWithId4"
> e4 <- new("numWithId4", id="3 numbers", 1:3)
# 結果は単に擬似(名無し)スロットが加わるだけ
> str(e4)
Formal class 'numWithId4' [package ".GlobalEnv"] with 2 ...
..@ .Data: int [1:3] 1 2 3
..@ id : chr "3 numbers"
***COLOR(magenta){SIZE(16){例: もう少しややこしい例}} [#r...
> setClass("numWithId", representation(id = "character")...
[1] "numWithId"
## クラス "numWithId" を名前つきスロットと名前無しスロッ...
## 最初は失敗(スロット名 id が同じためらしい)
> setClass("foo", representation(id = "numWithId"), cont...
以下にエラー.validExtends(class1, class2, classDef, clas...
class "foo" cannot extend class "numWithId": slot...
extend corresponding slots in class "numWithId": ...
以下にエラーsetClass("foo", representation(id = "numWith...
error in contained classes ("numWithId") for clas...
class definition removed from '.GlobalEnv'
## スロット名を idd に変えると成功
> setClass("foo", representation(idd = "numWithId"), con...
[1] "foo"
> e1 <- new("numWithId", id = "3 random numbers", runif(...
> e2 <- new("numWithId", id = "4 random numbers", runif(...
> efoo <- new("foo", idd = e1, e2) # クラス "foo" のオブ...
> str(efoo) # オブジェクトの内容を見る(結構ややこしい...
Formal class 'foo' [package ".GlobalEnv"] with 3 slots
..@ .Data: num [1:4] 0.5930 0.0884 0.2011 0.7343
(# これは名前無しスロットの名前無しスロットの中身)
..@ idd :Formal class 'numWithId' [package ".GlobalEn...
.. .. ..@ .Data: num [1:3] 0.4524 0.0967 0.4248
(# これは名前 idd 付きスロットの名前無しスロットの...
.. .. ..@ id : chr "3 random numbers"
(# これは名前 idd 付きスロットの名前 id 付きスロッ...
..@ id : chr "4 random numbers"
(# これは名前無しスロットの名前 id 付きスロットの...
## 以下順に中身を取り出す
> efoo @ idd # 名前 idd 付きスロットの中身ークラス "n...
An object of class "numWithId"
[1] 0.5805303 0.8349548 0.9335655
Slot "id":
[1] "3 random numbers"
> (efoo @ idd) @ id # 名前 idd 付きスロットの中...
[1] "3 random numbers"
> (efoo @ idd) @ .Data # 名前 idd 付きスロットの中...
[1] 0.5805303 0.8349548 0.9335655
> efoo @ id # 名前 id 付きスロットの中身
[1] "4 random numbers"
> efoo @ .Data # 名前無しスロットの中身
[1] 0.3309665 0.7076782 0.9590298 0.7051191
以上の例からわかるように efoo の構造は一見
efoo ---> 名前付きスロット idd ---> 名前付きスロット id
| |
| ---> 名前無しスロット .Data
---> 名前無しスロット .Data ---> 名前付きスロット id
|
---> 名前無しスロット ....
となるように思われるが、実際は次のようになっている
efoo ---> 名前付きスロット idd ---> 名前付きスロット id
| |
| ---> 名前無しスロット .Data
---> 名前無しスロット .Data
|
---> 名前付きスロット id
**COLOR(magenta){SIZE(16){プロトタイプ}} [#k1d60876]
スロットにはCOLOR(blue){プロトタイプ(既定値)}を与えること...
***COLOR(magenta){SIZE(16){例: プロトタイプ付きクラス}} [...
> setClass("coord", representation(x="numeric", y="numer...
prototype = list(x=0, y=0) )
[1] "coord"
> new("coord")
An object of class "coord"
Slot "x": # プロトタイプ値が入っている
[1] 0
Slot "y":
[1] 0
> new("coord", x=1, y=1) # スロット変数に値を指定
An object of class "coord"
Slot "x": # 指定した値が入っている
[1] 1
Slot "y":
[1] 1
**COLOR(magenta){SIZE(16){クラスの継承}} [#l35188bb]
クラス定義は既存クラスをその一部として含むことができる(CO...
***COLOR(magenta){SIZE(16){例: クラスの継承、拡張}} [#y3a...
> setClass("coord", representation(x="numeric", y="numer...
prototype = list(x=0, y=0))
[1] "coord"
> ( c1 <- new("coord", x=1, y=1) )
An object of class "coord"
Slot "x":
[1] 1
Slot "y":
[1] 1
# "coord" を継承するクラス "coord2"
> setClass("coord2", representation(z="numeric", y="nume...
prototype = list(z=0), contains="coord")
[1] "coord2"
> ( c2 <- new("coord2", z=1, c1) )
An object of class "coord2" # 三つのスロットを...
Slot "z":
[1] 1
Slot "y":
[1] 1
Slot "x":
[1] 1
# 下位クラスに上位クラスとおなじ名前のスロットがあると、...
> setClass("coord3", representation(x="numeric"),
prototype = list(x=0), contains="coord")
[1] "coord3"
> new("coord3", x=2, c1)
An object of class "coord3"
Slot "x":
[1] 2
Slot "y":
[1] 1
***COLOR(magenta){SIZE(16){例: 基本データ型 matrix を拡張...
> setClass("foo", representation(x="numeric"), contains=...
[1] "foo"
> new("foo", x=1, matrix(1:4,2,2))
An object of class "foo"
[,1] [,2]
[1,] 1 3
[2,] 2 4
Slot "x":
[1] 1
**COLOR(magenta){SIZE(16){クラス定義の封印}} [#z8c82597]
クラス定義は改変できないようにCOLOR(blue){封印(seal)}でき...
***COLOR(magenta){SIZE(16){例: クラス定義の封印}} [#xcdc0...
> setClass("3coord", representation(x="numeric",y="numer...
[1] "3coord"
# 定義を書き換えるのは自由
> setClass("3coord", representation(x="numeric",y="numer...
[1] "3coord"
> sealClass("3coord", where=.GlobalEnv) # 定義を封印
## 書き換えようとするとエラーになる(封印を解除するのは?...
> setClass("3coord", representation(x="numeric",y="numer...
以下にエラー setClass("3coord", representation(x = "nume...
"3coord" has a sealed class definition and cannot b...
# 定義済みクラスの一覧
> ls() # ls ではオブジェクトのみ...
[1] "e" "e1" "e3" "e4" ...
[6] "e55" "last.warning"
> getClasses(.GlobalEnv) # .GlobalEnv 中のクラス一覧
[1] "3coord" "coord" "coord2" "matWithId" "num...
*COLOR(magenta){SIZE(18){R の S4 メソッド}} [#h04e5680]
S4 クラスに対する操作関数は、COLOR(blue){総称的(generic)...
***COLOR(magenta){SIZE(16){例: クラスに対するメソッドの定...
> setClass("track", representation(x="numeric", y="numer...
[1] "track"
> isGeneric("Arith") # (組み込みの)算術演算総称的関数(...
[1] TRUE
# クラスと数値の算術演算メソッドの定義
> setMethod("Arith", c("track", "numeric"),
function(e1, e2) {e1@y <- callGeneric(e1@y...
[1] "Arith"
# 数値とクラスの算術演算のメソッド定義
> setMethod("Arith", c("numeric", "track"),
function(e1, e2) {e2@y <- callGeneric(e1, ...
[1] "Arith"
# 算術演算全てにメソッドが同時に定義されている
> t1 <- new("track", x=1:4, y=sort(rnorm(4)))
> t1 - 100 # 第一のメソッド(引き算)適用
An object of class "track"
Slot "x":
[1] 1 2 3 4
Slot "y":
[1] -101.36265 -101.00339 -100.81776 -100.71723
> 100 - t1 # 第二のメソッド(引き算)適用
An object of class "track"
Slot "x":
[1] 1 2 3 4
Slot "y":
[1] 101.36265 101.00339 100.81776 100.71723
> 1/t1 # 第二のメソッド(割算)適用
An object of class "track"
Slot "x":
[1] 1 2 3 4
Slot "y":
[1] -0.7338617 -0.9966217 -1.2228547 -1.3942441
# クラス同士の算術演算のメソッドの定義
setMethod("Arith", c("track", "track"),
function(e1, e2) {
e1@x <- callGeneric(e1@x , e2@x);
e1@y <- callGeneric(e1@y , e2@y);
e1
})
> t1 <- new("track", x=1:4, y=rnorm(4))
> t2 <- new("track", x=rep(2,4), y=runif(4))
> t1 + t2
An object of class "track"
Slot "x":
[1] 3 4 5 6
Slot "y":
[1] 0.9274807 1.2821877 -0.3399180 1.7301085
***COLOR(magenta){SIZE(16){例: 総称的関数 plotData の定義...
> plotData <- function(x, y, ...) plot(x, y, ...)
> setGeneric("plotData") # "plotData" は総称的関数と宣言
[1] "plotData"
# そのメソッドの定義(第二引数は無いと宣言)
> setMethod("plotData", signature(x = "track", y = "miss...
function(x, y, ...) plot(slot(x, "x"), slot(...
[1] "plotData"
> plotData(t1)
> removeGeneric("plotData") # 総称的関数で無くする
[1] TRUE
***COLOR(magenta){SIZE(16){例: 総称的関数のメソッドの定義...
# 行列一つをスロットに持つクラス "foo" の定義
> setClass("foo", representation(m = "matrix"))
[1] "foo"
> m1 <- matrix(1:12, 3, 4)
> f1 = new("foo", m = m1)
> f2 = new("foo", m = t(m1))
# 二つのクラス "foo" 引数を持つ総称的関数のメソッドを定義
> setMethod("%*%", c("foo", "foo"), function(x, y) callG...
[1] "%*%"
> stopifnot(identical(f1 %*% f2, m1 %*% t(m1))) # 検査
> removeMethods("%*%") # メソッ...
[1] TRUE
***COLOR(magenta){SIZE(16){例: 特殊関数 "[" のメソッド定...
> setMethod("[", "track", function(x, i, j, ..., drop) {
x@x <- x@x[i]
x@y <- x@y[i]
x
})
[1] "["
> plot(t1[1:15])
***COLOR(magenta){SIZE(16){例: S4 クラスを引数に取る普通...
> setClass("numWithId", representation(id = "character")...
[1] "numWithId"
> e <- new("numWithId", id = "abc", runif(3))
> foo <- function (x) x@id # "唯の" 関数
> foo(e)
[1] "abc"
> foo2 <- function (x) x@.Data[3] # "唯の" 関数その2
> foo2(e)
[1] 0.2612681
*COLOR(magenta){SIZE(16){メソッドとクラスのドキュメント}}...
S4 クラスとメソッドには該当するドキュメント(もし作者がそ...
***COLOR(magenta){SIZE(16){例: クラス・メソッドのドキュメ...
# クラス "genericFunction" に対するドキュメントを得る
> class ? genericFunction
# initialize 関数に対するメソッドのドキュメントを得る
> methods ? initialize
# 関数呼び出し myFun(x, sqrt(wt)) を評価する際、この呼び...
# メソッドに関する何らかのドキュメントを得る。呼び出し自...
# 選択され、そのメソッドに対するドキュメントが得られる
> ?myFun(x, sqrt(wt))
# 第一引数がクラス maybeNumber、第二引数が logical であ...
# 指定されたクラスに対応する一つのメソッドが選択され、そ...
> method ? myFun("maybeNumber", "logical")
# 特定の総称関数に対して定義されたメソッド用のドキュメン...
# ファイル 'myFun-methods.Rd' を作り出す
> promptMethods("myFun")
# このファイルを編集した上、参照するには次のようにする
> methods ? myFun
*COLOR(magenta){SIZE(16){パッケージ methods 内のオブジェ...
以下は library(help=methods) で得られる R (2.1.1) の基本...
一覧である。
.BasicFunsList 組み込み・特殊関数のリスト
Classes クラス定義解説
Documentation クラスとメソッドのオンラインド...
GenericFunctions 総称的関数操作用ツール
LinearMethodsList-class クラス "LinearMethodsList"
MethodDefinition-class メソッド定義を表現するクラス
MethodWithNext-class クラス MethodWithNext
Methods メソッドの一般情報
MethodsList-class クラス Class MethodsList、総称...
ObjectsWithPackage-class 関連パッケージ名を持つ、ブジェ...
SClassExtension-class 継承(拡張)関係を表すクラス
as オブジェクトがあるクラスに属す...
callNextMethod 継承メソッドを呼び出す
character-class 基本データ型に対応するクラス
classRepresentation-class クラスオブジェクト
environment-class クラス "environment"
fixPre1.8 バージョン 1.8 以前の R からセ...
genericFunction-class 総称的関数オブジェクト
getClass クラス定義を得る
getMethod メソッド定義を得る、検査する
getPackageName 与えられたパッケージに伴う名前
hasArg 呼出し中の引数を見る
initialize-methods あるクラスからの新しいオブジェ...
is あるクラスからのオブジェクトか?
isSealedMethod 封印されたメソッド・クラスに対...
language-class 未評価の言語オブジェクトを表現...
makeClassRepresentation クラス定義を生成する
new あるクラスからオブジェクトを生...
promptClass 形式的クラスのドキュメントに対...
promptMethods 形式的メソッドのドキュメントに...
representation クラス定義に対するプロトタイプ...
setClass クラス定義を作成
setClassUnion 他のクラスの合併として定義され...
setGeneric 新しい総称的関数を定義
setMethod メソッドを作成、保管
setOldClass 古いスタイルに対する名前を指定
show オブジェクトを示す
showMethods 指定された関数に対する全てのメ...
signature-class メソッド定義に対する "signature...
slot 形式的クラスからのオブジェクト...
structure-class 基本構造に対するクラス
traceable-class トレースを制御するために内部的...
validObject オブジェクトの正統性を検査
//The object paradigm in R is different; I like to think ...
//orthogonal to classes, instead of nested within them.
//
//Probably what you want to try is
//
//# a generic function, to operate on different classes
//setGeneric("test", function( obj ) standardGeneric( "te...
//
//# a class, containing data
//setClass("connect", representation( value = "numeric" ))
//
//# a specific method, operating on "connect" objects
//setMethod("test", signature=c("connect"),
// function( obj ) { obj@value / 2 })
//
//# a new object of class "connect" with value slot assig...
//testObj <- new("connect", value=44 )
//# application of the generic function to an object of c...
//# dispatched to the method operating on objects of clas...
//test( testObj )
//
//This kind of structuure makes some types of operations ...
//natural in R -- dispatch on multiple arguments, for ins...
終了行:
COLOR(magenta){SIZE(18){R の S4 クラス、メソッド入門}} C...
//COLOR(red){SIZE(18){只今作業中!}}~
以下では、R のクラスとメソッドについて簡単に説明する。R ...
COLOR(blue){クラス(class)}とはある構造を持つデータの集ま...
S 言語第四版に関する原典は [[データによるプログラミング:h...
//しばらくの間修正・追加等はコメント経由でお願いします。
-例えば、e1071パッケージにあるsvmのオンラインヘルプ中のS3...
#comment
~
~
COLOR(blue){SIZE(20){目次}}
#contents
~
~
*COLOR(magenta){SIZE(18){R の S3 クラスとメソッド}} [#ife...
**COLOR(magenta){SIZE(16){S3クラスは本質的にオブジェクト...
S3クラスは本質的にオブジェクトのCOLOR(blue){クラス属性(cl...
***COLOR(magenta){SIZE(16){例: S3 クラス、総称的関数、メ...
> x <- lm(1:10~rnorm(10)) # 簡単な単回帰。クラス属性 ...
> class(x) # クラス属性
[1] "lm"
> summary(x) # 総称的関数 summary の適用。実際はメソッ...
Call:
lm(formula = 1:10 ~ rnorm(10))
Residuals:
Min 1Q Median 3Q Max
-4.3527 -2.2764 0.1823 2.4843 4.5825
(...以下略...)
**COLOR(magenta){SIZE(16){S3メソッドの仕組み}} [#kc7dfc58]
総称的関数はクラス属性文字列(だけ?)を頼りに、適当なメソッ...
***COLOR(magenta){SIZE(16){例:総称的関数 plot の(S3)メソ...
> methods(plot)
[1] plot.Date* plot.HoltWinters* plot.POSIXct*
[4] plot.POSIXlt* plot.TukeyHSD plot.acf*
.........................................................
[31] plot.ts plot.tskernel*
Non-visible functions are asterisked
**COLOR(magenta){SIZE(16){S3クラスの「いい加減さ」}} [#k3...
S3 クラス属性は「勝手に」与えることができる。
***COLOR(magenta){SIZE(16){例: S3 クラス属性は「勝手に」...
> y <- runif(10)
> class(y) <- "lm" # 騙す(線形回帰オブジェクトにする)
> class(y) # 騙された
[1] "lm"
> print(y) # 無意味な出力(しかしエラーにな...
Call:
NULL
No coefficients
**COLOR(magenta){SIZE(16){S3クラスの整合性チェック機能}} ...
S3クラスにも多少のCOLOR(blue){整合性チェック機能}がある。...
***COLOR(magenta){SIZE(16){例:S3クラスの強制変換。行列ク...
> x <- matrix(1:4, 2, 2)
> class(x)
[1] "matrix" # 行列クラス
> class(x) <- "numeric" # 騙す(困った挙げ句に白旗)
警告メッセージ: 強制変換により NA が生成されました
# 文字列クラスを行列クラスに変更
> y <- "matrix"
> class(x)
[1] "character" # 文字列クラス
> class(y) <- "matrix" # 騙す(さすがに苦情)
エラー:次元属性が長さ 2 でないかぎり(0 でした)、
行列にクラスを設定するのは不正です
*COLOR(magenta){SIZE(18){R の S4 クラス}} [#h39bd201]
S4 クラスの定義には、それが含むべきデータであるCOLOR(blue...
新しいクラスは COLOR(red){setClass} 関数で定義する。名前...
***COLOR(magenta){SIZE(16){例:名前付きスロット id (文字...
> setClass("numWithId", representation(id = "character"),
contains = "numeric")
[1] "numWithId"
> isClass("numWithId" # クラスかどうか検査。isClass(num...
[1] TRUE
> getClass("numWithId") # クラス定義を見る
Slots:
Name: .Data id # 名前無しスロットは...
Class: numeric character
Extends:
Class "numeric", from data part
Class "vector", by class "numeric"
***COLOR(magenta){SIZE(16){例:クラス "numWithId" のオブ...
# e <- new("numWithId", id = "3 random numbers", runif(3...
> ( e <- new("numWithId", runif(3), id = "3 random numbe...
An object of class "numWithId"
[1] 0.8540727 0.1615458 0.8514492 # 名前無し数値スロット
Slot "id": # 名前付き文字列スロ...
[1] "3 random random numbers"
# クラス定義は既定でパッケージ(環境) 「.GlobalEnv」 に登...
# 名前なしスロットは隠し名「.Data」を持つ
> str(e)
Formal class 'numWithId' [package ".GlobalEnv"] with 2 s...
..@ .Data: num [1:3] 0.854 0.162 0.851
..@ id : chr "3 random numbers"
***COLOR(magenta){SIZE(16){例: 二つの名前付きスロットを持...
> setClass("numWithId2", representation(id="character", ...
[1] "numWithId2"
> e2 <- new("numWithId2", id="3 sequence", num=1:3)
> e2
An object of class "numWithId2"
Slot "id": # 名前付き文字列スロット
[1] "3 sequence"
Slot "num": # 名前付き数値スロット
[1] 1 2 3
> str(e2)
Formal class 'numWithId2' [package ".GlobalEnv"] with 2 ...
..@ id : chr "3 sequence"
..@ num: int [1:3] 1 2 3
**COLOR(magenta){SIZE(16){スロットの中身を抜き出す}} [#qd...
名前付きスロットの中身を抜き出すには「COLOR(red){@ 演算子...
COLOR(red){e @ .Data}, COLOR(red){e @ ".Data"}, COLOR(red...
等とする。
***COLOR(magenta){SIZE(16){例: スロットの中身を取り出す}}...
> e2 @ id # id スロットの中身を取り...
[1] "3 sequence"
> e2 @ num # num スロットの中身を取り...
[1] 1 2 3
> slot(e2, "id") # 専用 slot 関数もある (slot(e2, id) ...
[1] "3 sequence"
**COLOR(magenta){SIZE(16){スロットへの付値}} [#tb45a3bd]
スロットには適正なオブジェクトを付値できる。不適正な値で...
***COLOR(magenta){SIZE(16){例: スロットへの代入}} [#ua0c7...
> ( e2@num <- rnorm(4) )
[1] -0.37293172 0.08139447 1.77335648 -0.54012836
# 数値スロットに行列を代入しようとする
> ( e2 <- new("numWithId", id="3 sequence", num=matrix(1...
以下にエラー validObject(.Object) : invalid class "numWi...
invalid object for slot "num" in class "numWithId":
got class "matrix", should be or extend class "numeric"
***COLOR(magenta){SIZE(16){例: 行列クラスをスロットに持つ...
> setClass("matWithId3", representation(id="character", ...
[1] "matWithId3"
> ( e3 <- new("matWithId3", id="2x2 matrix", mat=matrix(...
An object of class "matWithId3"
Slot "id":
[1] "2x2 matrix"
Slot "mat":
[,1] [,2]
[1,] 1 3
[2,] 2 4
> e3@"mat"' # スロット mat の中身。slot(e3, "mat") ...
[,1] [,2]
[1,] 1 3
[2,] 2 4
> e3@mat[1,2] # 当然行列操作が可能
[1] 3
***COLOR(magenta){SIZE(16){例: 指定されたクラス以外のクラ...
> setClass("numWithId", representation(id = "character")...
[1] "numWithId"
> setClass("bar", representation(id = "character"), cont...
[1] "bar"
> ebar <- new("bar", id = "abc", "def") # クラス "bar" ...
> e <- new("numWithId", id = "abc", ebar) # 名前無しス...
Warning message:
強制変換により NA が生成されました # エラーにはならない...
**COLOR(magenta){SIZE(16){クラスの拡張}} [#ueebc51b]
「COLOR(red){contains 欄}」を用いて既にあるクラスをCOLOR(...
拡張されたクラスは「COLOR(blue){下位クラス(sub-class)}」...
***COLOR(magenta){SIZE(16){例: 数値クラスを拡張するクラス...
> setClass("numWithId4", representation(id = "character"...
[1] "numWithId4"
> e4 <- new("numWithId4", id="3 numbers", 1:3)
# 結果は単に擬似(名無し)スロットが加わるだけ
> str(e4)
Formal class 'numWithId4' [package ".GlobalEnv"] with 2 ...
..@ .Data: int [1:3] 1 2 3
..@ id : chr "3 numbers"
***COLOR(magenta){SIZE(16){例: もう少しややこしい例}} [#r...
> setClass("numWithId", representation(id = "character")...
[1] "numWithId"
## クラス "numWithId" を名前つきスロットと名前無しスロッ...
## 最初は失敗(スロット名 id が同じためらしい)
> setClass("foo", representation(id = "numWithId"), cont...
以下にエラー.validExtends(class1, class2, classDef, clas...
class "foo" cannot extend class "numWithId": slot...
extend corresponding slots in class "numWithId": ...
以下にエラーsetClass("foo", representation(id = "numWith...
error in contained classes ("numWithId") for clas...
class definition removed from '.GlobalEnv'
## スロット名を idd に変えると成功
> setClass("foo", representation(idd = "numWithId"), con...
[1] "foo"
> e1 <- new("numWithId", id = "3 random numbers", runif(...
> e2 <- new("numWithId", id = "4 random numbers", runif(...
> efoo <- new("foo", idd = e1, e2) # クラス "foo" のオブ...
> str(efoo) # オブジェクトの内容を見る(結構ややこしい...
Formal class 'foo' [package ".GlobalEnv"] with 3 slots
..@ .Data: num [1:4] 0.5930 0.0884 0.2011 0.7343
(# これは名前無しスロットの名前無しスロットの中身)
..@ idd :Formal class 'numWithId' [package ".GlobalEn...
.. .. ..@ .Data: num [1:3] 0.4524 0.0967 0.4248
(# これは名前 idd 付きスロットの名前無しスロットの...
.. .. ..@ id : chr "3 random numbers"
(# これは名前 idd 付きスロットの名前 id 付きスロッ...
..@ id : chr "4 random numbers"
(# これは名前無しスロットの名前 id 付きスロットの...
## 以下順に中身を取り出す
> efoo @ idd # 名前 idd 付きスロットの中身ークラス "n...
An object of class "numWithId"
[1] 0.5805303 0.8349548 0.9335655
Slot "id":
[1] "3 random numbers"
> (efoo @ idd) @ id # 名前 idd 付きスロットの中...
[1] "3 random numbers"
> (efoo @ idd) @ .Data # 名前 idd 付きスロットの中...
[1] 0.5805303 0.8349548 0.9335655
> efoo @ id # 名前 id 付きスロットの中身
[1] "4 random numbers"
> efoo @ .Data # 名前無しスロットの中身
[1] 0.3309665 0.7076782 0.9590298 0.7051191
以上の例からわかるように efoo の構造は一見
efoo ---> 名前付きスロット idd ---> 名前付きスロット id
| |
| ---> 名前無しスロット .Data
---> 名前無しスロット .Data ---> 名前付きスロット id
|
---> 名前無しスロット ....
となるように思われるが、実際は次のようになっている
efoo ---> 名前付きスロット idd ---> 名前付きスロット id
| |
| ---> 名前無しスロット .Data
---> 名前無しスロット .Data
|
---> 名前付きスロット id
**COLOR(magenta){SIZE(16){プロトタイプ}} [#k1d60876]
スロットにはCOLOR(blue){プロトタイプ(既定値)}を与えること...
***COLOR(magenta){SIZE(16){例: プロトタイプ付きクラス}} [...
> setClass("coord", representation(x="numeric", y="numer...
prototype = list(x=0, y=0) )
[1] "coord"
> new("coord")
An object of class "coord"
Slot "x": # プロトタイプ値が入っている
[1] 0
Slot "y":
[1] 0
> new("coord", x=1, y=1) # スロット変数に値を指定
An object of class "coord"
Slot "x": # 指定した値が入っている
[1] 1
Slot "y":
[1] 1
**COLOR(magenta){SIZE(16){クラスの継承}} [#l35188bb]
クラス定義は既存クラスをその一部として含むことができる(CO...
***COLOR(magenta){SIZE(16){例: クラスの継承、拡張}} [#y3a...
> setClass("coord", representation(x="numeric", y="numer...
prototype = list(x=0, y=0))
[1] "coord"
> ( c1 <- new("coord", x=1, y=1) )
An object of class "coord"
Slot "x":
[1] 1
Slot "y":
[1] 1
# "coord" を継承するクラス "coord2"
> setClass("coord2", representation(z="numeric", y="nume...
prototype = list(z=0), contains="coord")
[1] "coord2"
> ( c2 <- new("coord2", z=1, c1) )
An object of class "coord2" # 三つのスロットを...
Slot "z":
[1] 1
Slot "y":
[1] 1
Slot "x":
[1] 1
# 下位クラスに上位クラスとおなじ名前のスロットがあると、...
> setClass("coord3", representation(x="numeric"),
prototype = list(x=0), contains="coord")
[1] "coord3"
> new("coord3", x=2, c1)
An object of class "coord3"
Slot "x":
[1] 2
Slot "y":
[1] 1
***COLOR(magenta){SIZE(16){例: 基本データ型 matrix を拡張...
> setClass("foo", representation(x="numeric"), contains=...
[1] "foo"
> new("foo", x=1, matrix(1:4,2,2))
An object of class "foo"
[,1] [,2]
[1,] 1 3
[2,] 2 4
Slot "x":
[1] 1
**COLOR(magenta){SIZE(16){クラス定義の封印}} [#z8c82597]
クラス定義は改変できないようにCOLOR(blue){封印(seal)}でき...
***COLOR(magenta){SIZE(16){例: クラス定義の封印}} [#xcdc0...
> setClass("3coord", representation(x="numeric",y="numer...
[1] "3coord"
# 定義を書き換えるのは自由
> setClass("3coord", representation(x="numeric",y="numer...
[1] "3coord"
> sealClass("3coord", where=.GlobalEnv) # 定義を封印
## 書き換えようとするとエラーになる(封印を解除するのは?...
> setClass("3coord", representation(x="numeric",y="numer...
以下にエラー setClass("3coord", representation(x = "nume...
"3coord" has a sealed class definition and cannot b...
# 定義済みクラスの一覧
> ls() # ls ではオブジェクトのみ...
[1] "e" "e1" "e3" "e4" ...
[6] "e55" "last.warning"
> getClasses(.GlobalEnv) # .GlobalEnv 中のクラス一覧
[1] "3coord" "coord" "coord2" "matWithId" "num...
*COLOR(magenta){SIZE(18){R の S4 メソッド}} [#h04e5680]
S4 クラスに対する操作関数は、COLOR(blue){総称的(generic)...
***COLOR(magenta){SIZE(16){例: クラスに対するメソッドの定...
> setClass("track", representation(x="numeric", y="numer...
[1] "track"
> isGeneric("Arith") # (組み込みの)算術演算総称的関数(...
[1] TRUE
# クラスと数値の算術演算メソッドの定義
> setMethod("Arith", c("track", "numeric"),
function(e1, e2) {e1@y <- callGeneric(e1@y...
[1] "Arith"
# 数値とクラスの算術演算のメソッド定義
> setMethod("Arith", c("numeric", "track"),
function(e1, e2) {e2@y <- callGeneric(e1, ...
[1] "Arith"
# 算術演算全てにメソッドが同時に定義されている
> t1 <- new("track", x=1:4, y=sort(rnorm(4)))
> t1 - 100 # 第一のメソッド(引き算)適用
An object of class "track"
Slot "x":
[1] 1 2 3 4
Slot "y":
[1] -101.36265 -101.00339 -100.81776 -100.71723
> 100 - t1 # 第二のメソッド(引き算)適用
An object of class "track"
Slot "x":
[1] 1 2 3 4
Slot "y":
[1] 101.36265 101.00339 100.81776 100.71723
> 1/t1 # 第二のメソッド(割算)適用
An object of class "track"
Slot "x":
[1] 1 2 3 4
Slot "y":
[1] -0.7338617 -0.9966217 -1.2228547 -1.3942441
# クラス同士の算術演算のメソッドの定義
setMethod("Arith", c("track", "track"),
function(e1, e2) {
e1@x <- callGeneric(e1@x , e2@x);
e1@y <- callGeneric(e1@y , e2@y);
e1
})
> t1 <- new("track", x=1:4, y=rnorm(4))
> t2 <- new("track", x=rep(2,4), y=runif(4))
> t1 + t2
An object of class "track"
Slot "x":
[1] 3 4 5 6
Slot "y":
[1] 0.9274807 1.2821877 -0.3399180 1.7301085
***COLOR(magenta){SIZE(16){例: 総称的関数 plotData の定義...
> plotData <- function(x, y, ...) plot(x, y, ...)
> setGeneric("plotData") # "plotData" は総称的関数と宣言
[1] "plotData"
# そのメソッドの定義(第二引数は無いと宣言)
> setMethod("plotData", signature(x = "track", y = "miss...
function(x, y, ...) plot(slot(x, "x"), slot(...
[1] "plotData"
> plotData(t1)
> removeGeneric("plotData") # 総称的関数で無くする
[1] TRUE
***COLOR(magenta){SIZE(16){例: 総称的関数のメソッドの定義...
# 行列一つをスロットに持つクラス "foo" の定義
> setClass("foo", representation(m = "matrix"))
[1] "foo"
> m1 <- matrix(1:12, 3, 4)
> f1 = new("foo", m = m1)
> f2 = new("foo", m = t(m1))
# 二つのクラス "foo" 引数を持つ総称的関数のメソッドを定義
> setMethod("%*%", c("foo", "foo"), function(x, y) callG...
[1] "%*%"
> stopifnot(identical(f1 %*% f2, m1 %*% t(m1))) # 検査
> removeMethods("%*%") # メソッ...
[1] TRUE
***COLOR(magenta){SIZE(16){例: 特殊関数 "[" のメソッド定...
> setMethod("[", "track", function(x, i, j, ..., drop) {
x@x <- x@x[i]
x@y <- x@y[i]
x
})
[1] "["
> plot(t1[1:15])
***COLOR(magenta){SIZE(16){例: S4 クラスを引数に取る普通...
> setClass("numWithId", representation(id = "character")...
[1] "numWithId"
> e <- new("numWithId", id = "abc", runif(3))
> foo <- function (x) x@id # "唯の" 関数
> foo(e)
[1] "abc"
> foo2 <- function (x) x@.Data[3] # "唯の" 関数その2
> foo2(e)
[1] 0.2612681
*COLOR(magenta){SIZE(16){メソッドとクラスのドキュメント}}...
S4 クラスとメソッドには該当するドキュメント(もし作者がそ...
***COLOR(magenta){SIZE(16){例: クラス・メソッドのドキュメ...
# クラス "genericFunction" に対するドキュメントを得る
> class ? genericFunction
# initialize 関数に対するメソッドのドキュメントを得る
> methods ? initialize
# 関数呼び出し myFun(x, sqrt(wt)) を評価する際、この呼び...
# メソッドに関する何らかのドキュメントを得る。呼び出し自...
# 選択され、そのメソッドに対するドキュメントが得られる
> ?myFun(x, sqrt(wt))
# 第一引数がクラス maybeNumber、第二引数が logical であ...
# 指定されたクラスに対応する一つのメソッドが選択され、そ...
> method ? myFun("maybeNumber", "logical")
# 特定の総称関数に対して定義されたメソッド用のドキュメン...
# ファイル 'myFun-methods.Rd' を作り出す
> promptMethods("myFun")
# このファイルを編集した上、参照するには次のようにする
> methods ? myFun
*COLOR(magenta){SIZE(16){パッケージ methods 内のオブジェ...
以下は library(help=methods) で得られる R (2.1.1) の基本...
一覧である。
.BasicFunsList 組み込み・特殊関数のリスト
Classes クラス定義解説
Documentation クラスとメソッドのオンラインド...
GenericFunctions 総称的関数操作用ツール
LinearMethodsList-class クラス "LinearMethodsList"
MethodDefinition-class メソッド定義を表現するクラス
MethodWithNext-class クラス MethodWithNext
Methods メソッドの一般情報
MethodsList-class クラス Class MethodsList、総称...
ObjectsWithPackage-class 関連パッケージ名を持つ、ブジェ...
SClassExtension-class 継承(拡張)関係を表すクラス
as オブジェクトがあるクラスに属す...
callNextMethod 継承メソッドを呼び出す
character-class 基本データ型に対応するクラス
classRepresentation-class クラスオブジェクト
environment-class クラス "environment"
fixPre1.8 バージョン 1.8 以前の R からセ...
genericFunction-class 総称的関数オブジェクト
getClass クラス定義を得る
getMethod メソッド定義を得る、検査する
getPackageName 与えられたパッケージに伴う名前
hasArg 呼出し中の引数を見る
initialize-methods あるクラスからの新しいオブジェ...
is あるクラスからのオブジェクトか?
isSealedMethod 封印されたメソッド・クラスに対...
language-class 未評価の言語オブジェクトを表現...
makeClassRepresentation クラス定義を生成する
new あるクラスからオブジェクトを生...
promptClass 形式的クラスのドキュメントに対...
promptMethods 形式的メソッドのドキュメントに...
representation クラス定義に対するプロトタイプ...
setClass クラス定義を作成
setClassUnion 他のクラスの合併として定義され...
setGeneric 新しい総称的関数を定義
setMethod メソッドを作成、保管
setOldClass 古いスタイルに対する名前を指定
show オブジェクトを示す
showMethods 指定された関数に対する全てのメ...
signature-class メソッド定義に対する "signature...
slot 形式的クラスからのオブジェクト...
structure-class 基本構造に対するクラス
traceable-class トレースを制御するために内部的...
validObject オブジェクトの正統性を検査
//The object paradigm in R is different; I like to think ...
//orthogonal to classes, instead of nested within them.
//
//Probably what you want to try is
//
//# a generic function, to operate on different classes
//setGeneric("test", function( obj ) standardGeneric( "te...
//
//# a class, containing data
//setClass("connect", representation( value = "numeric" ))
//
//# a specific method, operating on "connect" objects
//setMethod("test", signature=c("connect"),
// function( obj ) { obj@value / 2 })
//
//# a new object of class "connect" with value slot assig...
//testObj <- new("connect", value=44 )
//# application of the generic function to an object of c...
//# dispatched to the method operating on objects of clas...
//test( testObj )
//
//This kind of structuure makes some types of operations ...
//natural in R -- dispatch on multiple arguments, for ins...
ページ名: