ラベル R の投稿を表示しています。 すべての投稿を表示
ラベル R の投稿を表示しています。 すべての投稿を表示

2008年8月11日月曜日

An Introduction to R を読む (3) - 配列と行列

An Introduction to R を読む (2) – オブジェクトとカテゴリー (factor) の続き。

 

配列

ベクトルに dim 属性を与えると、配列 (array) になる。 dim 属性はベクトルで与えられ、次元ベクトル (dimention vector) と呼ばれる。この次元ベクトルの大きさ k に応じて、配列は k 次元であると言う。

ベクトル → dim を設定することにより → 配列

試してみる。

> a <- 1:24
> a
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
> dim(a) <- c (4,6)
> a
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    5    9   13   17   21
[2,]    2    6   10   14   18   22
[3,]    3    7   11   15   19   23
[4,]    4    8   12   16   20   24

> dim(a) <- c(3,4,2)
> a
, , 1

     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12

, , 2

     [,1] [,2] [,3] [,4]
[1,]   13   16   19   22
[2,]   14   17   20   23
[3,]   15   18   21   24

> dim(a) <- c(24)
> a
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

次元ベクトルが 2つの場合、行列 (matrix) 。 1 つ場合は、ベクトルと同じように扱える。 (多少違いがあるみたい。) 上記の例を見るとわかるように、ベクトルの先頭から、列方向に配置されていく。

 

要素の取得

配列の中の要素を取得する。先ほどの例の中で、次元ベクトルが c(3,4,2) の配列を対象とする。

> a[,,1]
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
> a[,2,1]
[1] 4 5 6
> a[3,2,1]
[1] 6

> # [1,]の行を取得する
> a[1,,]
     [,1] [,2]
[1,]    1   13
[2,]    4   16
[3,]    7   19
[4,]   10   22
> a[1,2,]
[1]  4 16
> a[1,2,3]

ちなみに a[,,] は全ての要素を取得することになる。インデックスが空になっているところは、その要素全てを対象にしていることを表わす。

 

要素の設定

配列のインデックスに配列を指定して、要素を取得、値の設定をすることができる。

> a
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,]    1    4    7   10   13   16   19   22
[2,]    2    5    8   11   14   17   20   23
[3,]    3    6    9   12   15   18   21   24

> a[array(c(c(1,2,3,2,1,2,3,2),1:8), dim=c(8,2))] <- 0
> a
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,]    0    4    7   10    0   16   19   22
[2,]    2    0    8    0   14    0   20    0
[3,]    3    6    0   12   15   18    0   24

ここで指定したいインデックスについて考えるとき、上記の場合であれば、まず行方向についてインデックスを見る。そして、次にそれに対応させるように列方向のインデックスについて考える。最後に、それらを組み合わせてインデックスを指定できる行列へとなるように次元の値を設定する。

 

array(ベクトル, ディメンション) による配列の作成

array() を利用して配列を生成することができる。ただし、 対象の要素が dim で指定した要素数に満たないときは、要素を満たすように要素の先頭から繰り返される。

> array(1:20, dim=c(6,4))
     [,1] [,2] [,3] [,4]
[1,]    1    7   13   19
[2,]    2    8   14   20
[3,]    3    9   15    1
[4,]    4   10   16    2
[5,]    5   11   17    3
[6,]    6   12   18    4

 

outer product

outer product 。 全てのベクトルの要素を掛け合わせる。(R: Outer Product of Arrays)

> c(1,2,3) %o% c(4,5,6)
     [,1] [,2] [,3]
[1,]    4    5    6
[2,]    8   10   12
[3,]   12   15   18

> outer(c(1,2,3),c(4,5,6), "*")
     [,1] [,2] [,3]
[1,]    4    5    6
[2,]    8   10   12
[3,]   12   15   18

outer() には自分で定義した関数を渡すことができる。ただし、その関数は引数を 2 つ取ること。例えば、適当に関数を作って、それを outer() に渡してみる。 (rel. ループと再帰)

> f <- function(x,y) (x + y) / y

> a <- c(1,2,3)
> b <- c(4,5,6)

> outer(a,b,f)
     [,1] [,2]     [,3]
[1,] 1.25  1.2 1.166667
[2,] 1.50  1.4 1.333333
[3,] 1.75  1.6 1.500000

 

行列

行列の作成

matrix() によって行列を作成できる。

> matrix(1:9)
      [,1]
 [1,]    1
 [2,]    2
 [3,]    3
 [4,]    4
 [5,]    5
 [6,]    6
 [7,]    7
 [8,]    8
 [9,]    9

># 行数と列数を指定
> matrix(1:9, nrow=3, ncol=3)
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

># 行方向に行列を作成する
> matrix(1:9, nrow=3, ncol=3, byrow=TRUE)
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9

 

A を上記の matrix() によって生成した行列とする。

> A * A
     [,1] [,2] [,3]
[1,]    1   16   49
[2,]    4   25   64
[3,]    9   36   81

># 行列の積
> A %*% A
     [,1] [,2] [,3]
[1,]   30   66  102
[2,]   36   81  126
[3,]   42   96  150


># quadratic form ってなんだろ? 二次形式???
> a <- c(1,2,3)
> a %*% A %*% a
     [,1]
[1,]  228

># クロス積
> crossprod(A,A)
     [,1] [,2] [,3]
[1,]   14   32   50
[2,]   32   77  122
[3,]   50  122  194

># 上記は以下と同じらしい。
> t(A) %*% A
     [,1] [,2] [,3]
[1,]   14   32   50
[2,]   32   77  122
[3,]   50  122  194

crossprod() とはクロス積 - Wikipedia のことか。

 

転置行列

転置行列 – Wikipedia によると、

mn 列の行列 A に対して A の (i, j) 要素と (j, i) 要素を入れ替えた nm 列の行列、つまり対角線で成分を折り返した行列のことである。

 

> A <- array(1:9,dim=c(3,3))
> A
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
> aperm(A, c(2,1))
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9

aperm() の特殊なケースとして t() を用いて同様に、

> t(A)
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9

 

対角要素、単位行列

対角行列 - Wikipedia によると

正方行列であって、その対角成分((i,i)-要素)以外が零であるような行列のことである。 (…)

対角行列の転置行列は同一である。そのため対角行列は対称行列でもある。

diag() 関数にベクトルを引数として与える。

> diag(c(1,2,3,4,5))
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    0    0    0    0
[2,]    0    2    0    0    0
[3,]    0    0    3    0    0
[4,]    0    0    0    4    0
[5,]    0    0    0    0    5

># 行列を引数に与えると対角要素が得られる
> diag(matrix(1:9, nrow=3,ncol=3))
[1] 1 5 9

># 数値 k を引数に与えると k × k の単位行列が得られる
> diag(5)
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    0    0    0    0
[2,]    0    1    0    0    0
[3,]    0    0    1    0    0
[4,]    0    0    0    1    0
[5,]    0    0    0    0    1

単位行列 - Wikipedia によると、

単位的環上で定義される同じ型の正方行列同士の、積演算における単位元のことである。単位行列の対角成分には 1 が並び、他は全て 0 となる:

 

行列と連立方程式

考え方は、線型方程式系 - Wikipedia を参考に。例えば、次の連立方程式を行列で解くとする。

2x + 3y = 15
 x +  y =  1

R では solve() を用いて次のようにする。

> A <- matrix(c(2,3,1,1),nrow=2,ncol=2,byrow=TRUE)
> A
     [,1] [,2]
[1,]    2    3
[2,]    1    1

> b <- matrix(c(15,1))
> b
     [,1]
[1,]   15
[2,]    1

> solve(A,b)
     [,1]
[1,]  -12
[2,]   13

逆行列を求めるには、上記の solve() を用いて、

> A <- matrix(1:4, nrow=2, ncol=2)
> A
     [,1] [,2]
[1,]    1    3
[2,]    2    4
> solve(A)
     [,1] [,2]
[1,]   -2  1.5
[2,]    1 -0.5

 

固有値と固有ベクトル

はぁ~未だよくわがんねぇ (@_@;)... パタッ(o_ _)o~†

とりあえず、イメージだけでもしておくかぁ。

結論を一言で言うと,”ほとんど” の線形写像はベクトルの”引き伸ばし(倍率が1以下ならば縮小)”と考えることができ,その引き伸ばしの方向を決めているのが固有ベクトルで倍率が固有値です。ただし,この様子は実数の世界で完全に捉えることは不可能で,複素数の世界において可能となります。

ときわ台学/固有値/固有ベクトルの幾何学的意味より

行列を 1個固定して考えてみます. この行列は何かよくわからないんですが線形変換を表します. たいていのベクトルはこの線形変換によって変な方向を向いてしまうんですが, まれに方向が変わらず長さだけが変わるベクトルがあります. このように「長さだけが変わるベクトル」がこの線形変換 (ひいては行列) の固有ベクトルとなります. で, 長さの変化率が固有値.

固有値、固有ベクトル、対角化...何のため? - 教えて!gooより

R では、

> Sm <- matrix(c(3,1,1,3),nrow=2,ncol=2)
> Sm
     [,1] [,2]
[1,]    3    1
[2,]    1    3
> eigen(Sm)
$values
[1] 4 2

$vectors
          [,1]       [,2]
[1,] 0.7071068 -0.7071068
[2,] 0.7071068  0.7071068

># 個々の値を取得するには...
> ev%val
Error: unexpected input in "ev%val"
> ev$val
[1] 4 2
> ev$vec
          [,1]       [,2]
[1,] 0.7071068 -0.7071068
[2,] 0.7071068  0.7071068

 

その他

特異値分解 : svd(M)。lsfit() : 最小二乗法? lm(), qr()。 パタッ(o_ _)o~†

 

cbind(), rbind()

cbind(), rbind() は、それぞれ列方向、行方向にベクトルや行列をくっつけて行列を作る。これにより、ベクトルを行列の行または列のように扱うことができる。

> cbind(1,1:5)
     [,1] [,2]
[1,]    1    1
[2,]    1    2
[3,]    1    3
[4,]    1    4
[5,]    1    5

> cbind(1:3,1:5)
     [,1] [,2]
[1,]    1    1
[2,]    2    2
[3,]    3    3
[4,]    1    4
[5,]    2    5
Warning message:
In cbind(1:3, 1:5) :
  number of rows of result is not a multiple of vector length (arg 1)

> rbind(1,1:5)
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    1    1    1    1
[2,]    1    2    3    4    5

> rbind(1:3,1:5)
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    2    3    1    2
[2,]    1    2    3    4    5
Warning message:
In rbind(1:3, 1:5) :
  number of columns of result is not a multiple of vector length (arg 1)


># 行列の場合
> A
     [,1] [,2]
[1,]    1    3
[2,]    2    4
> cbind(A,1:5)
     [,1] [,2] [,3]
[1,]    1    3    1
[2,]    2    4    2
Warning message:
In cbind(A, 1:5) :
  number of rows of result is not a multiple of vector length (arg 2)
> rbind(A,1:5)
     [,1] [,2]
[1,]    1    3
[2,]    2    4
[3,]    1    2
Warning message:
In rbind(A, 1:5) :
  number of columns of result is not a multiple of vector length (arg 2)

 

次元のクリア

配列の次元をクリアする方法。 as.vector() と c()。

> a <- c(1,2,3,4,5,6); dim(a) <- c(2,3)
> a
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
> b <- as.vector(a)
> b
[1] 1 2 3 4 5 6

> c <- c(a)
> c
[1] 1 2 3 4 5 6

 

クロス集計表

以下のように、クラス (class)  と性別 (sex)  を表わすベクトルがあるとする。これからクロス集計表を作りたい。

> class
[1] "A" "A" "B" "A" "C" "C" "B" "C" "C"
> sex
[1] "M" "M" "M" "M" "F" "F" "F" "F" "F"

> table(class,sex)
     sex
class F M
    A 0 3
    B 1 1
    C 4 0

cut() によって数値を特定の範囲に分類することができる。例えば、身長のベクトルがあり、これを 150cm から 5cm ごとの間隔で分ける場合、

> height <- c(170,168,175,160,163,153,155,170,165)

> cut(height, breaks = 150+5*(0:5)) -> heightf
> heightf
[1] (165,170] (165,170] (170,175] (155,160] (160,165] (150,155] (150,155]
[8] (165,170] (160,165]
Levels: (150,155] (155,160] (160,165] (165,170] (170,175]

上記の変数を使い、男女ごとに身長のクロス集計表を得る。

> table(heightf, sex)
           sex
heightf     F M
  (150,155] 2 0
  (155,160] 0 1
  (160,165] 2 0
  (165,170] 1 2
  (170,175] 0 1

2008年7月19日土曜日

An Introduction to R を読む (2) – オブジェクトとカテゴリー (factor)

An Introduction to R を読む (1) -- R の環境とベクトル のつづき

1. オブジェクト

R が扱うデータや関数はオブジェクトで、それぞれに型 (タイプ) がある。

mode(object) によって、オブジェクトの (ストレージ) モードを知ることができる。これは型のようなものかな?

> mode(100)
[1] "numeric"
> mode("abc")
[1] "character"
> mode(abs)
[1] "function"

> mode(NA)
[1] "logical"
> mode(True)
Error in mode(True) : object "True" not found
> mode(T)
[1] "logical"
> mode(TRUE)
[1] "logical"

ストレージと呼ばれるということは、保存形式に関わるものだろうか?

R: The (Storage) Mode of an Object によると、 R: The Type of an Object に、

Current values are the vector types "logical", "integer", "double", "complex", "character", "raw" and "list", "NULL", "closure" (function), "special" and "builtin" (basic functions and operators), "environment", "S4" ...

などの種類が挙げられている。

mode はオブジェクトの特殊な属性のようなもので、lenght() と同じように、全てのオブジェクトが持っている本質的なもの。

空のオブジェクトでも mode があることに注意。例えば numeric() で作成した空のオブジェクトは mode() で numeric となり、character() によって作成した空のオブジェクトは character になる。

> a <- numeric()
> a
numeric(0)
> mode(a)
[1] "numeric"
> typeof(a)
[1] "double"

typeof では double になる。何かごちゃごちゃしてるなぁ (@_@;)

ちなみに、numeric 関数に、引数として数値を与えると、次のような結果となる。

> a <- numeric(10)
> a
 [1] 0 0 0 0 0 0 0 0 0 0
> length(a)
[1] 10

> b <- character(10)
> b
 [1] "" "" "" "" "" "" "" "" "" ""

 

型の変換

character と interer の変換。

> a <- 0:9
> a
 [1] 0 1 2 3 4 5 6 7 8 9

> # 数値から文字へ
> as.character(a)
 [1] "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"

> # 文字から数値へ
> as.numeric(c("100","200","300"))
[1] 100 200 300

as.XXXXXX() という形式で統一されている。

 

オブジェクトの扱い

R におけるオブジェクトの扱いは非常に動的。

> a <- 100

> # いきなり a をベクトルと見なし、2 番目の要素を飛ばして代入
> a[3] <- 200
> # 飛ばされた 2 番目の要素は NA と表示される。
> a
[1] 100  NA 200

> # 次の要素に文字列を入れてみる
> a[4] <- "hoge"

> # お!(@_@;) 要素が文字列に変換された
> a
[1] "100"  NA     "200"  "hoge"

> # では今度は数値を入れてみる。
> a[5] <- 300

> # すると文字列として要素に格納された。
> a
[1] "100"  NA     "200"  "hoge" "300" 

> # 大きさを指定することによって、ベクトルの大きさを変更できる。
> length(a) <- 3
> a
[1] "100" NA    "200"

ところで話は変わるが、前回見たベクトルの要素の取得に、こんな方法もあった。

> a
 [1]  1  2  3  4  5  6  7  8  9 10
> a <- a[2 * 1:5]
> a
[1]  2  4  6  8 10
> a <- 1:10
> a <- a[2 * 2:5]
> a
[1]  4  6  8 10
> a <- 1:10
> a <- a[2 * 3:5]
> a
[1]  6  8 10
> a <- 1:10
> a <- a[3 * 2:5]
> a
[1]  6  9 NA NA

変数[step * from:to]

といった感じ。ただし、ベクトルの要素を、step ごとに抽出した、ベクトルのインデックスの from から to まで。

 

属性

オブジェクトの属性について、全て知りたい場合は attributes(object)

設定をするときは、attr(オブジェクト, "属性名") <- 値

> p1 <- "Tarou"
> attr(p1,"age") <- 20
> p1
[1] "Tarou"
attr(,"age")
[1] 20
> attributes(p1)
$age
[1] 20

サンプルとして書かれていたものは、dim 関数が使われていた。 属性に関数を設定しているということかな?

dim は R: Dimensions of an Object によると、オブジェクトの「ディメンション」を設定するようだけれど、ディメンションって何だろう (@_@;) ヘルプにあるサンプルを見て試してみる。

> x <- 1:12 ; dim(x) <- c(3,4)
> x
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12

> # 次元(?)を増やしてみると...
> x <- 1:12 ; dim(x) <- c(3,2,2)
> x
, , 1

     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6

, , 2

     [,1] [,2]
[1,]    7   10
[2,]    8   11
[3,]    9   12

動作を見ると、dim はベクトルに対して、任意の次元でベクトルを分割させて表示するために使われるようだ。注意することは、次元の要素をすべて掛けたときに、元のベクトルの要素の数と同じになること。

先ほどの属性の話に戻ると、サンプルでは、dim を任意のオブジェクトに attr を使って設定していた。

> a <- 1:12
> a
 [1]  1  2  3  4  5  6  7  8  9 10 11 12
> attr(a,"dim") <- c(3,4)
> a
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
> attributes(a)
$dim
[1] 3 4

オブジェクトに関数を設定すると、それに応じた表現で中身が表示されるということか。つまり、ダックタイピング

 

クラス

すべてのオブジェクトはクラスを持ち(?)、 class() 関数 によってそのクラスを知ることができる。これにより、データの種類が異なっても、同じ関数名で種類に応じて異なる振る舞いをさせることがきる。

 

2. Factor

factor は、データをカテゴリー化するときに使われるベクトル。

カテゴリー化したいデータに対して、factor() を適用した後に levels() を適用すると、カテゴリーが返される。

例えば、A ~ C までのクラスがあり、人がそのクラスに所属していることをベクトルで表わすとすると、

> class <- c('A','A','B','A','C','C','B','C','C')
> class
[1] "A" "A" "B" "A" "C" "C" "B" "C" "C"

> # 上記のベクトルに factor を適用すると...
> factor(class)
[1] A A B A C C B C C
Levels: A B C

factor によって Levels が表示されているが、これは levels(factor(class)) によって返される値。

 

tapply()

factor と tapply() を使うと、カテゴリーごとに計算を行うことができる。例えば、上記のクラスに所属している人がテストを受けたとして、各クラスごとに平均点を求めたいとする。テストのデータをクラスのデータと対応するように作成し、それを元にカテゴリーごとに計算を行う。

> test <- c(80,90,70,65,89,67,45,34,90)

> tapply(test,class,mean)
       A        B        C 
78.33333 57.50000 70.00000 

tapply(計算対象のベクトル, カテゴリー, 計算) 。カテゴリーは、与えられたベクトルを必要に応じて as.factor() によって求めるようになっているようだ。 ( R: Apply a Function Over a “Ragged” Array )

カテゴリーは複数設定できる。例えば、上記では人 (のテストデータ) に対してクラスというカテゴリーを想定したが、これに加えて「性別」情報があったとする。この場合、factor のリストを与えることによって、それぞれのカテゴリごとに計算が行われる。

> sex <- c('M','M','M','M','F','F','F','F','F')

> tapply(test,list(class,sex),mean)
   F        M
A NA 78.33333
B 45 70.00000
C 70       NA

2008年7月14日月曜日

An Introduction to R を読む (1) – R の環境とベクトル

R のインストールと手始めに「平均、分散、標準偏差」を求める のつづき

1. An Introduction to R から読んでいく

R に慣れるために、入門書から目を通していくことにした。

本家ドキュメントの筆頭にあった

を読んでいく。

はじめは、「R という環境の使い方」と、基本的なデータ型である「ベクトル」が対象。

 

2. R という環境の使い方

セッションの保存と復元

R は、言語というよりも、環境と見なすことができる。

  1. 分析を行うとき、作業はディレクリ単位で行い、
  2. 行った分析のデータ等は、セッションとして、ワーキングディレクトリに保存される。

分析をするときは、分析ごとにディレクトリを作成するのがよい。現在、分析の場となっているディレクトリを

ワーキングディレクトリ

と言う。ワーキングディレクトリを変更するには、メニューより、

  • File > Change dir…

で、ディレクトリを指定する。

セッションを、ワーキングディレクトリに保存すると、二つのファイルが作成される。

  • .RData
  • .Rhistory

.RData をダブルクリックすると、そのディレクトリに保存したセッションが、復元された状態で R が起動される。

初回の起動では、ワーキングディレクトリが My Documents の直下に作成された。

 

ヘルプの使い方

次に、ヘルプの使い方を覚えておく。

例えば、mean 関数のヘルプを見たいとき、

help(mean)

?(mean)

文法などを知りたいときは ” ” で囲む。

help(“if”)

を見たい場合は、

example(mean)

 

コマンドの使い方
  1. 改行または ; によって一つのコマンドを区切る。
  2. グループ化するときは、{} を使う。
  3. 先頭を # にすると以降はコメントになる。
  4. カーソルキーの上下でコマンドのヒストリーを辿ることができる。

コマンドを、外部ファイルとして保存する場合、

  • File > New Script

で R Editor を開き、例えば、次のように書いたとする。

a <- c(1,2,3,4,5,6)
print(mean(a))
plot(a)

上記を test.R というファイル名で保存した場合、このスクリプトを実行するには、

source("test.R")

または、 File > Source R code... によって test.R を開く。

 

実行結果をファイルに保存

結果をファイルに出力するためには、

  • sink("ファイル名")

例えば、次のように利用する。

> sink("result.txt")
> a <- c(1,2,3,4,5,6)
> print(mean(a))
> print(sd(a))
> sink()

最後の sink() の呼出しによってレコーディングは終了する。

上記の場合、実行した結果は result.txt に書き込まれる。

 

セッション中のオブジェクトの情報を取得

セッション中に作成したオブジェクトはすべて保存されいる。

objects() によって、作成したオブジェクトの名前を表示させることができる。

削除するには rm()

 

3. ベクトル

ベクトルの生成と代入

ベクトルは R において、データをまとめるときに使う、基本となるデータ型。

ベクトルの作成は c() によって行う。

c(1,2,3,4,5)

以下の 3 つの方法は、それぞれ x にベクトルを代入している。

x <- c(1,2,3,4,5)
assign("x", c(1,2,3,4,5))
c(1,2,3,4,5) -> x

ベクトルが代入されている変数を使って、新しく変数に代入した場合、元のベクトルのコピーが渡される。

> c(1,2,3,4,5) -> a
> a
[1] 1 2 3 4 5
> b <- c(a,a)
> b
 [1] 1 2 3 4 5 1 2 3 4 5
> rm(a)
> b
 [1] 1 2 3 4 5 1 2 3 4 5

 

ベクトルの演算は、要素が大きい方に合わせられる

ベクトルの演算において、二つのベクトルの大きさが異なる場合、小さい方が大きい方に合わせられる。その際、小さい方のベクトルは、大きい方のベクトルの要素数に合うように、要素が繰り返し生成される。

> a <- c(1,2,3,4,5)
> b <- c(10,20,30)
> c <- a + b
Warning message:
In a + b : longer object length is not a multiple of shorter object length
> c
[1] 11 22 33 14 25

上記では、b に代入されたベクトルの方が小さいので、a に代入したベクトルに合わせられる。b は、要素が繰り返され、同じ要素数にされた後、演算が行われている。

同じく、

> a - b
[1]  -9 -18 -27  -6 -15
Warning message:
In a - b : longer object length is not a multiple of shorter object length
> a * b
[1]  10  40  90  40 100
Warning message:
In a * b : longer object length is not a multiple of shorter object length
> a / b
[1] 0.10 0.10 0.10 0.40 0.25
Warning message:
In a/b : longer object length is not a multiple of shorter object length
> a ^ b
[1] 1.000000e+00 1.048576e+06 2.058911e+14 1.048576e+06 9.536743e+13
Warning message:
In a^b : longer object length is not a multiple of shorter object length

 

ベクトルの要素に対する関数

ベクトルの各要素に対して、関数が適用される。

> log(a)
[1] 0.0000000 0.6931472 1.0986123 1.3862944 1.6094379
> exp(a)
[1]   2.718282   7.389056  20.085537  54.598150 148.413159
> sin(a)
[1]  0.8414710  0.9092974  0.1411200 -0.7568025 -0.9589243
> cos(a)
[1]  0.5403023 -0.4161468 -0.9899925 -0.6536436  0.2836622
> tan(a)
[1]  1.5574077 -2.1850399 -0.1425465  1.1578213 -3.3805150
> sqrt(a)
[1] 1.000000 1.414214 1.732051 2.000000 2.236068

 

ベクトル全体から、答えを返す関数

> max(a)
[1] 5
> min(a)
[1] 1
> length(a)
[1] 5
> range(a)
[1] 1 5
> sum(a)
[1] 15
> prod(a)
[1] 120
> var(a)
[1] 2.5

上記の var() は不偏分散。標本分散は、

> sum((a - mean(a)) ^ 2) / length(a)
[1] 2

このように、R は、データをベクトルとして扱えるため、直観的な記述ができる。

 

ソート

> a <- c(3,1,NA,2,5,4)
> sort(a)
[1] 1 2 3 4 5
> sort(a, decreasing=TRUE)
[1] 5 4 3 2 1
> sort(a, na.last=TRUE)
[1]  1  2  3  4  5 NA
> sort(a, na.last=FALSE)
[1] NA  1  2  3  4  5

NA はデータが無効のことを表わす。(R言語 - Wikipedia)。

order と sort.list() は後回し。

max, min の親戚のような pmax, pmin は、ベクトルの個々の要素を対象として max, min を適用し、ベクトルとして返す。

> pmax(c(1,2,3,4,5),3)
[1] 3 3 3 4 5
> pmin(c(1,2,3,4,5),3)
[1] 1 2 3 3 3

複素数の計算は、複素数であることを明示して行う。

複素数 - Wikipedia によると、

複素数(ふくそすう、complex number)は、実数 a, b と虚数単位 i を用いて a + bi の形で表すことのできる数のことである。

> sqrt(-4)
[1] NaN
Warning message:
In sqrt(-4) : NaNs produced
> sqrt(-4+0i)
[1] 0+2i

虚数単位のことを英語で、imaginary unit と言うので (cf. 虚数単位 - Wikipedia) i を付けるのかな。

 

シーケンスの生成

> 1:10
 [1]  1  2  3  4  5  6  7  8  9 10
> seq(1,10)
 [1]  1  2  3  4  5  6  7  8  9 10
> seq(10)
 [1]  1  2  3  4  5  6  7  8  9 10

> # ステップ
> seq(1,10,by=2)
[1] 1 3 5 7 9

> # 降順
> 10:1
 [1] 10  9  8  7  6  5  4  3  2  1

># 大きさを指定
> seq(length=10, from=1)
 [1]  1  2  3  4  5  6  7  8  9 10
> # 大きさと、ステップを指定
> seq(length=10, from=10, by=-2)
 [1] 10  8  6  4  2  0 -2 -4 -6 -8

# 指定した区間における lenght.out で指定した大きさの要素を持つシーケンス
> seq(1,10,length.out=5)
[1]  1.00  3.25  5.50  7.75 10.00

> # 指定したベクトルの要素に沿ったシーケンスを生成
> a <- c(10,20,30,NA,NA,50)
> seq(along.with=a)
[1] 1 2 3 4 5 6

ベクトルを繰り返したものを生成には、

> a
[1] 10 20 30 NA NA 50
> rep(a,3)
 [1] 10 20 30 NA NA 50 10 20 30 NA NA 50 10 20 30 NA NA 50

# それぞれの要素ごとに指定の回数だけ繰り返す。
> rep(a,each=3)
 [1] 10 10 10 20 20 20 30 30 30 NA NA NA NA NA NA 50 50 50

 

論理値を要素に持つベクトル

NA に注意。 SQL の null の扱いと同じかな?(cf. 3値論理 - Wikipedia)

> a
[1] 10 20 30 NA NA 50
> a > 20
[1] FALSE FALSE  TRUE    NA    NA  TRUE
> a <= 20
[1]  TRUE  TRUE FALSE    NA    NA FALSE

AND と OR を適用すると、

> c1 <- c(T,T,F)
> c2 <- c(T,F,F)
> c1 & c2
[1]  TRUE FALSE FALSE
> c1 | c2
[1]  TRUE  TRUE FALSE

NA は値ではなくて、データが無効なものであることのマーカー。だから is.na() を用いて NA かどうか確かめる。

> is.na(c(1,2,NA))
[1] FALSE FALSE  TRUE

# 値ではないので == で比較できない。
> c(1,2,NA) == NA
[1] NA NA NA

NaN : Not a Number

> 0/0
[1] NaN

> Inf - Inf
[1] NaN

文字列の連結。 paste() はベクトルの各々の要素を次のように連結する。

> paste(c("hoge", "piyo"), c("A", "B", "C", "D"))
[1] "hoge A" "piyo B" "hoge C" "piyo D"

># 連結するときの文字列を sep で指定する。 
> paste(c("hoge", "piyo"), c("A", "B", "C", "D"), sep="-")
[1] "hoge-A" "piyo-B" "hoge-C" "piyo-D"

 

ベクトル要素の取得

> a
[1] 1 2 3 4 5

# 条件に合うものを抽出
> a[a>3]
[1] 4 5

> a[a>2 & a<=4]
[1] 3 4

# インデックスで指定
> a[1:3]
[1] 1 2 3

# 必要ない部分をインデックスで指定
> a[-(2:3)]
[1] 1 4 5

指定したインデックスに要素がない場合は NA となる。

> c("Aa","B")[c(1,2,1,2,1,3,1)]
[1] "Aa" "B"  "Aa" "B"  "Aa" NA   "Aa"

インデックスの代わりに、名前で指定して要素を取得する。ハッシュのようなものか。

> persons <- c(15, 20, 22)
> names(persons) <- ("Tarou", "Jirou", "Hanako")
Error: unexpected ',' in "names(persons) <- ("Tarou","
> names(persons) <- c("Tarou", "Jirou", "Hanako")
> persons[c("Jirou","Tarou")]
Jirou Tarou 
   20    15 

NA のデータを 0 に変換する。

> a
[1]  3  1 NA  2  5  4
> a[is.na(a)] <- 0
> a
[1] 3 1 0 2 5 4

 

ベクトル以外の重要なオブジェクト

今後、学習していくもの。

  • matrices, arrays : ベクトルのベクトル。複数のベクトルをまとめたものか。
  • factors : カテゴリーデータを扱う。
  • lists : 要素のタイプが異なってもいい。統計の計算結果を返されるのに使われたりする。
  • data frames : マトリクスに似ているが、列のタイプが異なってもよい。つまり、一行が一観測ユニットのデータで、列が測定対象の属性ということ。
  • 関数はオブジェクトで、プロジェクトのワークスペースに保存される。

関連記事

2008年7月10日木曜日

R のインストールと、手始めに「平均、分散、標準偏差」を求める

1. 統計のためのアプリケーションとして、SAS の代わりに R を使う

統計解析というと、大学時代に、SAS を使ったのを思い出す。あの頃、全く勉強してなかった ^^;

今ではフリーの統計ソフトとして、

R

を使える。いい時代だ。久しぶりに統計のお勉強を。 o(^^)o

R言語 - Wikipedia によると、

R言語の構成には広義の関数型言語の一つであるSchemeの影響があり、リストを基本にした内部処理、遅延評価静的スコープなどの特徴を持つ。

これは、おもしろそうだ。

 

2. R のインストール

より、Download R 2.14.0 for Windows をダウンロードして、インストールした。

 

3. ドキュメントの探し方

R Console において、

help()

と入力すると、マニュアルが表示される。

help(関数名)

により、関数のヘルプを表示。

例えば、平均 のヘルプを見たい場合、

help(mean)

HTML でヘルプを読みたい場合、メニューより

  • Help > html help

Packages > base > M > Mean と辿れる。ただし、これはローカルにあるファイルが表示される。ネット上で読むなら、The R Language 。検索するなら、R: Search Engine

その他、R – Search を見ると、いつくか検索サイトがある。

 

4. 平均、分散、標準偏差を求める

R: Arithmetic Mean によると、

Usage
mean(x, ...)
Arguments

x
An R object. Currently there are methods for numeric data frames, numeric vectors and dates. A complex vector is allowed for trim = 0, only.

Examples
x <- c(0:10, 50)
xm <- mean(x)

 

データをベクターに変換

例を見ると、mean に直接データを渡すのではなく、

C( )

に渡してから、計算が行われている。

c( ) とは、R: Combine Values into a Vector or List によると、

This is a generic function which combines its arguments.

The default method combines its arguments to form a vector.

ベクターに変換する関数のようだ。

データ解析用統計言語Rによる統計的プログラミング: 第1回 豊富な統計機能で遊ぶ によると、

Rでの基本的なデータ・オブジェクトはベクターです。ベクターの変種の幾つかによって、(多次元)配列やデータ・フレーム、(異種)リスト、マトリックスなどのような機能が追加されます。

 

平均

では、平均を求めてみる。

> mean(c(1,2,3,4,5))
[1] 3

 

分散

分散を求める。

R: Variance-Covariance Matrices (deprecated)

> var(c(1,2,3,4,5))
[1] 2.5

ただし、R-Source によると、

データの不偏分散を求める関数 var() は不偏分散を求める関数であって,標本分散を求める関数ではないことに注意.

「不偏分散」については、以下を参考に。正直未だよくわからず... ^^;

 

標準偏差

標準偏差を求める。R: Standard Deviation

> sd(c(1,2,3,4,5))
[1] 1.581139

 

参考

関連記事

(更新日: 2011.12.11)