[BASIC.1] 変数と代入

コメントアウトは、行頭に # をつけます。

変数 a に 1 を代入してみます。 イコールも矢印もどちらも使えます。 Rでは矢印が一般的ですが、この授業ではイコール記法を採用します。

a <- 1
a = 1

コードを実行するには、実行する行を選択して「⌘RETURN」を押します。 コンソールには、以下のように実行結果が表示されます。 [n] は、先頭の要素がn番目であることを指します。(以下、必要に応じて省略します。)

a
## [1] 1

ピリオドを変数の表記に使うこともできます(ただし先頭は不可)。 セミコロンを使うと、一行に複数の文を並べることができます。

A.a = 0.4; A.b = 0.8
A.a; A.b
## [1] 0.4
## [1] 0.8

大文字と小文字は区別されます。

name = -1; Name = -2
name+1 # 0
## [1] 0
Name+1 # -1
## [1] -1

[BASIC.2] 型

参考:https://qiita.com/maruman029/items/365a2abcdaaf99b720be

a = 1 #整数はデフォルトではdouble型として扱われます
b = 0.2 #double型
c = TRUE; C = T #logical型(T、F表記も可能)
d = 1L #整数型(integer型)として扱いたい時はLをつける
e = "Hello" #character型

データ型は typeof で調べます。

typeof(a) # "double"
## [1] "double"
typeof(b) # "double"
## [1] "double"
typeof(c) # "logical"
## [1] "logical"
typeof(d) # "integer"
## [1] "integer"
typeof(e) # "character"
## [1] "character"

型変換には as.xxx を使います。

a = 1; typeof(a) # "double"
## [1] "double"
b = as.integer(a) #double型からinteger型に変換
b # 1(見た目は1のまま)
## [1] 1
typeof(b) # "integer"
## [1] "integer"
c = as.character(a) #double型からcharacter型に変換
c # "1"(1は"1"に変換されます)
## [1] "1"
typeof(c) # "character"
## [1] "character"

numeric は、integerとdoubleを合わせたカテゴリです。(mode 関数で確認できます)

mode(a) # "numeric"
## [1] "numeric"
mode(b) # "numeric"
## [1] "numeric"

[BASIC.3] 一次元ベクトルの生成

(3.1) 一次元ベクトルを生成する方法

c(n1,n2,n3) で、ベクトルを生成します。(cはcombineに由来)

a = c(1,2,3)
a # 1 2 3
## [1] 1 2 3

以降は、2行分の書き方を簡略表記します。

a = c(1,2,3); a
## [1] 1 2 3
a = c(T,T,F); a
## [1]  TRUE  TRUE FALSE
a = c("T","T","F"); a # 文字列ベクトル
## [1] "T" "T" "F"

c(a:b) で、一次元のベクトル(a, a+1, …, b)を作成します。

a=c(101:105); a
## [1] 101 102 103 104 105

b<a のときは、(a, a-1, …, b)となります。

a=c(9:1); a
## [1] 9 8 7 6 5 4 3 2 1

要素が多い場合は、全ての要素が表示されます(以下は先頭の50要素のみ表示)。

a = c(-3:9999333)
head(a, 50)
##  [1] -3 -2 -1  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21
## [26] 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

ベクトルの長さは length 関数で取得できます。

length(a) # 9999337
## [1] 9999337

c(a,b) の引数が非整数の場合は、 初項a、公差1で、b以下のものを集めたベクトルを返します。

a=c(2.3:4); a # 2.3 3.3
## [1] 2.3 3.3

「:」記法の場合、c は省略できます。

a=101:105; a
## [1] 101 102 103 104 105
a=9:1; a
## [1] 9 8 7 6 5 4 3 2 1
a=2.3:4; a
## [1] 2.3 3.3

seq 関数を使うと、等差数列を作れます。

# 1~10を5分割
a = seq(1,10,length=5); a
## [1]  1.00  3.25  5.50  7.75 10.00
# 1から2ずつ増やして10を越える手前まで
a = seq(1,10,by=2); a
## [1] 1 3 5 7 9

rep 関数を使うと、繰り返しのベクトルを作れます。

# (1,2,3)を3回
a = rep(1:3,times=3); a
## [1] 1 2 3 1 2 3 1 2 3
# (1,2,3)を要素数5となるまで繰り返す
a = rep(1:3,length=5); a
## [1] 1 2 3 1 2

無作為サンプリング関数(sample)を使ってみましょう。

サイコロを1回振ります。実行のたびに結果はランダムに変わります。

a = sample(1:6,1); a
## [1] 3
a = sample(1:6,1); a
## [1] 4

1~6から無作為サンプルを6回とります(重複なし)。

a = sample(1:6,6); a
## [1] 4 2 1 3 5 6

母数よりサンプル数が多いと、エラーになります。

a = sample(1:6,7)
## Error in sample.int(length(x), size, replace, prob): 'replace = FALSE' なので、母集団以上の大きさの標本は取ることができません

replace を TRUE にセットすると、重複ありモードになります。

a = sample(1:6,7,replace = TRUE); a
## [1] 3 4 1 6 4 5 2

空のベクトルを作成します。

## integer型の空のベクトルを生成(中身は空)
a=vector("integer"); a
## integer(0)
## logical型の空のベクトルを生成(中身は空)
a=vector("logical"); a
## logical(0)

第2引数でベクトルの長さを指定します(初期値は0)。

a=vector("integer",10); a
##  [1] 0 0 0 0 0 0 0 0 0 0

logical型の場合、初期値は FALSE です。

a=vector("logical",10); a
##  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

(3.2) アトミックベクトルの性質

Rでは、全てのメンバが同じ型を持つタイプのベクトルを、アトミックベクトルと呼びます。 後で示すように、アトミックベクトルは一次元ベクトルとは限りません。

アトミックベクトルかどうかは is.atomic で確認できます。

a1=2:5; is.atomic(a1) # TRUE
## [1] TRUE

リストはアトミックベクトルではありません(次週学びます)。 (参考)リストは複数の型を扱います。

a2=list(2:5,"R"); is.atomic(a2) # FALSE
## [1] FALSE

データフレームもアトミックベクトルではありません(次週学びます)。

a3=data.frame(c(1,2),c("KODAKA","KENRI"))
is.atomic(a3) # FALSE
## [1] FALSE

(参考)is.vector は、名前以外の属性を持つかを調べます。 リストも大きな枠では「ベクトル」に含まれます。

is.vector(a1) # TRUE
## [1] TRUE
is.vector(a2) # TRUE
## [1] TRUE
is.vector(a3) # FALSE
## [1] FALSE

アトミックベクトルの型は typeof で調べます。

a=c(T,T,F); b=c(101:105)
typeof(a) # "logical"
## [1] "logical"
typeof(b) # "integer"
## [1] "integer"

異なる型を入れた場合、適当な型に型変換されます。 以下では、T と 102 は文字列型(character)に型変換されます。

a=c(T,102,"hello")
typeof(a) # "character"
## [1] "character"
a[1] # "TRUE"
## [1] "TRUE"
a[2] # "102"
## [1] "102"
a[3] # "hello"
## [1] "hello"

数値も、要素1のベクトルです。

a=2
is.atomic(a) # TRUE
## [1] TRUE
a[1] # 2
## [1] 2

(3.3) ベクトルの結合

a1 に2つの要素を追加してみます。

a1 = c(101:105)
a2 = c(a1,201,202); a2
## [1] 101 102 103 104 105 201 202

append 関数を使って結合することもできます。

a = c(101:104)
b = c(301:302)
## aとbを結合
append(a,b)
## [1] 101 102 103 104 301 302
## 2番目の要素の後ろに挿入
append(a,b,after=2)
## [1] 101 102 301 302 103 104
## afterのデフォルトは length(a)
append(a,b,after=length(a))
## [1] 101 102 103 104 301 302

ベクトルの要素に、ベクトルを指定してみます。

a1 = c(101:105)
## a2の2番目の要素にa1を追加
a2 = c(201,a1,202); a2
## [1] 201 101 102 103 104 105 202

この場合、a2の要素数は7となり、 例えばa1の3番目の要素(103)は、a2の4番目の要素となります。

a2[4] # 103
## [1] 103

多次元配列の様な構造を持つことはできません。 よって以下の様な書き方をしても、103とはなりません。

a2[2][3] # NA
## [1] NA

要するに、一次元ベクトルの要素に別の一次元ベクトルを配置すると、 新しいサイズの一次元ベクトルが作られます。

a1 = c(101:105); a1
## [1] 101 102 103 104 105
a2 = c(201,a1,202); a2
## [1] 201 101 102 103 104 105 202
a3 = c(301,a2,302); a3
## [1] 301 201 101 102 103 104 105 202 302

(3.4) ベクトルの要素抽出・置換

n番目の要素を取り出します。

a=101:105
a[3] # 103
## [1] 103

n番目の要素を書き換えます。

a=101:105; a[3] = 3
a # 101 102 3 104 105
## [1] 101 102   3 104 105

複数の要素をまとめて取り出す/取り除くこともできます。

a=101:105
# 2番目と4番目の要素を取り出してベクトルにする
a[c(2,4)]
## [1] 102 104
# 2番目と4番目の要素を取り除く
a[c(-2,-4)]
## [1] 101 103 105
# 範囲外はNA
a[4:8]
## [1] 104 105  NA  NA  NA

特定の条件を満たす要素のみを取り出す時は、 which() 関数で、引数に条件を記述します。

a=101:120
## 10を引いて105となる要素の添字を取り出す
which(a-10==105) # 15
## [1] 15

添字が存在しない場合、空の整数ベクトルが返されます。

## 10を引いて120となる要素の添字を取り出す
which(a-10==120) # integer(0)
## integer(0)

which と組み合わせると、条件を満たす要素そのものを取り出せます。

## aの要素のうち、10を引いて105となる要素を取り出す
a[which(a-10==105)] # 115
## [1] 115
## aの要素のうち、10を引いて120となる要素を取り出す(存在しない)
a[which(a-10==120)] # integer(0)
## integer(0)

整数商は「%/%」、割った余りは「%%」です。 例えば、17わる3は、5余り2です。

17 %/% 3 # 5
## [1] 5
17 %% 3 # 2
## [1] 2

これを使うと、次のようなことができます。

a=101:125
## 偶数の要素のみを取り出す
a[which(a%%2==0)]
##  [1] 102 104 106 108 110 112 114 116 118 120 122 124
## 103で割った商が1より小さい要素を集める
a[which(a%/%103<1)] # 101 102
## [1] 101 102

[BASIC.4] ベクトルの演算

(4.1) 四則演算と剰余

ベクトルに対する演算は、全ての要素に対して一度に適用されます。

dice=1:6 # 1 2 3 4 5 6
dice-1
## [1] 0 1 2 3 4 5
dice/2
## [1] 0.5 1.0 1.5 2.0 2.5 3.0
dice * dice
## [1]  1  4  9 16 25 36
dice %% 3 # 3で割った余り
## [1] 1 2 0 1 2 0

(4.2) リサイクル規則

ベクトルのサイズが異なる場合の演算は、 短い方のベクトルの要素が繰り返し使われます。

x = c(2,2,3,3,4,4)
y = c(0.1,0.2)
z = x+y; z
## [1] 2.1 2.2 3.1 3.2 4.1 4.2
z = x*y; z
## [1] 0.2 0.4 0.3 0.6 0.4 0.8

(4.3) 比較演算と論理演算

ベクトルを比較すると、結果は論理値(TRUE/FALSE)のベクトルになります。

dice = 1:6
dice > 3    # 3より大きいか
## [1] FALSE FALSE FALSE  TRUE  TRUE  TRUE
dice == 3   # 3と等しいか(イコールは2つ)
## [1] FALSE FALSE  TRUE FALSE FALSE FALSE
dice != 3   # 3と等しくないか
## [1]  TRUE  TRUE FALSE  TRUE  TRUE  TRUE

比較演算子は > >= < <= == != です。 代入の = と、比較の == を混同しないようにしましょう。

複数の条件を組み合わせるには、論理演算子を使います。

  • &:かつ(AND)
  • |:または(OR)
  • !:ではない(NOT)
# 3以下 かつ 偶数
(dice <= 3) & (dice %% 2 == 0)
## [1] FALSE  TRUE FALSE FALSE FALSE FALSE
# 1 または 6
(dice == 1) | (dice == 6)
## [1]  TRUE FALSE FALSE FALSE FALSE  TRUE
# 3より大きくない
!(dice > 3)
## [1]  TRUE  TRUE  TRUE FALSE FALSE FALSE

それぞれの条件は、カッコで囲んでおくと安全です。

論理ベクトルを添字に使うと、条件を満たす要素だけを取り出せます。 これは、(3.4)で学んだ which() を使った方法と同じ結果になります。

a = 101:110
a > 105             # 論理ベクトル
##  [1] FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE
which(a > 105)      # TRUEの要素の添字
## [1]  6  7  8  9 10
a[which(a > 105)]   # (3.4)の方法
## [1] 106 107 108 109 110
a[a > 105]          # 論理ベクトルを直接添字にする(こちらが一般的)
## [1] 106 107 108 109 110
a[a %% 2 == 0]              # 偶数
## [1] 102 104 106 108 110
a[a > 103 & a %% 2 == 0]    # 103より大きい偶数
## [1] 104 106 108 110

TRUE は 1、FALSE は 0 として計算されるため、 sum や mean で「条件を満たす要素の個数・割合」を数えられます。

sum(a > 105)    # 105より大きい要素の個数
## [1] 5
mean(a > 105)   # その割合
## [1] 0.5

[BASIC.5] ベクトルに適用される関数

(5.1) 基本統計系

vec = 1:6
sum(vec) # 21(総和)
## [1] 21
mean(vec) # 3.5(平均)
## [1] 3.5
round(mean(vec)) # 4(四捨五入)
## [1] 4
min(vec) # 1(最小値)
## [1] 1
max(vec) # 6(最大値)
## [1] 6

(5.2) 論理ベクトル系

  • any(x):1つでも TRUE があるか
  • all(x):すべて TRUE か
x = c(TRUE, FALSE, TRUE)
any(x) # TRUE
## [1] TRUE
all(x) # FALSE
## [1] FALSE
## 3で割り切れる数字が一つでもあるか?
any(c(2,3,5,7,11,13) %% 3 == 0) # TRUE
## [1] TRUE
## 全て3で割り切れるか?
all(c(2,3,5,7,11,13) %% 3 == 0) # FALSE
## [1] FALSE

(5.3) 関数と引数

ランダムサンプリング(既出)です。実行のたびに結果は変わります。

sample(1:4, 2)
## [1] 2 3
sample(1:4, 2)
## [1] 2 3

引数を明示して関数を実行します。(x と size は引数の名前として指定) 名前が無いもの(1:4)は、x として扱われます。 sample の場合、x が引数のデフォルト値です。

sample(x=1:4,size=2)
## [1] 2 1
sample(size=2,1:4)
## [1] 3 4

関数の引数の名前(および引数のデフォルト値 + 引数の順序)は args で調べます。

args(sample)
## function (x, size, replace = FALSE, prob = NULL) 
## NULL
args(append)
## function (x, values, after = length(x)) 
## NULL

replace は、同一の値のサンプリングを許可するかを指定します。

sample(1:4, replace=TRUE)
## [1] 4 2 2 1
sample(1:4, replace=TRUE)
## [1] 2 2 4 3

名前がなければ、2番目の引数は size が期待されるため、エラーとなります。

sample(1:4, TRUE)
## Error in sample.int(length(x), size, replace, prob): 'size' 引数が不正です

誤った引数の名前も、エラーとなります。

sample(1:4,saizu=2)
## Error in sample(1:4, saizu = 2): 使われていない引数 (saizu = 2)

(5.4) NA(欠損値)

NA は「値がない(不明)」ことを表す特別な値です。 (3.4)で、範囲外の添字を指定したときにも NA が返りました。

x = c(3, NA, 5)
x
## [1]  3 NA  5

NA を含む計算の結果は、NA になります。

NA + 1
## [1] NA
sum(x)
## [1] NA
mean(x)
## [1] NA

na.rm=TRUE を指定すると、NA を取り除いて計算します。

sum(x, na.rm=TRUE)
## [1] 8
mean(x, na.rm=TRUE)
## [1] 4

NA かどうかは、== ではなく is.na() で調べます。

x == NA        # 常に NA になってしまい、判定できない
## [1] NA NA NA
is.na(x)       # NAの要素が TRUE
## [1] FALSE  TRUE FALSE
x[!is.na(x)]   # NAではない要素だけを取り出す
## [1] 3 5
sum(is.na(x))  # NAの個数
## [1] 1

(参考)NULL は「何もない(空)」ことを表し、長さは0です。NA は長さ1の値です。

length(NA)
## [1] 1
length(NULL)
## [1] 0

[BASIC.6] 配列

(6.1) 配列の基本

アトミックベクトルを、2行3列の配列に変換します。

a = array(1:6,dim=c(2,3))
a
##      [,1] [,2] [,3]
## [1,]    1    3    5
## [2,]    2    4    6
is.array(a) # TRUE(aは配列)
## [1] TRUE
is.atomic(a) # TRUE(aはアトミックベクトルのまま)
## [1] TRUE
length(a) # 6(長さは6)
## [1] 6

配列の要素は、行と列の添字で指定できます。

a[2,1] # 2(2行1列目の要素)
## [1] 2
a[2,3] # 6(2行3列目の要素)
## [1] 6
a[4] # 4(a[2,2]に同じ)
## [1] 4
a[5] # 5(a[1,3]に同じ)
## [1] 5

行や列をまとめて取り出すこともできます。

a[2,] # 2行の要素群
## [1] 2 4 6
a[,3] # 3列の要素群
## [1] 5 6
a[,c(1,3)] # 1列目と3列目を切り出す(配列)
##      [,1] [,2]
## [1,]    1    5
## [2,]    2    6

(6.2) コマンドの複製(replicate)

1+1の結果を3回繰り返し、ベクトルにします。

a = replicate(3, 1+1); a
## [1] 2 2 2

サイコロの無作為抽出を10回繰り返します。

a = replicate(10,sample(1:6,1)); a
##  [1] 1 6 2 1 5 6 4 6 1 2

このとき、a は配列ではなく、単なる(一次元)ベクトルです。

is.array(a) # FALSE
## [1] FALSE

要素数n(>1)のベクトルを返す関数をm回 replicate すると、結果はn x mの配列となります。

a = replicate(10,sample(1:6,size=2))
a
##      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,]    4    6    4    4    2    3    5    6    4     2
## [2,]    5    1    1    6    3    4    6    2    5     4
is.array(a) # TRUE(aは配列)
## [1] TRUE
is.atomic(a) # TRUE(aはアトミックベクトル)
## [1] TRUE
length(a) # 20(長さは20(2x10))
## [1] 20

[BASIC.7] 繰り返し文・条件文

(7.1) for 文

1:6 に含まれる個々の要素を a とし、a を出力します(print 関数)。

for(a in 1:6){
  print(a)
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6

for(a in vec) の a は、必ずしも使う必要はありません。 以下は、サイコロの無作為抽出を5回繰り返したものの加算を計算したものです。 Rでは「+=」の記法は使えません。

sum = 0
for(a in 1:5){
  sum = sum + sample(1:6,1)
  print(sum)
}
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8

(7.2) while 文

サイコロの総和が50以上となるまで加算します(while)。

sum=0
while(sum<50){
  sum = sum + sample(1:6,1)
  print(sum)
}
## [1] 3
## [1] 8
## [1] 9
## [1] 11
## [1] 16
## [1] 21
## [1] 26
## [1] 32
## [1] 34
## [1] 39
## [1] 45
## [1] 48
## [1] 52

(7.3) repeat 文

repeat は、while(TRUE) に相当します。 break が実行されるまで、永遠に実行します。 (ここで使っている if は、次の(7.4)で詳しく学びます。)

sum = 0
repeat{
  sum = sum + sample(1:6,1)
  if(sum>50){
    break
  }
  print(sum)
}
## [1] 4
## [1] 6
## [1] 8
## [1] 9
## [1] 14
## [1] 18
## [1] 19
## [1] 24
## [1] 27
## [1] 28
## [1] 30
## [1] 33
## [1] 39
## [1] 41
## [1] 45
## [1] 46
## [1] 50

(7.4) if / else(条件分岐)

条件が TRUE のときだけ処理を実行するには if を使います。

x = 5
if(x > 3){
  print("3より大きい")
}
## [1] "3より大きい"

else を使うと、条件が FALSE のときの処理も書けます。

x = 2
if(x > 3){
  print("3より大きい")
}else{
  print("3以下")
}
## [1] "3以下"

(else は、直前の } と同じ行に書きます。)

条件は else if でいくつでも重ねられます。

x = sample(1:6,1)
print(x)
## [1] 5
if(x == 6){
  print("大当たり")
}else if(x >= 4){
  print("まずまず")
}else{
  print("はずれ")
}
## [1] "まずまず"

for 文と組み合わせると、繰り返しの中で条件を判定できます。

# サイコロを2個振る操作を5回繰り返し、ゾロ目のときだけメッセージを出す
for(i in 1:5){
  d = sample(1:6, size=2, replace=TRUE)
  print(d)
  if(d[1] == d[2]){
    print("ゾロ目!")
  }
}
## [1] 2 3
## [1] 6 1
## [1] 4 2
## [1] 4 4
## [1] "ゾロ目!"
## [1] 1 1
## [1] "ゾロ目!"

注意:if の条件には、長さ1の論理値しか使えません。 複数の要素を持つベクトルを渡すとエラーになります。

x = 1:6
if(x > 3){
  print("3より大きい")
}
## Error in if (x > 3) {: the condition has length > 1

2つの条件を組み合わせるときも、if の中では &&(かつ)と ||(または)を使います。 & と | は、ベクトルの要素ごとの演算に使います。

x = 4
if(x > 3 && x %% 2 == 0){
  print("3より大きい偶数")
}
## [1] "3より大きい偶数"

(7.5) ifelse(ベクトルに対する条件分岐)

ベクトルの要素ごとに条件を判定して値を切り替えるには、ifelse(条件, TRUEのとき, FALSEのとき) を使います。

x = 1:6
ifelse(x > 3, "大", "小")
## [1] "小" "小" "小" "大" "大" "大"
ifelse(x %% 2 == 0, "偶数", "奇数")
## [1] "奇数" "偶数" "奇数" "偶数" "奇数" "偶数"
d = sample(1:6, 10, replace=TRUE)
d
##  [1] 3 3 2 3 3 4 6 1 6 4
ifelse(d >= 4, "高", "低")
##  [1] "低" "低" "低" "低" "低" "高" "高" "低" "高" "高"

ifelse は、次回以降に学ぶデータフレームの列を作るときにも、形を変えて何度も登場します。

[BASIC.8] 関数定義(独自の関数をつくる)

(8.1) 関数の定義

2個のサイコロを振って、総和を得るプログラムです。

dice = 1:6
dice2 = sample(dice, size=2, replace = TRUE)
sum(dice2)
## [1] 5

これを roll() として関数化します。

roll = function(){
  dice = 1:6
  dice2 = sample(dice, size=2, replace = TRUE)
  sum(dice2)
}

関数定義の最後の行が返り値となります。 基本的に、return は書きません。

for(i in 1:3){
  ret = roll()
  print(ret)
}
## [1] 8
## [1] 6
## [1] 9

n個のサイコロを振って、総和を得るプログラムです。 引数ありの関数をつくります。

roll.n = function(n){
  dice = 1:6
  dice2 = sample(dice, size=n, replace = TRUE)
  sum(dice2)
}

ただし、関数の途中で処理を打ち切って値を返したいときには、return() を使います。 return() が実行された時点で、関数はそこで終了します。

roll.safe = function(n){
  if(n < 1){
    return(NA)   # ここで関数を終了し、NAを返す
  }
  dice = 1:6
  dice2 = sample(dice, size=n, replace = TRUE)
  sum(dice2)     # 最後の行が返り値
}
roll.safe(3)
## [1] 14
roll.safe(0)
## [1] NA

サイズ10の、全ての要素がゼロのベクトルを生成します。

result = vector("integer",10)
result = vector(mode="integer",length=10) #同じです
for(i in 1:10){
  result[i] = roll.n(i)
}
result
##  [1]  5  8  8 19 14 22 24 19 27 31

roll 関数を1000回繰り返し、一次元ベクトルに格納します。

rolls = replicate(1000, roll())
head(rolls, 50)
##  [1]  8  4  3  9  4 10  7  8 10  4  9 10  5  6  9  4  6  7  8  5  5  6  6  9  6
## [26]  6  7 10  8  6  5 11  5  6  6 12 10  8  5 10  4  5  5 11  4  7  6 11 11  4

for 文で書き直すこともできます(同じことです)。

rolls=vector("integer",1000)
for(i in 1:1000){
  rolls[i] = roll()
}

(8.2) ヒストグラムの計算

roll 関数を使って、ヒストグラムを計算します。 中身が0の、長さ12のベクトルをつくります。

imax = 10000
rolls = replicate(imax, roll())

hi=vector("integer",12)
for(i in 1:imax){
  hi[rolls[i]] = hi[rolls[i]]+1
}
hi
##  [1]    0  273  514  900 1077 1425 1719 1388 1069  770  580  285

この結果を、棒グラフ(barplot)で可視化します。

  • main はタイトル
  • names.arg はx軸の値
  • ylab はy軸のラベル
barplot(hi, main="Double dice",names.arg=1:12, ylab="Frequency")

hist 関数を使うと、サンプルベクトルから自動でヒストグラムを生成できます。

  • breaks は区切りのベクトル
  • xlim/ylim はx/yの範囲
hist(rolls,breaks=0:13,xlim=c(0,12),ylim=c(0,2000))