R の概観

Computation
R
Author

司馬博文

Published

5/07/2021

Modified

6/07/2024

概要
R は統計計算のための言語です.その基本的なデータ型と,「属性」を通じた実装,そしてオブジェクト志向の構造について解説します.

1 R の概要

R 言語とは

  • 統計計算のための言語と環境の総称
  • 最新の技術や方法が簡単に導入できることも多い
    • 新しい技法のデモとして論文でも実装される.
    • Python や Julia と同様.
  • Austria 中心の開発.データの分類・集計・整理の機能は織り込み済み.
    • ニュージーランドのオークランド大学の Ross IhakaRobert Clifford Gentleman により作られた
    • BBC のグラフは R で書いている.BBC が R 用のパッケージをリリースしている.

2 基本型

2.1 データ構造:built-in は5つ

  • vector
    • scaler オブジェクトは長さ1の vector として実装されている?
      • scaler は数値,文字列,論理値など.
    • c()が constructor
    • x[]で indexing できる
      • []の中身はベクトルで指定できる!これが slice の代わり.
x <- c(10, 20, 30, 40, 50)
x[1]
[1] 10
x[2:4]
[1] 20 30 40
  • matrix
    • matrix() がコンストラクタ
mat <- matrix(1:9, nrow = 3, ncol = 3)
mat
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
mat[2, 3]
[1] 8
  • list:ベクトルとの違いはデータ型が不均一であるのを認めること.
    • list() がコンストラクタ
    • 多分データ分析じゃない計算機命令的な棲み分け.一番 csv みたい,
lst <- list(name = "Alice", age = 25, scores = c(90, 85, 88))
lst
$name
[1] "Alice"

$age
[1] 25

$scores
[1] 90 85 88
lst[[1]]
[1] "Alice"
lst$name
[1] "Alice"
  • data frame:要は実データに即した構造で,行列の拡張.csv みたいな.長さの等しい vector の list.
    • data.frame がコンストラクタ.
df <- data.frame(name = c("Alice", "Bob"), age = c(25, 30))
df
   name age
1 Alice  25
2   Bob  30
df[1, 2]
[1] 25
df$name
[1] "Alice" "Bob"  
  • array:ベクトル,行列のその先へ
    • arrayがコンストラクタ
arr <- array(1:8, dim = c(2, 2, 2))
arr
, , 1

     [,1] [,2]
[1,]    1    3
[2,]    2    4

, , 2

     [,1] [,2]
[1,]    5    7
[2,]    6    8
arr[1, 2, 2]
[1] 7

2.2 データ型:built-in は 251

typeof()で調べる

Note that in the C code underlying R, all objects are pointers to a structure with typedef SEXPREC; the different R data types are represented in C by SEXPTYPE, which determines how the information in the various parts of the structure is used.

  • int:整数
  • double:クラスとしてはnumericとして実装されている.浮動小数点
    • 3.4e-2\(3.4×10^-2\) で表す.
  • complex1iを虚数単位とし,a+biと表す.
  • character
    • paste(x,y,[sep=“ “])
  • logical:Boole 値
typeof(1L)
[1] "integer"
typeof(1i)
[1] "complex"
typeof(FALSE)
[1] "logical"
  • print(pi, digit=12)
    • 任意精度表示.多分 print.numeric_version への dispatch
print(pi, digit=12)
[1] 3.14159265359

2.3 予約語とそのデータ型

  • pi, edouble
  • Inf, NaNdoule
  • T,F:TRUE と FALSE の予約.logical
    • as.numeric()1,0に埋め込まれる.
  • NA:Not Available,統計データの欠損を表す.
    • 各モードに1つずつ存在する generic な存在である.
    • NA_integer_, NA_real_, NA_complex_, NA_character_, NA_logical_, ……
  • LETTERS, letters:アルファベットのベクトル,character
  • NULLNULL 型でモードを持たない特殊なオブジェクト.\(\emptyset\) のこと.
LETTERS
 [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S"
[20] "T" "U" "V" "W" "X" "Y" "Z"

2.4 データのクラス

class()で調べることが出来る.

多くはデータ型(typeof())と一致する.

typeof(pi)
[1] "double"
class(pi)
[1] "numeric"

2.5 Logical:2値関数

ベクトルを各成分ごとに評価して,logical vector を返す関数.

  • !=, >=, <=
x <- c(1, 2, 3)
y <- c(3, 2, 1)
x != y
[1]  TRUE FALSE  TRUE
x >= y
[1] FALSE  TRUE  TRUE
x <= y
[1]  TRUE  TRUE FALSE
  • is.null(), is.na(), is.nan(), is.finite(), is.infinite()
is.na(c(1, NA, 3))
[1] FALSE  TRUE FALSE
is.finite(c(1, Inf, NA, NaN))
[1]  TRUE FALSE FALSE FALSE
  • identical(1,1.0)Tである,いずれも倍精度浮動小数点で表現されるので.
  • all.equal():「ほぼ同じ」かどうか.数値の近似比較に使える.
identical(1, 1.0)
[1] TRUE
all.equal(1, 1.0000001)
[1] "Mean relative difference: 1e-07"
  • &,|:論理積・和
  • &&, ||:条件式の論理積・和
    • &,|と違い,ベクトルには使えない.
  • xor():排他的論理和
x <- c(TRUE, FALSE, TRUE)
y <- c(TRUE, TRUE, FALSE)
x & y
[1]  TRUE FALSE FALSE
x && y
Error in x && y: 'length = 3' in coercion to 'logical(1)'
xor(x, y)
[1] FALSE  TRUE  TRUE
  • %in%:match の二項関係版 interface.
    • "%in%" <- function(x, table) match(x, table, nomatch = 0) > 0が現状の定義
  • with(data, expr, …)
    • data:data frame
    • exprdataの列名に関する expression をベタがき
    • 列ごとにexprを実行した結果を返す.
  • match(x, table)
    • x %in% tableと使える.
    • x:vector
    • table:vector
    • 返り値:logical vector
x <- c(1, 2, 3)
table <- c(2, 3, 4)
x %in% table
[1] FALSE  TRUE  TRUE
match(x, table)
[1] NA  1  2
data <- data.frame(a = 1:3, b = 4:6)
with(data, a + b)
[1] 5 7 9

2.6 mode について

  • str(obj):R object の構造を教えてくれる.structure
  • mode(obj):オブジェクトのモード=データ型を返す.
  • class(obj):R は全てのものはオブジェクトだから,class を返す.この値に従って dispatch されている.

Function mode gives information about the mode of an object in the sense of Becker, Chambers & Wilks (1988), and is more compatible with other implementations of the S language. – R Language Definition

  • storage.mode(obj):オブジェクトの storage mode を返す.

Finally, the function storage.mode returns the storage mode of its argument in the sense of Becker et al. (1988). – R Language Definition

  • help()?keywordと等価.
    • Trig {base}:パッケージ base の Trig についての説明.
    • graphics::hist:はパッケージ graphics の関数 hist について.
    • 特殊関数を調べるには””で escape する必要があることがある.
  • example():R のこの機能やばすぎる
    • help 内の例を実行
    • demo()がさらにある.
  • help.search()??”keyword”と等価.
    • キーワード検索
    • Google 検索と同じ要領で使ってください.

3 属性

NULL以外の全てのオブジェクトはattributeを持ち得る.attributeとは,全ての成分に名前がついたpairlistである.

attributes(y ~ x1 + x2)
$class
[1] "formula"

$.Environment
<environment: R_GlobalEnv>

属性は,第一義的には R にクラス構造を実装するのに使われる.class属性を評価し,そのオブジェクトにどの function dispatch を適用するかを決定する.

3.1 names

namesは,ベクトルの各要素に名前をつけるための属性であり,indexing にも使われる.

3.2 class

classは,オブジェクトのクラスを指定する文字列である.

4 R のオブジェクト志向構造

4.1 Polymorphism(多態的)なオブジェクト志向

  • polymorphic な関数を generic function という.2
  • R では、クラスはオブジェクトに付随する属性として扱われるものの一つであり、リストとして保持される。その「クラス」という付加情報によって,同じ関数名でも挙動が違う,というのが R の関数である.

R の OO システムは3つあり,S3, S4, R5 という.

S3 implements a style of object oriented programming called generic-function OO. This is different to most programming languages, like Java, C++ and C#, which implement message-passing OO. In message-passing style, messages (methods) are sent to objects and the object determines which function to call. Typically this object has a special appearance in the method call, usually appearing before the name of the method/message: e.g. canvas.drawRect(“blue”). S3 is different. While computations are still carried out via methods, a special type of function called a generic function decides which method to call. Methods are defined in the same way as a normal function, but are called in a different way, as we’ll see shortly.

S3クラス(S言語ver.3という意味) 初期のRクラス構造で現在もRの有力なクラスパラダイム. 組み込みクラスのほとんどがS3パラダイム. 1. 全てがリストであり,新たにクラス名属性を持つとクラスになる. 2. method dispatch機能の実装のためにある 1. 「ジェネリック関数が呼び出された時に,実引数のmodeを見て適切なクラスメソッドに引き渡す機能」があるのでgeneric functionが定義できる. 2. plot()で適切に動くのも,全てのオブジェクトが密かにクラスが違うからである.ジェネリック関数printの呼び出しprint(lm)はlmクラスのメソッドprint.lm()にディスパッチされる.

実装に使われている関数 * attr(): * class():クラス属性のベクトル.ここへ付与する形でS3は実装されている.

それを確認できる関数 * attributes(obj):\(nameや\)classなどの属性を格納したlist. * 実はリストのtag(\(で参照されるやつ)はnamesというattributeである. * それに次いで2番目が\)classというattributeになる. * 通常のlist objectを表示した時,最後の要素がattr(,”class”)となるのは,通常のリストの構造は1列目の要素としたら,2列目の要素ということである. * #これがリストの多次元入れ子構造. * unclass(obj):クラス属性を外せる.lmなど,ほとんどがクラスという属性を持ったlist. * methods(fun):generic methodの全てを表示する. * がついているものは,デフォルトのbase名前空間にはない関数. getAnywhere():あらゆる名前空間からその名前を持つobjectを持ってくる. * 標準名前空間にない存在はnamespace:::nameでアクセスできる. * methods(,”classname”)と使うと,classnameという名前を持ったクラスにdispatchされているmethodを表示する.

4.2 クラスシステム

  • list などはクラスとして実装されていて,class(object) で確認できる.
  • mode(object) <- value は storage mode のこと.
    • typeof()を wrap している.
    • <- valueとできるのは:“logical”, “integer”, “double”, “complex”, “raw”, “character”, “list”, “expression”, “name”, “symbol” and “function”
  • typeof(object)

4.3 S3 クラス(S 言語 ver.3 という意味)

初期の R クラス構造で現在も R の有力なクラスパラダイム. 組み込みクラスのほとんどが S3 パラダイム. 1. 全てがリストであり,新たにクラス名属性を持つとクラスになる. 2. method dispatch機能の実装のためにある 1. 「ジェネリック関数が呼び出された時に,実引数のmodeを見て適切なクラスメソッドに引き渡す機能」があるのでgeneric functionが定義できる. 2. plot()で適切に動くのも,全てのオブジェクトが密かにクラスが違うからである.ジェネリック関数printの呼び出しprint(lm)はlmクラスのメソッドprint.lm()にディスパッチされる.

実装に使われている関数 * attr(): * class():クラス属性のベクトル.ここへ付与する形でS3は実装されている.

それを確認できる関数 * attributes(obj):\(nameや\)classなどの属性を格納したlist. * 実はリストのtag(\(で参照されるやつ)はnamesというattributeである. * それに次いで2番目が\)classというattributeになる. * 通常のlist objectを表示した時,最後の要素がattr(,”class”)となるのは,通常のリストの構造は1列目の要素としたら,2列目の要素ということである. * #これがリストの多次元入れ子構造. * unclass(obj):クラス属性を外せる.lmなど,ほとんどがクラスという属性を持ったlist. * methods(fun):generic methodの全てを表示する. * がついているものは,デフォルトのbase名前空間にはない関数. getAnywhere():あらゆる名前空間からその名前を持つobjectを持ってくる. * 標準名前空間にない存在はnamespace:::nameでアクセスできる. * methods(,”classname”)と使うと,classnameという名前を持ったクラスにdispatchされているmethodを表示する.

クラス定義のための機構 * print() * prints its argument and returns it invisibly (via ‘invisible(x)’) * 新しいクラスを作ったら,そのためのprintを定義するのが流れ.

4.4 S4 クラス

S3 クラスとの棲み分けは,安全性で,まだ存在しないクラスコンポーネントにアクセスできなくなった.

References

Wickham, H. (2019). Advanced r. Chapman & Hall.

Footnotes

  1. (Wickham, 2019) 第12章↩︎

  2. c++ならば仮想関数という.↩︎