Submit Search
Upload
R6パッケージの紹介―機能と実装
•
Download as PPTX, PDF
•
16 likes
•
27,689 views
_
__nakamichi__
Follow
R6パッケージの紹介―機能と実装
Read less
Read more
Software
Slideshow view
Report
Share
Slideshow view
Report
Share
1 of 34
Download now
Recommended
東京R非公式おじさんが教える本当に気持ちいいパッケージ作成法
東京R非公式おじさんが教える本当に気持ちいいパッケージ作成法
Nagi Teramo
Visual Studio CodeでRを使う
Visual Studio CodeでRを使う
Atsushi Hayakawa
Rで計量時系列分析~CRANパッケージ総ざらい~
Rで計量時系列分析~CRANパッケージ総ざらい~
Takashi J OZAKI
ようやく分かった!最尤推定とベイズ推定
ようやく分かった!最尤推定とベイズ推定
Akira Masuda
負の二項分布について
負の二項分布について
Hiroshi Shimizu
Rによるやさしい統計学第20章「検定力分析によるサンプルサイズの決定」
Rによるやさしい統計学第20章「検定力分析によるサンプルサイズの決定」
Takashi J OZAKI
【読書会資料】『StanとRでベイズ統計モデリング』Chapter12:時間や空間を扱うモデル
【読書会資料】『StanとRでベイズ統計モデリング』Chapter12:時間や空間を扱うモデル
Masashi Komori
DeepLearning 輪読会 第1章 はじめに
DeepLearning 輪読会 第1章 はじめに
Deep Learning JP
Recommended
東京R非公式おじさんが教える本当に気持ちいいパッケージ作成法
東京R非公式おじさんが教える本当に気持ちいいパッケージ作成法
Nagi Teramo
Visual Studio CodeでRを使う
Visual Studio CodeでRを使う
Atsushi Hayakawa
Rで計量時系列分析~CRANパッケージ総ざらい~
Rで計量時系列分析~CRANパッケージ総ざらい~
Takashi J OZAKI
ようやく分かった!最尤推定とベイズ推定
ようやく分かった!最尤推定とベイズ推定
Akira Masuda
負の二項分布について
負の二項分布について
Hiroshi Shimizu
Rによるやさしい統計学第20章「検定力分析によるサンプルサイズの決定」
Rによるやさしい統計学第20章「検定力分析によるサンプルサイズの決定」
Takashi J OZAKI
【読書会資料】『StanとRでベイズ統計モデリング』Chapter12:時間や空間を扱うモデル
【読書会資料】『StanとRでベイズ統計モデリング』Chapter12:時間や空間を扱うモデル
Masashi Komori
DeepLearning 輪読会 第1章 はじめに
DeepLearning 輪読会 第1章 はじめに
Deep Learning JP
『バックドア基準の入門』@統数研研究集会
『バックドア基準の入門』@統数研研究集会
takehikoihayashi
for関数を使った繰り返し処理によるヒストグラムの一括出力
for関数を使った繰り返し処理によるヒストグラムの一括出力
imuyaoti
MICの解説
MICの解説
logics-of-blue
Rで学ぶロバスト推定
Rで学ぶロバスト推定
Shintaro Fukushima
ベイズ機械学習(an introduction to bayesian machine learning)
ベイズ機械学習(an introduction to bayesian machine learning)
医療IT数学同好会 T/T
不均衡データのクラス分類
不均衡データのクラス分類
Shintaro Fukushima
第4回DARM勉強会 (構造方程式モデリング)
第4回DARM勉強会 (構造方程式モデリング)
Yoshitake Takebayashi
Rによる高速処理 まだfor使ってるの?
Rによる高速処理 まだfor使ってるの?
jundoll
構造方程式モデルによる因果探索と非ガウス性
構造方程式モデルによる因果探索と非ガウス性
Shiga University, RIKEN
ベイズ統計入門
ベイズ統計入門
Miyoshi Yuya
Stan超初心者入門
Stan超初心者入門
Hiroshi Shimizu
DARM勉強会第3回 (missing data analysis)
DARM勉強会第3回 (missing data analysis)
Masaru Tokuoka
指数分布とポアソン分布のいけない関係
指数分布とポアソン分布のいけない関係
Nagi Teramo
【解説】 一般逆行列
【解説】 一般逆行列
Kenjiro Sugimoto
構造方程式モデルによる因果推論: 因果構造探索に関する最近の発展
構造方程式モデルによる因果推論: 因果構造探索に関する最近の発展
Shiga University, RIKEN
数式を綺麗にプログラミングするコツ #spro2013
数式を綺麗にプログラミングするコツ #spro2013
Shuyo Nakatani
MCMCでマルチレベルモデル
MCMCでマルチレベルモデル
Hiroshi Shimizu
ベイズ統計学の概論的紹介
ベイズ統計学の概論的紹介
Naoki Hayashi
CRAN Rパッケージ BNSLの概要
CRAN Rパッケージ BNSLの概要
Joe Suzuki
Rでisomap(多様体学習のはなし)
Rでisomap(多様体学習のはなし)
Kohta Ishikawa
Python におけるドメイン駆動設計(戦術面)の勘どころ
Python におけるドメイン駆動設計(戦術面)の勘どころ
Junya Hayashi
Prophet入門【理論編】Facebookの時系列予測ツール
Prophet入門【理論編】Facebookの時系列予測ツール
hoxo_m
More Related Content
What's hot
『バックドア基準の入門』@統数研研究集会
『バックドア基準の入門』@統数研研究集会
takehikoihayashi
for関数を使った繰り返し処理によるヒストグラムの一括出力
for関数を使った繰り返し処理によるヒストグラムの一括出力
imuyaoti
MICの解説
MICの解説
logics-of-blue
Rで学ぶロバスト推定
Rで学ぶロバスト推定
Shintaro Fukushima
ベイズ機械学習(an introduction to bayesian machine learning)
ベイズ機械学習(an introduction to bayesian machine learning)
医療IT数学同好会 T/T
不均衡データのクラス分類
不均衡データのクラス分類
Shintaro Fukushima
第4回DARM勉強会 (構造方程式モデリング)
第4回DARM勉強会 (構造方程式モデリング)
Yoshitake Takebayashi
Rによる高速処理 まだfor使ってるの?
Rによる高速処理 まだfor使ってるの?
jundoll
構造方程式モデルによる因果探索と非ガウス性
構造方程式モデルによる因果探索と非ガウス性
Shiga University, RIKEN
ベイズ統計入門
ベイズ統計入門
Miyoshi Yuya
Stan超初心者入門
Stan超初心者入門
Hiroshi Shimizu
DARM勉強会第3回 (missing data analysis)
DARM勉強会第3回 (missing data analysis)
Masaru Tokuoka
指数分布とポアソン分布のいけない関係
指数分布とポアソン分布のいけない関係
Nagi Teramo
【解説】 一般逆行列
【解説】 一般逆行列
Kenjiro Sugimoto
構造方程式モデルによる因果推論: 因果構造探索に関する最近の発展
構造方程式モデルによる因果推論: 因果構造探索に関する最近の発展
Shiga University, RIKEN
数式を綺麗にプログラミングするコツ #spro2013
数式を綺麗にプログラミングするコツ #spro2013
Shuyo Nakatani
MCMCでマルチレベルモデル
MCMCでマルチレベルモデル
Hiroshi Shimizu
ベイズ統計学の概論的紹介
ベイズ統計学の概論的紹介
Naoki Hayashi
CRAN Rパッケージ BNSLの概要
CRAN Rパッケージ BNSLの概要
Joe Suzuki
Rでisomap(多様体学習のはなし)
Rでisomap(多様体学習のはなし)
Kohta Ishikawa
What's hot
(20)
『バックドア基準の入門』@統数研研究集会
『バックドア基準の入門』@統数研研究集会
for関数を使った繰り返し処理によるヒストグラムの一括出力
for関数を使った繰り返し処理によるヒストグラムの一括出力
MICの解説
MICの解説
Rで学ぶロバスト推定
Rで学ぶロバスト推定
ベイズ機械学習(an introduction to bayesian machine learning)
ベイズ機械学習(an introduction to bayesian machine learning)
不均衡データのクラス分類
不均衡データのクラス分類
第4回DARM勉強会 (構造方程式モデリング)
第4回DARM勉強会 (構造方程式モデリング)
Rによる高速処理 まだfor使ってるの?
Rによる高速処理 まだfor使ってるの?
構造方程式モデルによる因果探索と非ガウス性
構造方程式モデルによる因果探索と非ガウス性
ベイズ統計入門
ベイズ統計入門
Stan超初心者入門
Stan超初心者入門
DARM勉強会第3回 (missing data analysis)
DARM勉強会第3回 (missing data analysis)
指数分布とポアソン分布のいけない関係
指数分布とポアソン分布のいけない関係
【解説】 一般逆行列
【解説】 一般逆行列
構造方程式モデルによる因果推論: 因果構造探索に関する最近の発展
構造方程式モデルによる因果推論: 因果構造探索に関する最近の発展
数式を綺麗にプログラミングするコツ #spro2013
数式を綺麗にプログラミングするコツ #spro2013
MCMCでマルチレベルモデル
MCMCでマルチレベルモデル
ベイズ統計学の概論的紹介
ベイズ統計学の概論的紹介
CRAN Rパッケージ BNSLの概要
CRAN Rパッケージ BNSLの概要
Rでisomap(多様体学習のはなし)
Rでisomap(多様体学習のはなし)
Viewers also liked
Python におけるドメイン駆動設計(戦術面)の勘どころ
Python におけるドメイン駆動設計(戦術面)の勘どころ
Junya Hayashi
Prophet入門【理論編】Facebookの時系列予測ツール
Prophet入門【理論編】Facebookの時系列予測ツール
hoxo_m
Pythonはどうやってlen関数で長さを手にいれているの?
Pythonはどうやってlen関数で長さを手にいれているの?
Takayuki Shimizukawa
Prophet入門【R編】Facebookの時系列予測ツール
Prophet入門【R編】Facebookの時系列予測ツール
hoxo_m
Prophet入門【Python編】Facebookの時系列予測ツール
Prophet入門【Python編】Facebookの時系列予測ツール
hoxo_m
TokyoR42_around_chaining
TokyoR42_around_chaining
TokorosawaYoshio
Python入門 : 4日間コース社内トレーニング
Python入門 : 4日間コース社内トレーニング
Yuichi Ito
Viewers also liked
(7)
Python におけるドメイン駆動設計(戦術面)の勘どころ
Python におけるドメイン駆動設計(戦術面)の勘どころ
Prophet入門【理論編】Facebookの時系列予測ツール
Prophet入門【理論編】Facebookの時系列予測ツール
Pythonはどうやってlen関数で長さを手にいれているの?
Pythonはどうやってlen関数で長さを手にいれているの?
Prophet入門【R編】Facebookの時系列予測ツール
Prophet入門【R編】Facebookの時系列予測ツール
Prophet入門【Python編】Facebookの時系列予測ツール
Prophet入門【Python編】Facebookの時系列予測ツール
TokyoR42_around_chaining
TokyoR42_around_chaining
Python入門 : 4日間コース社内トレーニング
Python入門 : 4日間コース社内トレーニング
Similar to R6パッケージの紹介―機能と実装
Rあんなときこんなとき(tokyo r#12)
Rあんなときこんなとき(tokyo r#12)
Shintaro Fukushima
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと
Haruka Ozaki
[東京] JapanSharePointGroup 勉強会 #2
[東京] JapanSharePointGroup 勉強会 #2
Atsuo Yamasaki
[機械学習]文章のクラス分類
[機械学習]文章のクラス分類
Tetsuya Hasegawa
d3sparql.js
d3sparql.js
Toshiaki Katayama
Apache Spark チュートリアル
Apache Spark チュートリアル
K Yamaguchi
R6 classes
R6 classes
hiroki84
Ruby on Rails on MySQL チューニング入門
Ruby on Rails on MySQL チューニング入門
だいすけ さとう
HaskellDB
HaskellDB
Kei Hibino
EucalyptusのHadoopクラスタとJaqlでBasket解析をしてHiveとの違いを味わってみました
EucalyptusのHadoopクラスタとJaqlでBasket解析をしてHiveとの違いを味わってみました
Etsuji Nakai
メタメタプログラミングRuby
メタメタプログラミングRuby
emasaka
RailsエンジニアのためのSQLチューニング速習会
RailsエンジニアのためのSQLチューニング速習会
Nao Minami
Project lambda
Project lambda
Appresso Engineering Team
Fess/Elasticsearchを使った業務で使える?全文検索への道
Fess/Elasticsearchを使った業務で使える?全文検索への道
Shinsuke Sugaya
10分で分かるRパッケージの作り方
10分で分かるRパッケージの作り方
Yohei Sato
知って得する標準関数の使い方
知って得する標準関数の使い方
Soudai Sone
Python opt
Python opt
Mikio Kubo
10分で分かるr言語入門ver2.10 14 1101
10分で分かるr言語入門ver2.10 14 1101
Nobuaki Oshiro
10分で分かるr言語入門ver2.9 14 0920
10分で分かるr言語入門ver2.9 14 0920
Nobuaki Oshiro
Gorinphp0729
Gorinphp0729
akitsukada
Similar to R6パッケージの紹介―機能と実装
(20)
Rあんなときこんなとき(tokyo r#12)
Rあんなときこんなとき(tokyo r#12)
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと
[東京] JapanSharePointGroup 勉強会 #2
[東京] JapanSharePointGroup 勉強会 #2
[機械学習]文章のクラス分類
[機械学習]文章のクラス分類
d3sparql.js
d3sparql.js
Apache Spark チュートリアル
Apache Spark チュートリアル
R6 classes
R6 classes
Ruby on Rails on MySQL チューニング入門
Ruby on Rails on MySQL チューニング入門
HaskellDB
HaskellDB
EucalyptusのHadoopクラスタとJaqlでBasket解析をしてHiveとの違いを味わってみました
EucalyptusのHadoopクラスタとJaqlでBasket解析をしてHiveとの違いを味わってみました
メタメタプログラミングRuby
メタメタプログラミングRuby
RailsエンジニアのためのSQLチューニング速習会
RailsエンジニアのためのSQLチューニング速習会
Project lambda
Project lambda
Fess/Elasticsearchを使った業務で使える?全文検索への道
Fess/Elasticsearchを使った業務で使える?全文検索への道
10分で分かるRパッケージの作り方
10分で分かるRパッケージの作り方
知って得する標準関数の使い方
知って得する標準関数の使い方
Python opt
Python opt
10分で分かるr言語入門ver2.10 14 1101
10分で分かるr言語入門ver2.10 14 1101
10分で分かるr言語入門ver2.9 14 0920
10分で分かるr言語入門ver2.9 14 0920
Gorinphp0729
Gorinphp0729
R6パッケージの紹介―機能と実装
1.
R6パッケージの紹介:機能と実装 Tokyo.R #46 2015-02-21 @__nakamichi__
2.
• R6パッケージとは • R6を使う –
既存のオブジェクト指向システム(S3, S4, RC) – R6の機能 • R6の中身をのぞいてみる – Rにおける環境 – R6Class()の実装 – $new()の実装 • まとめ 1
3.
• R6パッケージとは • R6を使う –
既存のオブジェクト指向システム(S3, S4, RC) – R6の機能 • R6の中身をのぞいてみる – Rにおける環境 – R6Class()の実装 – $new()の実装 • まとめ 2
4.
R6パッケージとは • Rの新しいオブジェクト指向システム • 作者:Winston
Changさん@RStudio • R言語のコアではなくパッケージとして実装 • 主にRStudio関係のパッケージで 利用されている – dplyr – httr – shiny 3
5.
R6パッケージとは • 既に3つもOOシステムがあるのに,なぜまたもう1つ? – S3,
S4, RC (Reference Class) • R6の特徴 – より「普通の」オブジェクト指向っぽい • 「普通の」= Java, C++, Python, etc. • RCと同様のreference semantics • フィールド,メソッドにpublic / private が指定可能 • パッケージをまたいだ継承が可能 – RCより速くて軽い – 設計・実装が単純 • Rの基本的な機能だけを使って実装されている 4
6.
• R6パッケージとは • R6を使う –
既存のオブジェクト指向システム(S3, S4, RC) – R6の機能 • R6の中身をのぞいてみる – Rにおける環境 – R6Class()の実装 – $new()の実装 • まとめ 5
7.
6 既存のOOシステム • S3 – クラスはclass属性として個別のオブジェクトに対して設定 •
フォーマルなクラス定義はない • 継承もclass属性で行う – メソッドはジェネリック関数 john <- list(name = "John", age = 40) class(john) <- c("Employee", "Person") # printはジェネリック関数 print #> function (x, ...) #> UseMethod("print") # メソッド定義 print.Person <- function(x) { paste0("こんにちは,", x$name, "です.") } # printで実際に呼ばれるのはprint.Person print(john) #> [1] "こんにちは,Johnです."
8.
7 既存のOOシステム • S4 – S3よりフォーマルで厳密なクラス定義 –
スロット(フィールド)には@でアクセス # クラス定義 setClass("Person", slots = list(name = "character", age = "numeric")) # containsで継承 setClass("Employee", contains = "Person" slots = list(boss = "Person")) # new()でオブジェクト作成 alice <- new("Person", name = "Alice", age = 40) john <- new("Employee", name = "John", age = 20, boss = alice) # @でスロットにアクセス alice@age #> [1] 40 # クラス定義にないスロットは作れない alice@age <- '40' #> Error in checkAtAssignment("Person", "age", "character") : ... alice@sex <- "female" #> Error in checkAtAssignment("Person", "sex", "character") : ...
9.
8 既存のOOシステム • S4 – メソッドはジェネリック関数 –
copy-on-modify semantics: オブジェクトは変更不能(immutable) # ジェネリック関数 setGeneric("greet", function(x) { standardGeneric("greet") }) # メソッドの実装 setMethod("greet", signature = c(x = "Person"), definition = function(x) { paste0("こんにちは,", x@name, "です.") }) greet(john) #> [1] "こんにちは,Johnです." # aliceとalice2は別人 alice2 <- alice alice2@age <- 50 alice2@age #> [1] 50 alice@age #> [1] 40 age=50 name=“alice” age=40 name=“alice” Person alice Person alice2 copy on modify
10.
9 既存のOOシステム • RC (Reference
Class) – メソッドはオブジェクトに属する – フィールドとメソッドには$でアクセス # クラス定義 Person <- setRefClass("Person", # フィールド定義 fields = list(name = “character”, age = "numeric", hair = "character"), # メソッド定義 methods = list( # オブジェクトの初期化関数 # フィールドへの代入は<<-か.selfを使う initialize = function(name, age, hair) { name <<- name .self$age <- age .self$hair <- hair }, set_hair = function(hair) { .self$hair <- hair }, greet = function() { paste0("こんにちは,", name, "です.") }) ) # オブジェクト作成 alice <- Person$new("Alice", 40, "red") # $でメソッドアクセス alice$greet() # 継承はcontains引数で Employee <- setRefClass("Employee", contains = "Person", methods = list( # メソッドオーバーライド greet = function() { paste0("こんにちは,会社員の", name, "です.") }) ) john <- Employee$new("John", 25, "black") john$greet() #> [1] "こんにちは,会社員のJohnです."
11.
10 既存のOOシステム • RC (Reference
Class) – reference semantics: オブジェクトは変更可能(mutable) – 「普通の」OOP言語っぽい name = “john” age = 25 hair = “green” Employee john Employee john2 john$hair #> [1] "black" # johnとjohn2は同じ人 john2 <- john john2$set_hair("green") john$hair #> [1] "green“
12.
• R6パッケージとは • R6を使う –
既存のオブジェクト指向システム(S3, S4, RC) – R6の機能 • R6の中身をのぞいてみる – Rにおける環境 – R6Class()の実装 – $new()の実装 • まとめ 11
13.
12 R6の機能 • クラス定義 – syntaxはRCに類似しているが,より簡潔 –
フィールドとメソッドを分けずに全てpublic引数に記述すればよい – RCと異なり,フィールドの型は指定できない # クラス定義 Person <- R6Class("Person", # publicでフィールドとメソッドを両方設定する public = list( # RCと異なり,変数の型ではなくデフォルト値を設定 name = NA, hair = "black", # オブジェクトの初期化関数 # オブジェクト自身にはselfでアクセス initialize = function(name, hair) { self$name <- name self$hair <- hair }, set_hair = function(hair) { self$hair <- hair }, greet = function() { paste0("こんにちは,", self$name, "です.") }) )
14.
13 R6の機能 • オブジェクト作成 – $new()メソッドで作成 –
reference semantics # オブジェクト作成 alice <- Person$new("Alice", “black") # フィールド,メソッドには$でアクセス alice$hair #> [1] "black" alice$greet() #> こんにちは,Aliceです. alice$set_hair("red") # クラス定義にないフィールドは作れない alice$age <- 40 #> Error in alice$age <- 40 : ... # aliceとalice2は同一人物 alice2 <- alice alice2$set_hair("blue") alice$hair #> [1] "blue" name=“alice” hair=“blue” Person alice Person alice2
15.
14 R6の機能 • public/private – R6ではprivateフィールド,メソッドを作ることができる •
RCにはない機能 • オブジェクト自身のメソッドからしかアクセスできない • (selfではなく)privateを通じてアクセスする # privateを持つクラス Person <- R6Class("Person", private = list(age = NA, # 年齢はprivate # 年齢のgetter get_age = function() private$age), public = list(name = NA, hair = "black", initialize = function(name,hair,age) { # 中略 # メソッドからはprivateフィールドが見える private$age <- age }, set_hair = function(hair) { #略 }, greet = function() { #略 }, # 外向け年齢はサバを読む show_age = function() { private$get_age() - 5 }) ) # オブジェクト作成 alice <- Person$new("Alice", "red", 40) # age, get_age()は外からは見えない alice$age #> NULL alice$get_age() #> Error: attempt to apply non-function alice$show_age() #> [1] 35
16.
15 R6の機能 • 継承 – スーパークラスを
inherit 引数で指定 – スーパークラスのメソッドはsuperを通じて呼べる – パッケージをまたいだ継承が可能(portable class, RCではできない) # inheritで継承 Employee <- R6Class("Employee", inherit = Person, private = list(tsurami = 0), # つらみ public = list( # メソッドオーバーライド initialize = function(name, hair, age, tsurami) { # スーパークラスはsuperで呼ぶ super$initialize(name, hair, age) private$tsurami <- tsurami }, work = function() { private$tsurami <- private$tsurami + 1}, greet = function() { if(private$tsurami > 5) paste0("社畜の", self$name, "です!") else super$greet() }) ) # Johnは社畜 john <- Employee$new("John", "black", 35, tsurami = 10) john$greet() #> 社畜のJohnです!
17.
16 R6の機能 • パフォーマンス – R6はRCより速くて軽い #
RCとR6のパフォーマンス比較 library(microbenchmark) # 適当なクラスを定義 R6 <- R6Class("R6", public = list( x = NULL, initialize = function(x = 1) self$x <- x, inc = function(n = 1) self$x <- self$x + n) ) RC <- setRefClass("RC", fields = list(x = "numeric"), methods = list( initialize = function(x = 1) x <<- x, inc = function(n = 1) x <<- x + n) ) # オブジェクト生成 microbenchmark( r6 <- R6$new(x = 100), rc <- RC$new(x = 100)) #> Unit: microseconds #> expr median neval #> r6 <- R6$new(x = 100) 84.7825 100 #> rc <- RC$new(x = 100) 405.3950 100 # メソッド呼び出し microbenchmark(r6$inc(), rc$inc()) #> Unit: microseconds #> expr median neval #> r6$inc() 16.065 100 #> rc$inc() 62.918 100 # オブジェクトサイズ pryr::object_size(r6) #> 3.94 kB pryr::object_size(rc) #> 465 kB
18.
17 R6の機能 • ここまでのまとめ • R6はRCと同様,
reference semantics のOOシステム • R6は「普通の」オブジェクト指向っぽい – 簡潔なsyntax – public/privateの区別 – パッケージをまたいだ継承 • R6はRCより速くて軽い
19.
• R6パッケージとは • R6を使う –
既存のオブジェクト指向システム(S3, S4, RC) – R6の機能 • R6の中身をのぞいてみる – Rにおける環境 – R6Class()の実装 – $new()の実装 • まとめ 18
20.
19 R6の中身をのぞいてみる • R6の仕組みを知りたい – R6Class()や$new()って何? –
public / private の仕組みは? • 実はR6の実装は意外と簡単 – Rの基本的な機能だけで実装できる • 要は,reference semantics を持つデータ構造を 「普通の」OOPのオブジェクトらしく見えるように 仕立てあげればよい • reference semanticsを持つデータ構造 =「環境」
21.
20 Rにおける環境 • 環境(environment) =
関数を構成する要素のひとつ – Rの関数の3つの構成要素 • formals: 引数 • body: 関数本体 • environment: 変数(名前)をオブジェクトに結びつけるデータ構造 g x 1 g x 2 environment(g) <- e e f <- function() { x <- 1 function() { x + 1 } } g <- f() environment(g) #> <environment: 0x0000000013ddc1b8> # gは親環境にxを探しに行く g() #> [1] 2 # gの環境を変更する e <- new.env() e$x <- 2 environment(g) <- e g() #> [1] 3 <environment: 0x0000000013ddc1b8>
22.
21 Rにおける環境 • 環境は2つの要素からなる – フレーム:名前をオブジェクトに結びつける –
親環境(parent environment) • 関数は親環境を辿っていって名前を探す y <- 2 f <- function() { x <- 1 function() { x + y } } h <- f() h() #> [1] 3 environment(h) #> <environment: 0x000000001424c380> parent.env(environment(h)) #> <environment: R_GlobalEnv> h x 1 <environment: 0x000000001424c380> y 2 globalenv() parent.env()
23.
22 Rにおける環境 • 環境 ≃
reference semantics を持つリスト – 関数とは無関係に,便利なデータ構造としても使える – 環境がだんだん「オブジェクト」に見えてきたような… # 環境e1を作成 e1 <- new.env() e1$x <- 1 e1$x #> [1] 1 # e2を変更するとe1も変わる e2 <- e1 e2$x <- 2 e1$x #> [1] 2 # 関数に渡した環境自体が変更される g <- function(e) { e$y <- 3 } g(e1) e1$y #> [1] 3 # リストl1を作成 l1 <- list() l1$x <- 1 l1$x #> [1] 1 # l2を変更してもl1はそのまま l2 <- l1 l2$x <- 2 l1$x #> [1] 1 # 関数に渡したリスト自体は不変 f <- function(l) { l$y <- 3 } f(l1) l1$y #> NULL
24.
• R6パッケージとは • R6を使う –
既存のオブジェクト指向システム(S3, S4, RC) – R6の機能 • R6の中身をのぞいてみる – Rにおける環境 – R6Class()の実装 – $new()の実装 • まとめ 23
25.
24 R6Class()の実装 • R6Class()の戻り値は? Person <-
R6Class("Person", private = list(age = NA, get_age = function() private$age), public = list(name = NA, hair = "black", initialize = function(name, hair, age) { self$name <- name self$hair <- hair private$age <- age }, set_hair = function(hair) { self$hair <- hair }, greet = function() { paste0("こんにちは,", self$name, "です.") }, show_age = function() { private$get_age() - 5 }) ) Person #> <Person> object generator #> Public: #> name: NA #> hair: black #> initialize: function #> set_hair: function #> greet: function #> show_age: function #> Private: #> age: NA #> get_age: function #> Parent env: <environment: R_GlobalEnv> #> Lock: TRUE #> Portable: TRUE
26.
25 R6Class()の実装 • R6Class() の戻り値=環境 –
R6Class()の引数やnew()を要素に持つgenerator環境がR6クラスの実体 # encapsulate()はR6Classの親環境をcapsuleにする R6Class <- encapsulate(function(classname = NULL, public = list(), private = NULL, inherit = NULL, ...) { # ジェネレータオブジェクトの作成 generator <- new.env(parent = capsule) generator$self <- generator # selfはgenerator自身 generator$classname <- classname generator$public_fields <- get_nonfunctions(public) generator$private_fields <- get_nonfunctions(private) generator$public_methods <- get_functions(public) generator$private_methods <- get_functions(private) # generator_funsはnewを含む関数のリスト # generator_funcs$newの環境をgeneratorにする generator_funs <- assign_func_envs(generator_funs, generator) # generator_funs$newをgenerator$new にコピー list2env2(generator_funs, generator) class(generator) <- "R6ClassGenerator" generator })
27.
26 R6Class()の実装 generator [Person] R6Class self classname public_fields public_methods private_methods private_fields new function “Person” R6パッケージ内部の ユーティリティ関数群 capsule list(name=NA,
...) list(initialize = function(name, ...), ...) NULL list(age=NA, ...) Person <- R6Class() R6Class()の引数
28.
• R6パッケージとは • R6を使う –
既存のオブジェクト指向システム(S3, S4, RC) – R6の機能 • R6の中身をのぞいてみる – Rにおける環境 – R6Class()の実装 – $new()の実装 • まとめ 27
29.
28 $new()の実装 • $new()の戻り値=環境 – R6オブジェクトの実体はpublic_bind_env環境 –
generatorからpublic_bind_envにフィールドとメソッドをコピーする # publicフィールド・メソッドのみ,継承なしの場合 generator_funs$new <- function(...) { # publicオブジェクトの束縛環境を作成 public_bind_env <- new.env(parent = emptyenv(), hash = FALSE) # メソッドの環境を作成 enclos_env <- new.env(parent = parent_env, hash = FALSE) # selfの実体はpublic_bind_env enclos_env$self <- public_bind_env # generator$public_methodsの環境をenclos_envにして # public_bind_envにコピー public_methods <- assign_func_envs(public_methods, enclos_env) # フィールドとメソッドをpublic環境にコピー list2env2(public_methods, envir = public_bind_env) list2env2(public_fields, envir = public_bind_env) # オブジェクト初期化 public_bind_env$initialize(...) public_bind_env }
30.
29 $new()の実装 public_fieldsと public_methodsのコピー generator [Person] self classname public_fields public_methods private_methods private_fields new function alice <-
Person$new() initialize set_hair name greet hair function function function “black” “Alice” enclos_env public_bind_env [alice] self emptyenv()
31.
30 $new()の実装 • privateがある場合:privateをpublicと別の環境として作成 enclos_env public_fieldsと public_methodsのコピー initialize set_hair name greet hair function function function “black” “Alice” public_bind_env [alice] self emptyenv() private_fieldsと private_methodsのコピー get_age age function 40 private_bind_env private
32.
31 $new()の実装 • スーパークラスがある場合:superをpublicとは別の環境として作成 enclos_env public_fieldsと public_methodsのコピー initialize set_hair name greet hair function function function “black” “Alice” public_bind_env [john] self emptyenv() super_bind_env super super_enclos_env self super greetfunction スーパークラスの スーパークラスを 参照 スーパークラスの public_fieldsと public_methodsのコピー
33.
• R6パッケージとは • R6を使う –
既存のオブジェクト指向システム(S3, S4, RC) – R6の機能 • R6の中身をのぞいてみる – Rにおける環境 – R6Class()の実装 – $new()の実装 • まとめ 32
34.
まとめ • R6は新しいオブジェクト指向システム • R6の特徴 –
「普通の」オブジェクト指向っぽい • reference semantics • public / private – RCより速くて軽い • R6の実装 – 環境を活用したシンプルな実装 • 参考 – Introduction to R6 Classes • http://cran.r-project.org/web/packages/R6/vignettes/Introduction.html – Advanced R – Environments • http://adv-r.had.co.nz/Environments.html 33
Download now