あるデータセットの特徴を把握するときに用いられる統計量。元のデータから算出される。なお、ここではデータとは数値のみで構成されているものとする。
以下では実際に次のデータ【04_example.csv】を使って例を示していく。このデータを右クリックメニューからダウンロードしたうえで,自分自身のPosit CloudのProjectに前回の要領でアップロードしておくこと.
Shohoku <- read.csv("practice/04_example_Shohoku.csv", header = TRUE, fileEncoding="UTF8")
Shohoku
## nam number score
## 1 赤木 4 7
## 2 桜木 10 4
## 3 三井 13 10
## 4 宮城 7 7
## 5 流川 11 9
## 6 木暮 5 6
## 7 潮崎 8 6
## 8 安田 6 7
## 9 角田 9 7
## 10 石井 12 5
## 11 佐々岡 13 5
## 12 桑田 15 4
fileEncoding="SJIS"
というオプションを追加して読み込むことで文字化けを防ぐことができる.
以降は、前々回紹介したRMarkdownを作成し、上記の内容を含めて自分で入力・実行して出力結果を確認しながら進めていくこと。
あるデータセットの全体的な特徴を一番端的に表現する値であり、文字通りデータセットを「代表」する値。平均、中央値、最頻値の3種類がある。
すべてのデータ(数値)を足し合わせて、データの数で割った値のこと。
\[
\bar{x} =\frac{1}{n}\sum^{n}_{i=1}x_{i}
\] Rで求めるにはmean()
関数を用いる。
example<-c(1,2,3,4,5) # 例として1,2,3,4,5という5つの数値からなるベクトルを使った
mean(example)
## [1] 3
mean(Shohoku$score) #先ほどの湘北高校バスケ部のフリースロー10本勝負のスコアの平均
## [1] 6.416667
なお、実際のデータを扱う際には、CSVファイルやExcelファイルからデータを読み込むことが多くなる。そうしたデータファイルにはたまに「空白」が含まれているケースがある(例えばアンケートで無回答だったり、実験で計測に失敗したりした場合)。その場合、Rにそれらのデータを読み込むと、空白だった箇所にはNA
(Not
Available:利用不可能という意味)という記号が自動的に入力される。
mean()
関数を用いる際に、与えたベクトルにNA
が含まれていた場合、Errorにはならないが出力はNA
となる。
このようなデータの場合には、以下のようにna.rm
オプションをTrue
(真)に設定する。するとNAを除いた上で平均が算出される(当然、データの総数はNAの数の分だけ減ることになる)。
example<- c(1,2,3,4,NA)
mean(example) #NAが含まれているのでNAが出力される
## [1] NA
example<- c(1,2,3,4,NA)
mean(example, na.rm = T)
## [1] 2.5
全てのデータ(数値)を数の大小で順に並べ、ちょうど中央の順位に来る数値。データ点数が偶数だった場合には、中央の位置の前後の数の平均値を中央値とする。
Rではmedian()
を用いる
median(Shohoku$score)
## [1] 6.5
先の湘北高校のデータは12人分なので、中央値は6位と7位の間をとることになるため、小数の値が出てきている。
全てのデータ(数値)について、度数分布をとり、最も度数が大きい(出現頻度が最も多い)数値。
Rでは最頻値を直接求める関数は存在しない。そのため、まずはtable()
コマンドを使って、対象となるデータの度数分布表を求める。
次いで、その度数分布表で度数が最も高いものを求める、という手続きで算出する。
ただし、度数分布表で最も度数が高いものを取り出したときのデータは名前付きベクトルで出力され、最頻値を表す値は度数値に対する「名前」(すなわち文字列)として出力れる。そこでその名前を数値として読みなおす必要がある。
以下は例である。行っている一連の処理をよく確認しておくこと。
table_data<-table(Shohoku$score) # 度数分布表を作成
print(table_data)
##
## 4 5 6 7 9 10
## 2 2 2 4 1 1
d<-which.max(table_data) ##度数分布表から最も度数が高い値を取り出す
print(d) # 7と4が表示されている。わかりにくいが、これは"7"という名前の付いた列に4という度数データが入っている、ということを表している。ここで"7"は数値ではなく文字列である。
## 7
## 4
mode<-as.numeric(names(d)) #欲しいのは値としての7なので、names()を掛けた後に、as.numeric()を行っている。
print(mode)
## [1] 7
ちなみに、上記のスクリプトファイルは細かく一つ一つ分けて書いているが、以下のように関数の中に関数を入れることで、シンプルに書くことができる。このように関数が入れ子になっている場合、内側の関数から順次実行される。
as.numeric(names(which.max(table(Shohoku$score))))
## [1] 7
さらには、tidyvers
というライブラリを読み込んでおくことによって、以下のような書き方もできる。なお、初めてTidyverseを使う場合には、library(tidyverse)を読み込んだときにパッケージのインストールをするかどうか聞かれるので、installを選択しておく。tidyverseについては後ほど別章で詳しく説明する。
library(tidyverse)
Shohoku$score %>%
table() %>%
which.max() %>%
names() %>%
as.numeric()
## [1] 7
正規分布のように左右対象の一山の度数分布をしていた場合には、平均値・中央値・最頻値は全てほぼ一致する。
一方、次の図のように左右非対称であった場合には、平均値・中央値・最頻値は一致しなくなる。
あるデータセットがどの程度ばらつき(広がり)を持っているのかを示す指標。平均系の平均偏差・分散・標準偏差と、中央値系の四分位数とがある。
平均偏差とは、データ全体の平均値を予め求めておいた上で、各データと平均値との距離(差の絶対値)を全てのデータに対して求め、その平均をとったもの。
\[
M.A.D =\frac{1}{n}\sum^{n}_{i=1}|x_{i} - \bar{x}|
\] Rではmad()
関数を用いる。
MAD <- mad(Shohoku$score)
print(MAD)
## [1] 1.4826
平均偏差は数式のなかに絶対値記号が入ってきて、数値計算が非常に面倒になる。絶対値を加えたのは単純に\(x_{i}-\bar{x}\)を求めると\(x_{i}\)によっては負の数字になるからである。負を正にするためだけなら、\(x_{i}-\bar{x}\)を2乗するということでもよい。そこで、「差の絶対値」ではなく「差の2乗」の平均値をばらつきの指標としたものが分散(Variance)である。一般に \(S^{2}\)と表現する。
「2乗の平均」にしたことによって数値自体の絶対的な意味の解釈は難しくなる。すなわち、例えば元々は平均値からの距離が1,2,3のデータはそれぞれ等間隔で平均から離れていることになるが、これを2乗すると1,4,9となり等間隔ではなくなる。このように、平均から離れれば離れるだけより大きな値になってしまって、数値自体の絶対的な意味が分かり難くなってしまう。ただ、少なくとも2つのデータセットがある時に、どちらのデータのほうがよりばらついているかは分散の値を比較することによって知ることができる。
\[ S^{2} = \frac{1}{n}\sum^{n}_{i=1}(x_{i}-\bar{x})^2 \]
Rではvar()
関数とnrow()
関数を用いて以下のように書く。nrow()
はデータフレームの行数、すなわちデータフレームに含まれているサンプル数を返す関数である。複雑な式に見えるが、要するに、\(\frac{データ数-1}{データ数}\)をvar()
に掛けているということである。これはvar()
関数は不偏分散を算出する関数であり、データそのものの分散(標本分散)を算出するためには、補正をしてやる必要があるためである。不偏分散については後ほど改めて説明する。
s2<- var(Shohoku$score)
n <- nrow(Shohoku)
VAR <- (n-1)/n*s2
print(VAR) #こちらが標本分散
## [1] 3.076389
分散の場合、先に述べた通り、距離(差)の2乗にしてしまっているので、元のデータと次元が異なってしまい、出てきた数値が何を意味しているかがにわかには分からない。そこで分散の平方根を取ることによって、元のデータと同じ次元の数値として、元のデータと比較したり平均と組み合わせられるようにしたものが標準偏差(Standard Deviation)である。一般に\(S\)と表現する。
\[ S=\sqrt{S^{2}} = \sqrt{\frac{1}{n}\sum^{n}_{i=1}(x_{i}-\bar{x})^2} \]
Rではsd()
関数を用いるが、データそのものの標準偏差を得たい場合には分散の時と同様にnrow()
関数を用いた補正(標準偏差の場合にはさらに平方根を求める関数sqrt()
も用いる)をしてやる必要がある。
s <- sd(Shohoku$score) # こちらのsは小文字
S <- sqrt((n-1)/n)*s # nは先に求めたnrow()関数の出力。
print(S)
## [1] 1.753964
標準偏差は「ばらつき」の単位(ものさし)として用いることが一般的である。データが完全に正規分布をしていた場合、次の図のように、平均値から±1Sだけ離れたところに境界を引くと、その境界内には全データの約68.27%のデータが含まれる。同様に±2Sの範囲内であれば約95.45%のデータが、±3Sになると約99.73%のデータが含まれることになる。
平均\(\bar{x}\)を基準(すなわち0)とし、それぞれのデータの値\(x_{i}\)と平均との距離を標準偏差\(S\)を単位として表現した値。要するに、そのデータ全体の中で、あるデータ値が相対的にどのくらいの位置にあるのかを表した値のことを標準化得点、もしくは正規化得点と呼ぶ。一般に\(z_{i}\)と表現する。さらに、こうした処理を行うことを標準化、あるいは正規化と呼ぶ。 \[ z_{i} = \frac{x_{i}-\bar{x}}{S} \]
Rで標準化を行う場合、scale()
関数を用いればよい。
z <- scale(Shohoku$score)
print(z)
## [,1]
## [1,] 0.3184211
## [2,] -1.3191733
## [3,] 1.9560156
## [4,] 0.3184211
## [5,] 1.4101508
## [6,] -0.2274437
## [7,] -0.2274437
## [8,] 0.3184211
## [9,] 0.3184211
## [10,] -0.7733085
## [11,] -0.7733085
## [12,] -1.3191733
## attr(,"scaled:center")
## [1] 6.416667
## attr(,"scaled:scale")
## [1] 1.831955
出力結果の上12個は各データ値を標準化した値である。続いて、attr()
にあるのは、それぞれ標準化に用いた平均値と標準偏差である。先ほど求めた平均、標準偏差と比べてみると、平均は一致しているが標準偏差は異なる。これは、scale()
関数が内部で計算に用いている標準偏差は、あくまで補正の掛けない不偏標準偏差、すなわちsd()
関数の結果をそのまま計算に用いているからである。実際に、先ほどsd()
関数の結果を格納したs
(小文字)をプリントさせてみると、同じ値が出力される。
print(s)
## [1] 1.831955
全てのデータ(数値)を小さいものから順に並べ、最小値(0%)、下位25%、中央値(50%)、上位25%、最大値(100%)の順位に来る数値のことをまとめて四分位数と呼ぶ。特に下位25%を第1四分位数、上位25%を第3四分位数と呼ぶ。 分散と標準偏差が平均値を代表値とした場合のばらつきの指標であるのに対して、中央値を代表値とした場合のばらつきの指標が四分位数となる。
四分位数を求めるRの基本関数はquantile()
である。quantile()
関数は算出対象となるデータを与えた後に、どの四分位数を求めるかを小数で与えてやる。
Q_1 <- quantile(Shohoku$score, 0.25) # 第1四分位数 下位25%の値。
Q_2 <- quantile(Shohoku$score, 0.75) # 第3四分位数 上位25%、すなわち下から75%の値
print(Q_1)
print(Q_2)
## 25%
## 5
## 75%
## 7
このように関数を用いるときに()
に与えるデータやオプションのことを引数(ひきすう)と呼ぶ。
また、quantile()
は以下のように2つ目の引数にc()
を用いて複数のパラメータを指定してやることで、複数の四分位数を一度に求めることもできる。
Q <- quantile(Shohoku$score, c(0.0, 0.25, 0.50, 0.75, 1.0))
print(Q)
## 0% 25% 50% 75% 100%
## 4.0 5.0 6.5 7.0 10.0
ちなみに、quantile()
の出力は名前付きベクトルである。
四分位数はその数字そのものを示すより、一般に「箱ひげ図」と呼ばれるグラフを作成する際に用いられることが多い。箱ひげ図の具体例を以下に示す。箱の上端と下端で第1、第3四分位数を示し、箱の中の線で中央値を示す。さらに上下に伸びたひげで最大値、最小値を示す。場合によっては、箱の中に点線で平均値を示したり、一点鎖線で最頻値を示したりといったことも可能である。
このグラフの秀逸な点は、データが概ねどのような分布をしているかを示すことができる点である。例の箱ひげ図の場合、上にひげが長く伸び、さらに第3四分位数と中央値の間が、第1四分位数と中央値の間よりも広がっていることから、データの分布として、全体として点の低いほうに山が偏っており、点の高いほうに裾野が伸びた分布をしているということが読み取れる。
以前は棒グラフで平均値を示したグラフや、平均値の棒グラフに標準偏差の幅分だけ「ひげ」(エラーバーと呼ぶ)をつけたグラフを示すのがほとんどであったが、平均と標準偏差を示すだけでは、上記のような分布の形状までは分からない。このため、最近では、箱ひげ図を示すことも多くなってきている。以上、個別に記述統計量を算出する方法について説明した。
算出したこれらの統計量を別の計算で用いたい場合には、個別にこれらのコマンドで算出する必要がある。
一方、レポートや論文などで記述統計量を報告したり、とりあえず全体的な傾向を把握したいといった場合には、summary()
関数やdescribe()
関数を利用することができる
summary()
関数を使うと、ベクトルやデータフレームに含まれている各列について、四分位数と平均値を一度に得ることができる。また、ベクトルやデータフレームの列が文字列型だった場合にはデータの点数が表示される.
ベクトルやデータフレームの列が要因型(factor型)だった場合には要因ごとのデータ点数が表示される。
簡単にデータ全体の傾向を把握することができるので、データを読み込んだ場合にはsummary()
をまずは実施する、というのがデータ分析の基本フローと言えるだろう。
summary(Shohoku) #データフレームを与えると、含まれているベクトルごとの平均と四分位数を出力される。
## nam number score
## Length:12 Min. : 4.000 Min. : 4.000
## Class :character 1st Qu.: 6.750 1st Qu.: 5.000
## Mode :character Median : 9.500 Median : 6.500
## Mean : 9.417 Mean : 6.417
## 3rd Qu.:12.250 3rd Qu.: 7.000
## Max. :15.000 Max. :10.000
summary(Shohoku$score) #ベクトルを与えると、そのベクトルの平均と四分位数をが出力される。
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 4.000 5.000 6.500 6.417 7.000 10.000
psych
パッケージに含まれるdescribe()
関数を用いるとより詳しい記述統計量を得ることができる。psych
パッケージを利用するためには、上部のメニューの中からTools->install.packagesを選択したうえで、以下のようにPackagesにpsych
と入力してパッケージをインストールする。
インストールが完了すれば、library()
関数を使ってpsych
パッケージを読み込み、describe()
関数を実行すると、以下のような結果が表示される。
library(psych)
##
## 次のパッケージを付け加えます: 'psych'
## 以下のオブジェクトは 'package:ggplot2' からマスクされています:
##
## %+%, alpha
describe(Shohoku)
## vars n mean sd median trimmed mad min max range skew kurtosis se
## nam* 1 12 6.50 3.61 6.5 6.5 4.45 1 12 11 0.00 -1.50 1.04
## number 2 12 9.42 3.50 9.5 9.4 4.45 4 15 11 -0.03 -1.47 1.01
## score 3 12 6.42 1.83 6.5 6.3 1.48 4 10 6 0.41 -0.88 0.53
それぞれ、以下のような指標である
名前 | 内容 |
---|---|
mean | 平均 |
sd | 標準偏差(不偏標準偏差) |
median | 中央値 |
trimmed | トリム平均(データの上下5%ずつを取り除いて算出した平均) |
mad | 平均偏差 |
min | 最小値 |
max | 最大値 |
range | 最大値-最小値 |
skew | 歪度(データの分布がどの程度左右に偏っているか。負の場合は左に、正の場合には右に偏っている。また値が大きいほど偏りが大きい。) |
kurtosis | 尖度(データの分布がどの程度尖っているか。正規分布の尖り具合を0として、正の場合には正規分布より尖っており、負の場合には正規分布より平坦になっている) |
se | 標準誤差(詳しくは後述{#平均値の区間推定}。) |
なお、上記のname列に対する結果の通り、describe()
関数はたとえ列の型が文字列であっても数字を出力してくる。当然ながら意味は全くない。参考までに、この出力結果は各要素のインデックス番号をデータとして計算を行ったものであある。
この例のようにRでは標準的なコマンド以外にも様々なコマンドが用意されている。ただし、それらのコマンドを利用するためには、そのコマンドが定義された外部パッケージをTools->install.packagesによってインストールし、さらにスクリプト内でlibrary()
関数を使ってそのパッケージを読み込む必要がある。
なおlibrary()
関数での外部パッケージの読み込みはスクリプトの実行中1回だけで良い。1度読み込みば、その後はその外部パッケージのコマンドを入力するだけでコマンドを実行することができる。
またパッケージのインストールも一度行えばその後は行う必要はなくなる。
【課題ファイル】には大学共通テストの結果を基にシミュレーションした1000人分の各教科の得点を記載している.このデータについて,各教科の平均値,中央値,最頻値,分散,標準偏差,第1四分位数,第3四分位数を求めなさい.ただし,summary()関数とdescribe()関数は用いてはらならない.
何らかの調査をするときに、その調査が想定している対象全体のことを母集団という。それに対して、母集団の中から一部だけを抜け出して調査を行った場合、実際に調査を行った対象をサンプル(標本)集団と呼び、サンプル集団に含まれる個々のデータのことをサンプル(標本)と呼ぶ。また、母集団に対して行う調査を母集団調査、あるいは全数調査と呼び、サンプル集団に対して行う調査をサンプル調査と呼ぶ。
母集団調査(全数調査)を実施できればそれに越したことはないが、実際には費用的・時間的な制約であったり、現実に不可能であったりするために、母集団調査を実施できないことは多い。そういう場合には、現実的に実施可能な限られた数のサンプル調査を行い、その結果をもとに母集団の特徴を推測するということが行われる。
母集団調査(全数調査)の例
母集団にアクセスできず、あくまでサンプル調査となる例
そのほか、マーケティング調査なども基本的に全てサンプル調査である。
母集団全体での記述統計量を母数と呼ぶ。また、特に平均、分散については母平均、母分散と呼ぶこともある。 それに対してサンプル集団の記述統計量を標本統計量と呼び、平均を標本平均、分散を標本分散と呼ぶ。
母集団全体にアクセスできる場合には、得られたデータの記述統計量は母数そのものとなる。それに対してサンプル集団にしかアクセスできない場合には、そのデータの記述統計量はあくまで標本統計量であり母数ではない。
先の例にも述べた通り、サンプル調査ではデータそのものの記述統計量(つまり標本統計量)が得たいのではなく、その結果を基に母数を推定することが目的である。従って、標本統計量から母数を推定する必要がある。
推定には大きく2種類あり、値を単刀直入に推定することを点推定と呼ぶ。一方、「〇%の確率で、この範囲内に母数がある可能性が高い」という範囲を推定することを区間推定と呼ぶ。点推定の値のことを不偏推定量、区間推定の範囲のことを〇%信頼区間と呼ぶ。なお、区間推定では「95%」が用いられることが多いが、場合によっては90%や99%が用いられることもああり、その場合には信頼区間の呼び名もそれぞれの確率値に変わる。
標本統計量と点推定値,信頼区間の関係を以下の図に示す。
細かな導出過程や導出に当たっての考え方については省略するが、母数の推定値は以下の数式によって算出される。なお、以下では\(\mu\), \(\sigma^2\)は母平均と母分散(要するに真の値)、\(\hat\mu\)や\(\hat{\sigma^2}\)はデータから推定した母平均と母分散の推定量、\(\bar{x}\)と\(s^2\)は標本平均、標本分散を表す。
母平均の不偏推定量を式で表すと以下のようになる。 \[ \mu \approx \hat{\mu}=\bar{x}=\frac{1}{n}\sum^{n}_{i=1}x_{i} \] 要するに、母平均の推定量は標本平均そのものである。つまり、サンプル調査を行った時、得られたデータの平均を母集団全体の平均と見なそう、ということである。
したがってRで母平均の推定量を求めるときも、従来通りmean()
関数を用いればよい。
mean(Shohoku$score)
## [1] 6.416667
母分散の不偏推定量(不偏分散)は以下の式となる。
\[ \sigma^2 \approx \hat{\sigma^2}=\frac{n}{n-1}s^2=\frac{1}{n-1}\sum^{n}_{i=1}(x_i-\bar{x})^2 \]
要するに、標本分散を求める時には「データと平均との差の二乗の和」をnで割っていたのを、n-1で割る形にしているだけである(なぜ\(n-1\)になるかは結構面倒な話になるので省略。興味ある人は上の数式の導出過程をネットで調べてみてほしい。ちなみにこの\(n-1\)のことを自由度と呼ぶ)。
さらに母標準偏差の不偏推定量は、上記の式の平方根となる。
\[\begin{align} \sigma \approx \hat{\sigma}&=\sqrt{\frac{n}{n-1}s^2} = \sqrt{\frac{1}{n-1}\sum^{n}_{i=1}(x_i-\bar{x})^2} \\ &= \sqrt{\frac{n}{n-1}}s \end{align}\]
Rで不偏分散や標準偏差の不偏推定量を求める方法については、すでに上記で説明したとおり、var()
やsd()
をそのまま用いればよい。
すなわち、先ほどの湘北高校のデータを用いるならば、以下の通りとなる。
var(Shohoku$score)
sd(Shohoku$score)
## [1] 3.356061
## [1] 1.831955
ちなみに、この数値の解釈として、湘北高校のバスケ部員はフリースローで10本中、約6本(平均の不偏推定量)を入れることができるが、メンバー間でのばらつきとして1.8点ほどの標準偏差を持っている、ということである。これはあくまで母数の推定量をであり、赤木・桜木・三井・宮城・流川の5人の得点の平均や5人の中でのばらつきではない。5人をサンプルとした「湘北高校のレギュラーメンバー」という母集団のフリースローの成績の推定値ということである。つまり、赤木・桜木・三井・宮城・流川が入学する前の過去のレギュラーメンバーや、彼らが引退した後の未来のレギュラーメンバーも対象に入れた、湘北高校バスケ部のレギュラーメンバー一般の成績の推定値ということになる。
続いて、区間推定であるが、平均の区間推定を行う際には標準誤差(Standard Error)と呼ばれる統計量を算出する必要がある。標準誤差は以下の数式で算出される。
\[ SE = \sqrt{\frac{\hat{\sigma^2}}{n}}=\frac{\hat{\sigma}}{\sqrt{n}} \] 要するに、標準偏差の不偏推定量を\(\sqrt{n}\)で割った値である。 この標準誤差(以下SE)を用いて、平均値の95%信頼区間(上限と下限)はそれぞれ以下の数式で得られる。
\[\begin{align} 上限 &= \hat\mu + t\times SE \\ 下限 &= \hat\mu - t\times SE \end{align}\]
ここで\(t\)とは自由度\(n-1\)(\(n\)はサンプル数)のT分布表の両側95%から得られる値である。T分布表は大抵の統計学の教科書の末尾に記載されている。具体的には以下のような表である。自由度n-1の行の\(\alpha=0.025\)の値を読む。例えば、サンプル数が30の場合、自由度は29なので、t=2.045となる。
Rで平均値の信頼区間を求めるにあたっては、2つの方法がある。
まず一つ目はt.test()
を使う方法である。本来t.test()
関数は後日説明する平均の比較に用いる関数であるが、信頼区間を出力させるのに用いることができる。
res<-t.test(Shohoku$score)
res$conf.int
## [1] 5.252698 7.580636
## attr(,"conf.level")
## [1] 0.95
\(5.252698\)が下限、\(7.580636\)が上限となる。\(0.95\)は信頼区間の確率である。
ちなみに、res
自体を出力させると以下のような出力になる。ごちゃごちゃと書かれているが、真ん中あたりに95 percent confidence interval:
とあり、信頼区間が記載されている。
print(res)
##
## One Sample t-test
##
## data: Shohoku$score
## t = 12.133, df = 11, p-value = 1.038e-07
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## 5.252698 7.580636
## sample estimates:
## mean of x
## 6.416667
もし信頼区間の確率設定を変えたい場合には以下のようにすればよい。
res<-t.test(Shohoku$score, conf.level = 0.99)
res$conf.int
## [1] 4.774192 8.059141
## attr(,"conf.level")
## [1] 0.99
二つ目の方法は、先に示した式を自分で打ち込む方法である。
# 平均と標準誤差の算出
n <-length(Shohoku$score)#length()はベクトルの長さ(要素数)を得る関数。もちろんnrow(Shohoku)としてもよい。
res_mean <- mean(Shohoku$score)
res_se <- sd(Shohoku$score)/sqrt(n)
#t値の取得
t_value <- qt(0.975, df=n-1) # 0.025でもよい。0.025とした場合、負の数字が出力される点に注意すること。
#信頼区間の算出
Band_Upper <- res_mean + t_value * res_se
Band_Lower <- res_mean - t_value * res_se
#出力
c(Band_Lower, Band_Upper)
## [1] 5.252698 7.580636
先ほどと同じ数値が算出されていることが確認できる。
分散についての95%信頼区間については不偏分散\(\hat{\sigma^2}\)を用いて次の式で与えられる。
\[\begin{align} 上限 &= \frac{(n-1)\hat{\sigma^2}}{\chi^2_{0.975}} \\ 下限 &= \frac{(n-1)\hat{\sigma^2}}{\chi^2_{0.025}} \end{align}\]
\(\chi^2\)(カイ2乗と呼ぶ)は、\(t\)と同様に自由度n-1(nはサンプル数)のカイ2乗分布表から得られる値である。分布表と同様に、カイ2乗分布表も統計学の教科書には記載されている。具体的には次々項のような表である。自由度n-1の\(\alpha=0.025と0.975\)の値を読み取る。例えば、サンプル数が30の場合、自由度は29なので、上限算出に使う\(\chi^2\)値は16.047、下限算出に使う\(\chi^2\)値は45.722となる
Rで分散の信頼区間を算出する方法も2つある。1つはEnvStats
パッケージに含まれているvarTest()
関数を使う方法である。使うにはEnvStats
パッケージをインストールしたうえで、library()
関数を実行する必要がある(こちら参照)。
library(EnvStats)
##
## 次のパッケージを付け加えます: 'EnvStats'
## 以下のオブジェクトは 'package:stats' からマスクされています:
##
## predict, predict.lm
res<-varTest(Shohoku$score)
res$conf.int
## LCL UCL
## 1.684151 9.674817
## attr(,"conf.level")
## [1] 0.95
res<-varTest(Shohoku$score, conf.level = 0.90) #90%信頼区間の場合
res$conf.int
## LCL UCL
## 1.876310 8.069546
## attr(,"conf.level")
## [1] 0.9
ちなみにvarTest()
自体の出力結果は以下の通りである。一番下に信頼区間が記載されている。なお、上のコードで確率を90%に設定したものをresに格納しているので、90%信頼区間の結果が表示されている。
print(res)
##
## Results of Hypothesis Test
## --------------------------
##
## Null Hypothesis: variance = 1
##
## Alternative Hypothesis: True variance is not equal to 1
##
## Test Name: Chi-Squared Test on Variance
##
## Estimated Parameter(s): variance = 3.356061
##
## Data: Shohoku$score
##
## Test Statistic: Chi-Squared = 36.91667
##
## Test Statistic Parameter: df = 11
##
## P-value: 0.0002379912
##
## 90% Confidence Interval: LCL = 1.876310
## UCL = 8.069546
もう一つの方法は、平均値の区間推定と同様に先に示した式を自分で打ち込む方法である。
n <- nrow(Shohoku) # 今度はnrow()を用いた。当然length()を用いてもよい
res_var <- var(Shohoku$score)
# カイ二乗分布のクリティカル値を使用して信頼区間を計算
chi_upper <- qchisq(0.025, df = n - 1) #上で示した式の上限・下限の確率値が入れ替わっていることに注意
chi_lower <- qchisq(0.975, df = n - 1)
# 分散の信頼区間
Band_Lower <- (n - 1) * res_var / chi_lower
Band_Upper <- (n - 1) * res_var / chi_upper
#出力
c(Band_Lower, Band_Upper)
## [1] 1.684151 9.674817
なお、Rで計算するときの\(\chi^2\)値算出の関数qchisq()
での確率設定値と、先ほど式で示したものの中での\(\chi^2\)値の確率設定値が入れ替わっている。これは確率を「残された方」で見るのか、「切り落とす方」で見るのかの違いである。入れ替わってしまったとしても数値自体が変わるわけではないので、実際に出力させてみて、上限と下限の値が逆順になっていれば、数値を入れ替えればよい。
平均値の区間推定にしろ、分散の区間推定にしろ、「95%」信頼区間なのに、\(\alpha=0.05\)や\(0.95\)ではなく\(\alpha=0.025\)や\(0.975\)の値を読むのはなぜなのか疑問に思う人もいると思う。これは「95%の確率でその区間の中に平均値がある」という範囲を取り出す、ということはその範囲よりも上下にある2.5%ずつを切り落とすということだからである。仮に5%と95%の値を読むことにしてしまうと、残された区間は90%となってしまう。
先ほどの【課題ファイル】にある大学共通テストのデータについて,各教科の平均と分散の点推定値および95%の推定区間を求めなさい.
これまでに紹介してきたmean()
やvar()
、sd()
はベクトルに対しての関数である。
データフレームの各列に対して平均や分散,標準偏差を算出しようとするとき,これらの関数では各列を一つ一つ$
を用いてベクトルとして取り出して,これらの関数に与えていく必要がある.
取り出そうとしている列の数が少ないのであれば,それでも問題ないが,列の数が多くなってきたときには1つ1つベクトルで取り出していくのは骨が折れてしまう.
そういう場合には,先に紹介したdescribe()
関数を用いるのが良いが,ほかに
sapply()
関数を用いるという手段もある.sapply()
関数は,データフレームの各列に対して関数を適用する関数である.第1引数には対象となるデータフレーム,第2引数には適用したい関数を指定する。たとえば平均であればmean
,標準偏差であればsd
,分散であればvar
といった具合である.注意点として,引数としてこれらの関数名を与える際には()
はつける必要はなく,あくまで関数名だけを与えればよい.
さらに第3引数として,適用したい関数に引数がある場合にそれを指定することができる.たとえば,mean()
で紹介した通り,na.rm=TRUE
を第3引数として与えることで,NAが含まれる場合にそれを無視して計算することができる.
このデータは,ある大学で行われた主要5因子性格検査短縮版アンケート(外向性,協調性,勤勉性,神経症傾向,開放性)参考で得られた学生400人分のデータである.このデータから,各性格特性の平均と標準偏差を求めなさい.
出典:小塩 真司, 阿部 晋吾, Pino Cutrone, 日本語版Ten Item Personality Inventory(TIPI-J)作成の試み., パーソナリティ研究, Vol.21, No.1, pp.40-52 (2012)
data <- read.csv("practice/04_work_basicStatistics_sapply.csv")
sapply(data, mean)
## 外向性 協調性 勤勉性 神経症傾向 開放性
## 7.8675 9.4125 6.4350 9.2200 8.1625
sapply(data, sd)
## 外向性 協調性 勤勉性 神経症傾向 開放性
## 2.539896 2.087640 2.346175 2.276963 2.405319
これまでつかってきたデータ(湘北高校のデータ)には特にグループ(群)分けという概念は存在していないデータであった。
しかし実際のデータには大抵、属性項目(例えば、性別や、実験データにおいては実験条件、あるいは学年や年齢区分、国籍など)によるグループ分けというものが存在する。そういったグループ分けが存在するときに、グループごとに記述統計量(推測統計量)を算出するには、aggregate()
関数を用いると良い。
以下では先の湘北高校のデータを、レギュラー組と控え組にグループ分けしたものにしたうえで、グループごとの平均と標準偏差を算出させてみる。
まずは湘北高校のデータにグルプ分けのための変数Group
を追加する。
Shohoku["Group"] <- as.factor(c("レギュラー", "レギュラー", "レギュラー", "レギュラー", "レギュラー", "控え", "控え", "控え", "控え", "控え", "控え", "控え"))
Shohoku # 確認
## nam number score Group
## 1 赤木 4 7 レギュラー
## 2 桜木 10 4 レギュラー
## 3 三井 13 10 レギュラー
## 4 宮城 7 7 レギュラー
## 5 流川 11 9 レギュラー
## 6 木暮 5 6 控え
## 7 潮崎 8 6 控え
## 8 安田 6 7 控え
## 9 角田 9 7 控え
## 10 石井 12 5 控え
## 11 佐々岡 13 5 控え
## 12 桑田 15 4 控え
as.factor()
関数に関しては先に軽く触れたが(参考)、ここで改めて詳しく説明する。
グループ分けに使う変数の型は「要因型」と呼ぶ。要因型に設定するためにはc()
関数を使って作成したベクトルをas.factor()
関数で括ってやる必要がある。内容はレギュラー
や控え
という文字列になっているが、列全体としては文字列型ではないことに注意してもらいたい。
文字列型と要因型とでは結果が異なる。summary()
の実行結果として出力されるものが異なってくる。それぞれ以下で確認してみてほしい。
Shohoku$Group <- as.factor(c("レギュラー", "レギュラー", "レギュラー", "レギュラー", "レギュラー", "控え", "控え", "控え", "控え", "控え", "控え", "控え"))
summary(Shohoku)
## nam number score Group
## Length:12 Min. : 4.000 Min. : 4.000 レギュラー:5
## Class :character 1st Qu.: 6.750 1st Qu.: 5.000 控え :7
## Mode :character Median : 9.500 Median : 6.500
## Mean : 9.417 Mean : 6.417
## 3rd Qu.:12.250 3rd Qu.: 7.000
## Max. :15.000 Max. :10.000
Shohoku$Group <- c("レギュラー", "レギュラー", "レギュラー", "レギュラー", "レギュラー", "控え", "控え", "控え", "控え", "控え", "控え", "控え")
summary(Shohoku)
## nam number score Group
## Length:12 Min. : 4.000 Min. : 4.000 Length:12
## Class :character 1st Qu.: 6.750 1st Qu.: 5.000 Class :character
## Mode :character Median : 9.500 Median : 6.500 Mode :character
## Mean : 9.417 Mean : 6.417
## 3rd Qu.:12.250 3rd Qu.: 7.000
## Max. :15.000 Max. :10.000
要因型にした場合には、それぞれのグループに含まれるデータの数が返されるのに対して、文字列型の場合には全体のデータ点数と文字列型であることを示すClass: character
やMode: charater
という表示が返されるだけである。
なお、要因型に設定するのであれば、その内容は数値でも構わない。ただ、数値をグループ分け変数に使用する場合には特にas.factor()
を実行するのを忘れないようにしなければならない。文字列型だった場合には数値演算はできないので結果自体は要因型であってもなくても変わらないことはよくあるが、数値型のときにas.factor()
を忘れてしまうと、グループ分け用の変数としていたつもりでも数値の変数として処理され、演算の中に組み込まれてしまうことがあり、誤った結果を出力するケースがある(例えば、回帰分析)。
具体的に例を示すと,まずは以下は正しく処理している例.
Shohoku$Group <- as.factor(c(1,1,1,1,1,2,2,2,2,2,2,2)) #1:レギュラー, 2:控え
summary(Shohoku)
## nam number score Group
## Length:12 Min. : 4.000 Min. : 4.000 1:5
## Class :character 1st Qu.: 6.750 1st Qu.: 5.000 2:7
## Mode :character Median : 9.500 Median : 6.500
## Mean : 9.417 Mean : 6.417
## 3rd Qu.:12.250 3rd Qu.: 7.000
## Max. :15.000 Max. :10.000
一方,こちらはas.factor()
を忘れてしまった例.
Shohoku$Group <- c(1,1,1,1,1,2,2,2,2,2,2,2)
summary(Shohoku)
## nam number score Group
## Length:12 Min. : 4.000 Min. : 4.000 Min. :1.000
## Class :character 1st Qu.: 6.750 1st Qu.: 5.000 1st Qu.:1.000
## Mode :character Median : 9.500 Median : 6.500 Median :2.000
## Mean : 9.417 Mean : 6.417 Mean :1.583
## 3rd Qu.:12.250 3rd Qu.: 7.000 3rd Qu.:2.000
## Max. :15.000 Max. :10.000 Max. :2.000
Groupは数値型として処理されてしまい,summary()
関数の結果も数値型として出力されてしまっている.
しかし,元々は単なるラベルとして「1」や「2」としているだけであり,出力されている平均や中央値,四分位数は全く意味がないものである.
このように,あくまでラベルとして数値を用いるときには,Rがその列(ベクトル)を数値として扱わないように,as.factor()
を忘れないようにすることが重要である.
aggregate()
関数の機能は、ベクトルデータに対して、グループ分けを行った上で、それぞれのグループのデータに対して設定した関数演算を実行するというものである。
第1引数には、演算対象データの列名~グループ分けデータの列名という書式で、それぞれのデータを指定する。第2引数には演算を行いたいデータが入っているデータフレームを与える。第3引数には、実行したい演算関数の名前を与える。入力するものはあくまで関数の名前だけでよく、()
はつける必要はない。
結果はデータフレームで出力される。
#グループ分け変数の設定
Shohoku$Group <- as.factor(c("レギュラー", "レギュラー", "レギュラー", "レギュラー", "レギュラー", "控え", "控え", "控え", "控え", "控え", "控え", "控え"))
#平均を算出
res.mean<-aggregate(score~Group, Shohoku,mean)
print(res.mean)
## Group score
## 1 レギュラー 7.400000
## 2 控え 5.714286
#標準偏差を算出
res.sd<-aggregate(score~Group, Shohoku, sd)
print(res.sd)
## Group score
## 1 レギュラー 2.302173
## 2 控え 1.112697
次の【課題ファイル】は,Setosa, Versicolor, Verginica,という 3種類のアイリスの花の花びらとがくの長さと幅についてのデータである.このデータについて,花の種類ごとに花びらとがくの長さと幅の平均と標準偏差をそれぞれ求めなさい.
psych
パッケージをインストールしたうえで,現在実行しているRで読み込む必要がある.EnvStats
パッケージをインストールしたうえで,現在実行しているRで読み込む必要がある.