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 : マトリクスに似ているが、列のタイプが異なってもよい。つまり、一行が一観測ユニットのデータで、列が測定対象の属性ということ。
  • 関数はオブジェクトで、プロジェクトのワークスペースに保存される。

関連記事