毎回やる儀式

Rことはじめ

Rは一問一答式のプログラム言語です。 四則演算,関数の使い方,代入方法などについて順に説明していきます。 コピペでいいので,自分の環境で実行しながらついてきてください。

四則演算

2+3
## [1] 5
3-4
## [1] -1
5*6
## [1] 30
6/3
## [1] 2

関数を使う

sqrt(4)
## [1] 2
help(sqrt)
## starting httpd help server ... done

オブジェクトに代入する

obj <- 2
obj
## [1] 2
obj <- 3
obj
## [1] 3
obj2 <- 2
obj3 <- 3
obj2 + obj3
## [1] 5

ベクトルで扱う

obj <- c(1,2,3)
obj
## [1] 1 2 3
obj <- c(1:10)
obj
##  [1]  1  2  3  4  5  6  7  8  9 10
obj * 2
##  [1]  2  4  6  8 10 12 14 16 18 20

行列形式

obj <- matrix(c(1:10),nrow=5)
obj
##      [,1] [,2]
## [1,]    1    6
## [2,]    2    7
## [3,]    3    8
## [4,]    4    9
## [5,]    5   10
obj <- matrix(c(1:10),nrow=5,byrow=T)
obj
##      [,1] [,2]
## [1,]    1    2
## [2,]    3    4
## [3,]    5    6
## [4,]    7    8
## [5,]    9   10
obj *2
##      [,1] [,2]
## [1,]    2    4
## [2,]    6    8
## [3,]   10   12
## [4,]   14   16
## [5,]   18   20

行列の計算や,行列用の関数については自分で調べてね。

データセットとして:リスト形式

obj <- list(name=c("kosugi","tanaka","suzuki"),
            gender=c("male","female","male"),
            hight=c(170,160),
            weight=c(70.6,80.9,90.6,40.3)
            )
obj
## $name
## [1] "kosugi" "tanaka" "suzuki"
## 
## $gender
## [1] "male"   "female" "male"  
## 
## $hight
## [1] 170 160
## 
## $weight
## [1] 70.6 80.9 90.6 40.3
obj$name
## [1] "kosugi" "tanaka" "suzuki"
obj$weight
## [1] 70.6 80.9 90.6 40.3
str(obj)
## List of 4
##  $ name  : chr [1:3] "kosugi" "tanaka" "suzuki"
##  $ gender: chr [1:3] "male" "female" "male"
##  $ hight : num [1:2] 170 160
##  $ weight: num [1:4] 70.6 80.9 90.6 40.3

データセットとして:データフレーム形式

obj <- data.frame(
            list(name=c("kosugi","tanaka","suzuki"),
                gender=c(1,2,1),
                hight=c(170,160,170),
                weight=c(70.6,80.9,90.6)
                )
            )
obj
##     name gender hight weight
## 1 kosugi      1   170   70.6
## 2 tanaka      2   160   80.9
## 3 suzuki      1   170   90.6
str(obj)
## 'data.frame':    3 obs. of  4 variables:
##  $ name  : Factor w/ 3 levels "kosugi","suzuki",..: 1 3 2
##  $ gender: num  1 2 1
##  $ hight : num  170 160 170
##  $ weight: num  70.6 80.9 90.6
obj$gender
## [1] 1 2 1
obj$gender <- factor(obj$gender,labels=c("male","female"))
obj
##     name gender hight weight
## 1 kosugi   male   170   70.6
## 2 tanaka female   160   80.9
## 3 suzuki   male   170   90.6
str(obj)
## 'data.frame':    3 obs. of  4 variables:
##  $ name  : Factor w/ 3 levels "kosugi","suzuki",..: 1 3 2
##  $ gender: Factor w/ 2 levels "male","female": 1 2 1
##  $ hight : num  170 160 170
##  $ weight: num  70.6 80.9 90.6
obj$hight
## [1] 170 160 170
obj[3,]
##     name gender hight weight
## 3 suzuki   male   170   90.6
obj[,2]
## [1] male   female male  
## Levels: male female
obj[3,2]
## [1] male
## Levels: male female
obj[3,2] <- NA
obj
##     name gender hight weight
## 1 kosugi   male   170   70.6
## 2 tanaka female   160   80.9
## 3 suzuki   <NA>   170   90.6
summary(obj)
##      name      gender      hight           weight     
##  kosugi:1   male  :1   Min.   :160.0   Min.   :70.60  
##  suzuki:1   female:1   1st Qu.:165.0   1st Qu.:75.75  
##  tanaka:1   NA's  :1   Median :170.0   Median :80.90  
##                        Mean   :166.7   Mean   :80.70  
##                        3rd Qu.:170.0   3rd Qu.:85.75  
##                        Max.   :170.0   Max.   :90.60

簡単な描画

Rが持っているサンプルデータを使ってプロットしてみましょう。

data(iris)
summary(iris)
##   Sepal.Length    Sepal.Width     Petal.Length    Petal.Width   
##  Min.   :4.300   Min.   :2.000   Min.   :1.000   Min.   :0.100  
##  1st Qu.:5.100   1st Qu.:2.800   1st Qu.:1.600   1st Qu.:0.300  
##  Median :5.800   Median :3.000   Median :4.350   Median :1.300  
##  Mean   :5.843   Mean   :3.057   Mean   :3.758   Mean   :1.199  
##  3rd Qu.:6.400   3rd Qu.:3.300   3rd Qu.:5.100   3rd Qu.:1.800  
##  Max.   :7.900   Max.   :4.400   Max.   :6.900   Max.   :2.500  
##        Species  
##  setosa    :50  
##  versicolor:50  
##  virginica :50  
##                 
##                 
## 
hist(iris$Sepal.Length)

plot(iris$Sepal.Length,iris$Sepal.Width)

plot(iris$Sepal.Length,iris$Sepal.Width,pch=21,bg=c(2,3,4)[iris$Species])

boxplot(iris$Sepal.Length~iris$Species)

Rで記述統計

mean(iris$Sepal.Length)
## [1] 5.843333
median(iris$Sepal.Length)
## [1] 5.8
var(iris$Sepal.Length)
## [1] 0.6856935
sd(iris$Sepal.Length)
## [1] 0.8280661
cor(iris$Sepal.Length,iris$Sepal.Width)
## [1] -0.1175698

データ・ハンドリング

実際に自分のデータを分析する時は,外部ファイルから読み込むことが一般的です。 配布済みのデータセットを読み込んでみましょう。 10.16追記 エンコーディングのところでエラーがでるので指定しないようにしました。

b.data <- read.csv("baseball2015.csv",na.strings="*")
summary(b.data)
##  CP                name               team        money         position 
##  C:100   クルーズ    :  2   巨人        :24   Min.   : 4250   外野手:38  
##  P:100   T?岡田     :  1   ソフトバンク:23   1st Qu.: 6000   投手  :95  
##          Y.グリエル:  1   オリックス  :20   Median : 9750   内野手:58  
##          アンダーソン:  1   ヤクルト    :17   Mean   :13467   捕手  : 9  
##          イ・デウン  :  1   中日        :16   3rd Qu.:16375              
##          ウィーラー  :  1   日本ハム    :16   Max.   :51000              
##          (Other)     :193   (Other)     :84                              
##       year            age           birth.y        birth.m     
##  Min.   : 1.00   Min.   :21.00   Min.   :1970   Min.   : 1.00  
##  1st Qu.: 4.00   1st Qu.:29.00   1st Qu.:1980   1st Qu.: 4.00  
##  Median : 9.00   Median :31.00   Median :1983   Median : 7.00  
##  Mean   : 8.79   Mean   :31.75   Mean   :1983   Mean   : 7.01  
##  3rd Qu.:13.00   3rd Qu.:35.00   3rd Qu.:1986   3rd Qu.:10.00  
##  Max.   :27.00   Max.   :45.00   Max.   :1994   Max.   :12.00  
##                                                                
##     birth.d          height          weight        b.type   throw   
##  Min.   : 1.00   Min.   :167.0   Min.   : 67.00   A   :59   右:172  
##  1st Qu.: 9.00   1st Qu.:178.0   1st Qu.: 80.00   AB  :14   左: 28  
##  Median :15.00   Median :180.5   Median : 87.50   B   :34           
##  Mean   :15.95   Mean   :181.9   Mean   : 88.62   O   :47           
##  3rd Qu.:24.25   3rd Qu.:185.0   3rd Qu.: 95.25   不明:46           
##  Max.   :31.00   Max.   :205.0   Max.   :130.00                     
##                                                                     
##  hit                  from    
##  右:129   アメリカ      : 25  
##  左: 66   大阪          : 15  
##  両:  5   京都          : 10  
##           ドミニカ共和国:  9  
##           神奈川        :  9  
##           福岡          :  9  
##           (Other)       :123
head(b.data)
##   CP         name       team money position year age birth.y birth.m
## 1  C 阿部 慎之助       巨人 51000   内野手   15  36    1979       3
## 2  C   杉内 俊哉       巨人 50000     投手   14  34    1980      10
## 3  P   金子 千尋 オリックス 50000     投手   11  31    1983      11
## 4  C     マートン       阪神 45600   外野手    6  34    1981      10
## 5  C   黒田 博樹       広島 40000     投手   12  40    1975       2
## 6  C     鳥谷 敬       阪神 40000   内野手   12  34    1981       6
##   birth.d height weight b.type throw hit     from
## 1      20    180     97      A    右  左     千葉
## 2      30    175     82      A    左  左     福岡
## 3       8    180     77      O    右  左     新潟
## 4       3    185     99   不明    右  右 アメリカ
## 5      10    185     93      B    右  右     大阪
## 6      26    180     77      B    右  左     東京
tail(b.data)
##     CP         name     team money position year age birth.y birth.m
## 195  C   松岡 健一 ヤクルト  4550     投手   11  33    1982       6
## 196  C 小笠原 道大     中日  4500   内野手   19  41    1973      10
## 197  C   大野 雄大     中日  4500     投手    5  27    1988       9
## 198  C   藤井 彰人     阪神  4500     捕手   17  39    1976       6
## 199  C   福谷 浩司     中日  4500     投手    3  24    1991       1
## 200  C ザガースキー     広島  4250     投手    1  32    1983       1
##     birth.d height weight b.type throw hit     from
## 195       7    181     85     AB    右  右     熊本
## 196      25    178     84      A    右  左     千葉
## 197      26    183     78      O    左  左     京都
## 198      18    170     80     AB    右  右     大阪
## 199       9    183     90      B    右  右     愛知
## 200      27    183    109   不明    左  左 アメリカ

データの部分抽出

セ・リーグのデータだけにします。

centrals <- subset(b.data,b.data$CP=="C")
summary(centrals)
##  CP                name          team        money         position 
##  C:100   Y.グリエル: 1   巨人    :24   Min.   : 4250   外野手:20  
##  P:  0   アンダーソン: 1   ヤクルト:17   1st Qu.: 6000   投手  :48  
##          エルドレッド: 1   中日    :16   Median :10000   内野手:28  
##          エルナンデス: 1   広島    :15   Mean   :13595   捕手  : 4  
##          オンドルセク: 1   阪神    :15   3rd Qu.:16375              
##          グスマン    : 1   DeNA    :13   Max.   :51000              
##          (Other)     :94   (Other) : 0                              
##       year            age           birth.y        birth.m     
##  Min.   : 1.00   Min.   :21.00   Min.   :1970   Min.   : 1.00  
##  1st Qu.: 4.00   1st Qu.:30.00   1st Qu.:1979   1st Qu.: 4.00  
##  Median :10.00   Median :32.00   Median :1983   Median : 7.00  
##  Mean   : 9.57   Mean   :32.48   Mean   :1982   Mean   : 7.03  
##  3rd Qu.:13.25   3rd Qu.:36.00   3rd Qu.:1985   3rd Qu.:10.00  
##  Max.   :27.00   Max.   :44.00   Max.   :1994   Max.   :12.00  
##                                                                
##     birth.d          height          weight        b.type   throw  
##  Min.   : 1.00   Min.   :167.0   Min.   : 68.00   A   :32   右:82  
##  1st Qu.:10.75   1st Qu.:178.8   1st Qu.: 81.75   AB  :11   左:18  
##  Median :16.00   Median :182.0   Median : 88.00   B   :16          
##  Mean   :17.30   Mean   :182.2   Mean   : 89.10   O   :19          
##  3rd Qu.:26.00   3rd Qu.:185.0   3rd Qu.: 96.00   不明:22          
##  Max.   :31.00   Max.   :203.0   Max.   :122.00                    
##                                                                    
##  hit           from   
##  右:65   アメリカ:12  
##  左:32   大阪    :10  
##  両: 3   神奈川  : 7  
##          千葉    : 6  
##          愛知    : 5  
##          京都    : 5  
##          (Other) :55

身長と体重のデータだけ抜き出し,相関関係を見てみます。

physical <- subset(b.data,select=c("height","weight"))
cor(physical)
##           height    weight
## height 1.0000000 0.7284891
## weight 0.7284891 1.0000000

2015からプレイ年数(year)を引くことで,入団年(あるいはプロになった年齢)がわかります。これを新しい変数にします。

b.data$nyudan <- 2015-b.data$year

プレイ年数が第一4分位より長い人はexpertというラベルを張ることにします。

hist(b.data$year)

quantile(b.data$year,prob=c(0,0.25,0.5,0.75,1))
##   0%  25%  50%  75% 100% 
##    1    4    9   13   27
b.data$grade <- ifelse(b.data$year>=13,1,2)
b.data$grade <- factor(b.data$grade,labels=c("expert","normal"))
table(b.data$grade)
## 
## expert normal 
##     52    148

探索的データプロット

** データは図にする。プロットする。** これが分析の基本です。まずデータがどういう特徴を持っているかを,しっかりと目で把握しましょう。 それができていないと,データにモデルを当てはめるという話が始まりませんので。

ggplot2の導入

探索的データプロットのパッケージ,ggplot2をインストールします。

install.packages("ggplot2")

インストールしただけでは使えません。library関数(またはrequire関数)で装備します。

library(ggplot2)

まずはデータと全体設定を持ったggplotオブジェクトを作ります。

gp <- ggplot(b.data,aes(x=year,y=money,color=team))

点を打ってみましょう。

gp_point <- gp + geom_point()
plot(gp_point)

色だけじゃなく,大きさや形状を変えてプロットすることもできます。

gp <- ggplot(b.data,aes(x=year,y=money,color=team,shape=position,size=b.type))
gp_point <- gp + geom_point()
plot(gp_point)

タイトルや軸ラベルも書いておきましょう。

gp <- ggplot(b.data,aes(x=year,y=money,color=team,shape=position,size=b.type))
gp_point <- gp + geom_point()+xlab("プレイ期間")+ylab("年俸")+ggtitle("野球選手の年棒とプレイ期間の関係")
plot(gp_point)

画を複数に分けることもできます。

gp <- ggplot(b.data,aes(x=year,y=money,color=team,shape=position))
gp_point <- gp + geom_point() + facet_wrap(~b.type)
plot(gp_point)

横軸がカテゴリカルであれば,箱ひげ図や棒グラフになります。

gp <- ggplot(b.data,aes(x=team,y=money,fill=position))
gp_box <- gp + geom_boxplot()
plot(gp_box)

gp_bar <- gp + geom_bar(stat="identity",position="dodge")
plot(gp_bar)

# 平均が見たい
gp_bar <- gp + stat_summary(fun.y=mean,geom="bar",position="dodge")
plot(gp_bar)

# 中央値が見たい
gp_bar <- gp + stat_summary(fun.y=median,geom="bar",position="dodge")
plot(gp_bar)

エラーバーを追加する例。

gp <- ggplot(b.data,aes(x=position,y=money,fill=position))
gp_bar <- gp + stat_summary(fun.y=mean,geom="bar",position="dodge") + 
                stat_summary(fun.data=mean_se,geom="errorbar",width=0.5)
plot(gp_bar)

様々な角度からデータをプロットし,分布の形状や変数間関係をしっかり見極める癖をつけましょう。

本日の課題

  • 野球選手のBMIを計算してください。計算した値は,同じデータセットにBMIという変数を作って入れてください。
  • 年俸と守備位置とBMIの関係をグラフにして表現してください。何グラフを用いても良い。