5. 学生データを分析してみよう

前の節ではドラゴンズ選手の体格データを対象とした。 では、今度は皆さんから集めたデータ(過去分を含む)を分析してみよう。 実はドラゴンズ選手のデータには欠損値は含まれておらず、 完全なデータであったが、実データでは往々にして欠損値を含んでいることが多く、例に漏れず学生データも欠損値を含んているのでその対応を含めて習得せよ。

[演習5-1] データはMoodleにExcel形式で掲載しておいたので、前節の手順に従って各自でダウンロード後、CSV形式に変換し、ホームディレクトリにコピーせよ。

[Moodleに保存しているファイル名] StudAll20a.xlsx

[上記手順で保存されたファイル名] StudAll20a.csv (各自で別の名前を指定しても可。その場合はファイル名を忘れないように。)

[ファイルが保存されているディレクトリ名] KougiDS

  • ここまでが完了したことを前提に以下の話を進めている。この演習を終えないと先に進めないので解らない部分があるのであれば、早めに解決すべく連絡し助けを求めよ。

5.1. 学生データを読み込む

# ディレクトリの移動。必須ではない。個々人の設定に応じて。
setwd("D:/home_sub3/R_Dir")  # ホームディレクトリに移動(Set Working Directory)
getwd()           # 現在のディレクトリ位置を表示
## [1] "D:/home_sub3/R_Dir"
list.files()      # ファイル・ディレクトリ一覧を表示
## [1] "Dragons"      "grain"        "KougiDS"      "Unemployment"
setwd("KougiDS")  # ディレクトリを移動
list.files()      # ファイル・ディレクトリ一覧を表示
##  [1] "DS02.R"          "DS02b.R"         "DS03_1d.R"       "DS03_1f.html"   
##  [5] "DS03_1g.html"    "DS03_1g.Rmd"     "Kougi1015a.R"    "OldFiles"       
##  [9] "StudAll20a.csv"  "StudAll20a.R"    "StudAll20a.xlsx" "StudAll20aa.R"  
## [13] "Student20a.R"

目的のファイル(StudAll20a.csv)が保存されていることが確認された。 では、このファイルからデータを読み込んでみよう。 その際、先頭行(1行)には説明等の分析に必要ない情報が書き込まれて いるので、読み飛ばす(スキップ)。 また、それに続く行に変数名が指定されているので「header=TRUE」を 指定する。Excel入力時にこの行を準備することをお薦めしたのは このように指定できるからだ。

この行を準備していない場合はシステム側が任意の変数名を 付けてくれるが、無味簡素な名称なので、意味が理解しやすい変数名を 自分で付ける方が効率が上がると考えている。

興味があるのなら、変数名が指定されていないデータを作成して 試してみれば理解が促進されるであろう。

前節のドラゴンズデータには欠損値が含まれていなかったので、 何もオプションを指定しなかったが、 この学生データには欠損値が含まれているので、その文字を明示的に示しておく。ここではNAという文字が欠損値であることを指定している。 以下のデータ表示内に「NA」が散見されることを確認せよ。

# データの読み込み
Student20a<-read.csv("StudAll20a.csv", skip=6, header=TRUE, na.strings="NA")

ここで読み込んだデータを確認すべく

Student20a

を実行すると、

##    Sex Height Weight Chest Residence Remittance  Carrier  Fee
## 1    F  145.0   38.0    NA    自宅生      10000        NA
## 2    F  146.7   41.0    85    自宅生      10000 Vodafone 6000
## 3    F  148.0   42.0    NA    自宅生      50000        NA
   <中略>
## 123   M    165     55    90    自宅生      10000  DoCoMo 7000
## 124   M    165     55    NA    自宅生       4000      No   NA
## 125   M    165     55    NA    下宿生      50000      au 5000
 ## [ reached 'max' / getOption("max.print") -- omitted 290 rows ]

データが表示される。意図通りに読み込めているであろうか? 目視でカラムズレ(横方向)等が起こっていないかを確認せよ。

しかし、最終行に何やらメッセージが表示される。 表示最大行数を超えたので表示を中止したことと、 表示し切れなかったサンプルが290件(行)あることを示している。 上の例では125行しかデータが表示されていない(正確にはConsoleペインの画面サイズにより中断される行数は変化する) ので、 今回のように行数(サンプル)が多いデータの場合は、 表示する最大行を大きく指定することにより 全部を表示させることができる。

# 表示行数の制限を解除
old.op <- options(max.print=999999)
Student20a
##    Sex Height Weight Chest Residence Remittance  Carrier  Fee
## 1    F  145.0   38.0    NA    自宅生      10000        NA
## 2    F  146.7   41.0    85    自宅生      10000 Vodafone 6000
## 3    F  148.0   42.0    NA    自宅生      50000        NA
   <中略>
## 410    F     NA     NA    NA    下宿生      30000      au 1500
## 411    F     NA     NA    NA    自宅生      50000      au 8000
## 412      NA     NA    NA               NA       NA
## 413      NA     NA    NA    下宿生     100000       NA
## 414      NA     NA    NA               NA       NA
## 415      NA     NA    NA               NA       NA

一方で毎回、400行以上も表示されるのは面倒だと思えば、 上記のオプションに小さな数字を指定し直すか、 もしくは前の節で取り扱ったように陽に表示する行数を指定する方法も ある。どちらの策を取るかは個人の好みに任せる。 とは言え、分析の初期段階では、全体を一度目視で確認しておくことも必要ではないか。

なお、このテキストでは一部に左右方向のズレが見られるが、 これはブラウザの特性で、各自のConsoleペインではズレずに 表示されていることと思う。

# 先頭10人を表示
Student20a[1:10,]
##    Sex Height Weight Chest Residence Remittance  Carrier  Fee
## 1    F  145.0   38.0    NA    自宅生      10000     <NA>   NA
## 2    F  146.7   41.0    85    自宅生      10000 Vodafone 6000
## 3    F  148.0   42.0    NA    自宅生      50000     <NA>   NA
## 4    F  148.0   43.0    80    自宅生      50000   DoCoMo 4000
## 5    F  148.9     NA    NA    自宅生      60000     <NA>   NA
## 6    F  149.0   45.0    NA    下宿生      60000     <NA>   NA
## 7    F  150.0   46.0    86      <NA>      40000     <NA>   NA
## 8    F  151.0   45.0    NA    自宅生      20000   docomo 5000
## 9    F  151.0   50.0    NA    下宿生      60000  J-PHONE   NA
## 10   F  151.7   41.5    80    自宅生      35000     <NA>   NA
# 先頭20番目から30番目の11人分を表示
Student20a[20:30,]
##    Sex Height Weight Chest Residence Remittance  Carrier   Fee
## 20   F  153.0     NA    NA      <NA>      50000     <NA>  5000
## 21   F  153.5     46    NA    自宅生      30000  J-PHONE  8000
## 22   F  154.0     46    NA      <NA>         NA     <NA>    NA
## 23   F  154.4     44    75    自宅生       9000       au  2000
## 24   F  155.0     48    83    下宿生     180000     <NA>    NA
## 25   F  155.0     48    NA    下宿生      60000   DoCoMo    NA
## 26   F  155.0     51    NA    下宿生      70000     <NA> 10000
## 27   F  155.0     NA    NA    自宅生      20000     <NA>    NA
## 28   F  156.0     42    85    自宅生          0   DoCoMo 15000
## 29   F  156.0     42    NA    自宅生      35000     <NA>  7000
## 30   F  156.0     46    82    自宅生      10000 Vodafone  7000

5.2. 学生データの概観を把握する

まずは読み込んだデータを概観してみよう。 データのサイズ、変量数、変量名を表示するには?

# 基本情報を外観してみる
dim(Student20a)
## [1] 415   8
colnames(Student20a)
## [1] "Sex"        "Height"     "Weight"     "Chest"      "Residence" 
## [6] "Remittance" "Carrier"    "Fee"

データのサイズや変数名が把握できたであろうか? 415人、8変量のデータであることが判る。 変量名もExcelで指定されたものが採用されていることが判る。

次に各変量の概要を見てみよう。

# 基本情報を外観してみる
str(Student20a)      # データの内容を情報付きで表示
## 'data.frame':    415 obs. of  8 variables:
##  $ Sex       : chr  "F" "F" "F" "F" ...
##  $ Height    : num  145 147 148 148 149 ...
##  $ Weight    : num  38 41 42 43 NA 45 46 45 50 41.5 ...
##  $ Chest     : num  NA 85 NA 80 NA NA 86 NA NA 80 ...
##  $ Residence : chr  "自宅生" "自宅生" "自宅生" "自宅生" ...
##  $ Remittance: int  10000 10000 50000 50000 60000 60000 40000 20000 60000 35000 ...
##  $ Carrier   : chr  NA "Vodafone" NA "DoCoMo" ...
##  $ Fee       : int  NA 6000 NA 4000 NA NA NA 5000 NA NA ...

415サンプルで8変量のデータである。 各変量はそれぞれ、文字型(chr)か数字型(num)かが判る。 数値型の内、特に整数値を取るものにはintとの表示がある。 右側には例示もされている

# 基本情報を外観してみる
summary(Student20a)  # データの要約を表示
##      Sex                Height          Weight           Chest       
##  Length:415         Min.   :145.0   Min.   : 35.00   Min.   : 30.50  
##  Class :character   1st Qu.:163.0   1st Qu.: 53.00   1st Qu.: 82.00  
##  Mode  :character   Median :170.0   Median : 60.00   Median : 85.00  
##                     Mean   :168.3   Mean   : 59.05   Mean   : 85.68  
##                     3rd Qu.:174.0   3rd Qu.: 64.22   3rd Qu.: 90.00  
##                     Max.   :186.0   Max.   :100.00   Max.   :112.00  
##                     NA's   :15      NA's   :49       NA's   :280     
##   Residence           Remittance       Carrier               Fee       
##  Length:415         Min.   :     0   Length:415         Min.   :    0  
##  Class :character   1st Qu.: 10000   Class :character   1st Qu.: 4000  
##  Mode  :character   Median : 30000   Mode  :character   Median : 5000  
##                     Mean   : 46640                      Mean   : 6452  
##                     3rd Qu.: 65000                      3rd Qu.: 8750  
##                     Max.   :350000                      Max.   :30000  
##                     NA's   :34                          NA's   :236

各変量の大まかな様子が判るであろうか? 文字変量(character)の場合はそのことが、 また数値変量の場合は、最大値や平均値等、加えて欠損値の個数も 表示されている。

5.3. 基礎統計

では、この中から身長に注目して基礎統計を見てみよう。 今回のように欠損値を含んだデータの場合は、 欠損値を除外して計算する必要があるため、その除外を指示する オプションとして「na.rm=TRUE」を指定している。

「na.rm」は真偽の二値の何れかを指定するオプションで、 デフォルト(指定なし)では偽(FALSE)となっており欠損値を除外しない。 以下では真(TRUE)、つまり欠損値を計算対象から除外(No Answer Remove) することを指定していることになる。「TRUE」と4文字で指定しているが 省略形として「T」でも構わない。逆に偽は「FALSE」もしくは「F」である。

summary(Student20a$Height)             # 前項の出力の身長部分のみ。欠損値の個数も表示される。
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##   145.0   163.0   170.0   168.3   174.0   186.0      15
mean(Student20a$Height, na.rm=TRUE)     # 平均値
## [1] 168.3063
sd(Student20a$Height, na.rm=TRUE)         # 標準偏差
## [1] 8.022324
var(Student20a$Height, na.rm=TRUE)        # 分散
## [1] 64.35768
quantile(Student20a$Height, na.rm=TRUE)   # 四分位数
##   0%  25%  50%  75% 100% 
##  145  163  170  174  186

[演習5.3-1] 上記では欠損値を除外するオプションとして「na.rm = TRUE」を指定したが、指定しなかったら(偽(FALSE)を指定したら)どのような結果が得られるか? 各自でやってみよ。予想と合致したであろうか? なぜ、そのような結果になったかも考えよ。

5.4. 視覚的把握

前節で既に取り上げたので詳細の説明は不要であろう。 グラフに任意の説明(ラベル)を加えたい場合の書式を紹介しておく。

hist(Student20a$Height, right=FALSE, main="Histgram of Shintyou")   # ヒストグラム
abline(h=seq(0,100,20), lty=3)

boxplot(Student20a$Height, horizontal=TRUE, main="boxplot of Shintyou")   # 箱ひげ図(横向き)
abline(v=seq(150,180,10), lty=3)

plot(Student20a$Height, Student20a$Weight, main="Scatter Plot of Shintyou and Weight")   # 散布図
abline(h=seq(40,100,10), lty=3)
abline(v=seq(150,180,10), lty=3)

5.5. プログラムの保存

ここまでSourceペインに入力してきた式は全体としてプログラムと呼ばれる。 いろいろな処理を手順を追って実行する命令群とも言える。 1行ずつ、もしくは複数行をまとめて実行することができることは 既に紹介した。 苦労して作成したものなので、保存しておこう。

RStudio画面の左上にある[File]-[Save] もしくは[Save As]と進んで 自分の希望の場所(ディレクトリ)に希望の名称(ファイル名)で保存せよ。 なお、ファイルの属性には「.R」が付けられる。 また、保存したプログラムは[File]-[Open File]で呼び出すことができる。

[演習5.5-1] 各自のプログラムに好みのファイル名を付けて保存せよ。

  [例] StudAll20a.R

[この節全体を通しての演習5.5-2] ここまで身長に注目していくつかの指標を調べてきた。残りの連続変量(体重、胸囲、小遣い額、スマホ利用額)についても各自で調べてみよ。

6. レポートの作成方法

各種の統計手法を用いて分析を終えたら、それらを報告書やレポートにまとめる必要がある。RStudioには便利な機能(*)が付随しているのだが、 その使い方も含めて説明を始めると先に進めなくなるので、 ここでは簡便で直感的な方法を紹介しておく。 それは、MS Wordの新規の文書ファイルを準備し、各種計算結果をそこにコピー&ペーストしていけば最低限の文書ファイルを作成することができる。 その際、コピーする情報が、文字情報かグラフ情報かによってコピー元のペインが異なる。

情報をMS Wordに貼り付けた後は、それらの前後に「調査目的」や 「判ったこと」、「考察」等を記入していく。


(*) 興味のある者は「R Markdown」で調べてみよ。

【思い】欠損値を含むデータの分析方法と、レポートの作成方法を修得してほしい。

【分析例】

      学生データの中から身長に関して分析した。
      
      415名中、15件の欠損値があったので、分析対象となったのは400名である。
      この400名の身長についての各種の基礎統計量を算出した。以下はその要約である。
      
      平均 168.3
      標準偏差 8.0
      分散 64.4
      最小値 145.0
      最大値 186.0
      中央値 170.0
      第1四分位数 163.0
      第3四分位数 174.0
      
      <図省略>
      図1. 身長のヒストグラム
      
      <図省略>
      図2. 身長の箱ひげ図
      
      このヒストグラムや箱ひげ図を見ると、
      身長はやや大きい方(右側)に偏った分布をしていることが判る。
      また、箱ひげ図から、下側に外れ値に該当すると思われるサンプルが存在する。
      <<その他気付いたことを記載していく>>。
      
      これらの根拠となったRの出力は以下の通りである。
      
      > summary(Student20a$Height)
         Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
        145.0   163.0   170.0   168.3   174.0   186.0      15 
      > var(Student20a$Height, na.rm=TRUE)
      [1] 64.35768
      

88. 参考

このページで取り扱ったプログラムだけを抜き出して以下に列挙しておく。

# ディレクトリの移動。必須ではない。個々人の設定に応じて。
setwd("D:/home_sub3/R_Dir")  # ホームディレクトリに移動(Set Working Directory)
getwd()           # 現在のディレクトリ位置を表示
list.files()      # ファイル・ディレクトリ一覧を表示
setwd("KougiDS")  # ディレクトリを移動
list.files()      # ファイル・ディレクトリ一覧を表示

# データの読み込み
Student20a<-read.csv("StudAll20a.csv", skip=6, header=TRUE, na.strings="NA")
Student20a

# 表示行数の制限を解除
old.op <- options(max.print=999999)
Student20a

# 先頭10人を表示
Student20a[1:10,]

# 先頭20番目から30番目の11人分を表示
Student20a[20:30,]

# 基本情報を外観してみる
dim(Student20a)
colnames(Student20a)

# 基本情報を外観してみる
str(Student20a)      # データの内容を情報付きで表示

# 基本情報を外観してみる
summary(Student20a)  # データの要約を表示

summary(Student20a$Height)  # 前項の出力の身長部分のみ。欠損値の個数も表示される。
mean(Student20a$Height, na.rm=TRUE)       # 平均値
sd(Student20a$Height, na.rm=TRUE)         # 標準偏差
var(Student20a$Height, na.rm=TRUE)        # 分散
quantile(Student20a$Height, na.rm=TRUE)   # 四分位数

hist(Student20a$Height, right=FALSE, main="Histgram of Shintyou")   # ヒストグラム
abline(h=seq(0,100,20), lty=3)

boxplot(Student20a$Height, main="boxplot of Shintyou")   # 箱ひげ図
abline(h=seq(150,180,10), lty=3)

boxplot(Student20a$Height, horizontal=TRUE, main="boxplot of Shintyou")   # 箱ひげ図(横向き)
abline(v=seq(150,180,10), lty=3)

plot(Student20a$Height, Student20a$Weight, main="Scatter Plot of Shintyou and Weight")   # 散布図
abline(h=seq(40,100,10), lty=3)
abline(v=seq(150,180,10), lty=3)