◯◯◯ 使用するライブラリ
ggplot2ライブラリ(グラフ描画パッケージ)およびdplyr(データ操作)を使用するために、tidyverseパッケージを、また、複数グラフ配置のためにpatchworkライブラリを使います。
📌 本資料は ggplot2 4.0 に対応しています(動作確認:R 4.4.2、ggplot2 4.0.0)。
線の太さにはsizeではなくlinewidth、棒グラフ上の個数表示には..count..ではなくafter_stat(count)を使っています。古い書き方は、警告が出たり、将来の更新で動かなくなったりします。
手元のバージョンはpackageVersion("ggplot2")で確認できます(3.4 未満の場合はinstall.packages("ggplot2")で更新してください)。
install.packages("tidyverse")
install.packages("patchwork")
library(ggplot2)
library(dplyr)
library(patchwork)
packageVersion("ggplot2") # 4.0.0以上であることを確認
## [1] '4.0.0'
◯◯◯ データフレームをインポート
以下から、奇数偶数の好み実験結果の架空(N=3543)のデータをインポートしてください。
url = "https://lab.kenrikodaka.com/_download/csv/oddeven_3543.csv"
source = read.csv(url)
誕生日と奇数偶数の好みに関するアンケートの架空のデータ(3543人分)です。
#最初の6行をちょっと出し
source[1:6,]
## month day preference gender age domhand ## 1 4 11 ODD MALE 19 RIGHT ## 2 7 18 EVEN FEMALE 18 RIGHT ## 3 11 7 ODD MALE 20 RIGHT ## 4 2 6 ODD MALE 66 RIGHT ## 5 5 21 EVEN MALE 20 RIGHT ## 6 2 2 EVEN MALE 19 RIGHT
NAは「回答なし(未定)」です(ageとdomhandに492件ずつあります)。 また、ageには「-1」など、明らかに不自然な値も少数含まれます。
翻訳すると以下の様になります。
# 全部で3543人分のデータがあることが確認できます。
dim(source)
## [1] 3543 6
◯◯◯ mutateの復習
mutate(要dplyr)を使うと データフレームの属性を簡単に追加/更新できます。
# sourceをdatにコピーします。
dat = source
head(dat,3)
## month day preference gender age domhand ## 1 4 11 ODD MALE 19 RIGHT ## 2 7 18 EVEN FEMALE 18 RIGHT ## 3 11 7 ODD MALE 20 RIGHT
datに月日の奇数/偶数のラベル(mtype)を新たに追加します。
# 2で割った余りを変数mtypeに登録
dat2 = dat %>%
mutate(mtype=month%%2)
head(dat2,4)
## month day preference gender age domhand mtype ## 1 4 11 ODD MALE 19 RIGHT 0 ## 2 7 18 EVEN FEMALE 18 RIGHT 1 ## 3 11 7 ODD MALE 20 RIGHT 1 ## 4 2 6 ODD MALE 66 RIGHT 0
# characterに変換
dat2 = dat2 %>%
mutate(mtype = if_else(mtype==0,"EVEN","ODD"))
head(dat2,4)
## month day preference gender age domhand mtype ## 1 4 11 ODD MALE 19 RIGHT EVEN ## 2 7 18 EVEN FEMALE 18 RIGHT ODD ## 3 11 7 ODD MALE 20 RIGHT ODD ## 4 2 6 ODD MALE 66 RIGHT EVEN
# 同様にdtypeも追加
dat2 = dat2 %>%
mutate(dtype = if_else(day%%2==0,"EVEN","ODD"))
head(dat2,4)
## month day preference gender age domhand mtype dtype ## 1 4 11 ODD MALE 19 RIGHT EVEN ODD ## 2 7 18 EVEN FEMALE 18 RIGHT ODD EVEN ## 3 11 7 ODD MALE 20 RIGHT ODD ODD ## 4 2 6 ODD MALE 66 RIGHT EVEN EVEN
3つ以上の分岐はcase_whenを使います。
dat2 = dat2 %>%
mutate(combo =
case_when(mtype=="EVEN" & dtype=="EVEN" ~ "EE",
mtype=="ODD" & dtype=="ODD" ~ "OO",
mtype=="EVEN" & dtype=="ODD" ~ "EO",
TRUE ~ "OE"));
head(dat2,4)
## month day preference gender age domhand mtype dtype combo ## 1 4 11 ODD MALE 19 RIGHT EVEN ODD EO ## 2 7 18 EVEN FEMALE 18 RIGHT ODD EVEN OE ## 3 11 7 ODD MALE 20 RIGHT ODD ODD OO ## 4 2 6 ODD MALE 66 RIGHT EVEN EVEN EE
グラフを作成します。
## 4つのcomboごとに、偶数好きと奇数好きの人数を数え上げます。
g = ggplot(dat2, aes(x=combo, fill=preference))
g = g + geom_bar(position = position_dodge()) #fillを横に並べる
g = g + scale_fill_brewer(palette = "Dark2")
g = g + ggtitle("Graph0_Mutate") #グラフのタイトル
g | plot_spacer()
◯◯◯ pivot_longer
今回の演習では、グラフ化に先立って、 特定の変数に関して、「偶数」「奇数」「奇素数」ごとの特性を比較集計する 場面が多くなります。 この場合、比較する条件に重複がない場合は(たとえば「奇数」と「偶数」)、集計は容易です。
例えば、月の属性ごとの偶数好き割合は、以下で一気に出せますね。
dat = source
dat %>%
mutate(month.type = if_else(month%%2 == 0,"EVEN","ODD")) %>%
group_by(month.type) %>%
summarize(
erate = mean(preference == 'EVEN')
)
## # A tibble: 2 × 2 ## month.type erate ## <chr> <dbl> ## 1 EVEN 0.628 ## 2 ODD 0.545
他方で、「偶数」「奇数」「奇素数」で分けたい場合、 「奇素数」は「奇数」に含まれるので、一つの変数で綺麗に分けることができなくなります。
このようなケースでは、
pivot_longerを使った集計が便利です。pivot_longerは、簡単にいうと、「列を減らした分を行で表現する」手続きとなります。
わかりやすく、最初の8行の「月」と「好み」を抽出したデータフレーム(
dat2)を使って説明します。
# select関数がconflictする場合は、以下を実行してください。
# detach("package:MASS", unload = TRUE)
dat = source
dat2 = dat %>%
filter(row_number() <=8) %>%
select(month, preference)
dat2
## month preference ## 1 4 ODD ## 2 7 EVEN ## 3 11 ODD ## 4 2 ODD ## 5 5 EVEN ## 6 2 EVEN ## 7 10 EVEN ## 8 5 EVEN
dat2について、各行の月の属性を属性ごとの変数(EVEN,ODD,PRIME)を用意して、論理値で整形します。
dat2 = dat2 %>%
mutate(EVEN = month%%2==0,
ODD = month%%2==1,
PRIME = month %in% c(3,5,7,11)
)
dat2
## month preference EVEN ODD PRIME ## 1 4 ODD TRUE FALSE FALSE ## 2 7 EVEN FALSE TRUE TRUE ## 3 11 ODD FALSE TRUE TRUE ## 4 2 ODD TRUE FALSE FALSE ## 5 5 EVEN FALSE TRUE TRUE ## 6 2 EVEN TRUE FALSE FALSE ## 7 10 EVEN TRUE FALSE FALSE ## 8 5 EVEN FALSE TRUE TRUE
ここで
pivot_longerを用いて 変数名を新たな変数「group」の値として、 元々の値を、新たな変数「belongs」の値にスライドします。
library(tidyr)
dat3 = dat2 %>%
pivot_longer(
cols = c(EVEN, ODD, PRIME),
names_to = "group",
values_to = "belongs"
)
dat3
## # A tibble: 24 × 4 ## month preference group belongs ## <int> <chr> <chr> <lgl> ## 1 4 ODD EVEN TRUE ## 2 4 ODD ODD FALSE ## 3 4 ODD PRIME FALSE ## 4 7 EVEN EVEN FALSE ## 5 7 EVEN ODD TRUE ## 6 7 EVEN PRIME TRUE ## 7 11 ODD EVEN FALSE ## 8 11 ODD ODD TRUE ## 9 11 ODD PRIME TRUE ## 10 2 ODD EVEN TRUE ## # ℹ 14 more rows
# ここからbelongsがTRUEのものだけを抽出する。
dat3 = dat3 %>%
filter(belongs) %>%
select(month,group,preference)
dat3
## # A tibble: 12 × 3 ## month group preference ## <int> <chr> <chr> ## 1 4 EVEN ODD ## 2 7 ODD EVEN ## 3 7 PRIME EVEN ## 4 11 ODD ODD ## 5 11 PRIME ODD ## 6 2 EVEN ODD ## 7 5 ODD EVEN ## 8 5 PRIME EVEN ## 9 2 EVEN EVEN ## 10 10 EVEN EVEN ## 11 5 ODD EVEN ## 12 5 PRIME EVEN
結果として、奇素数の月のみ (上の例では、67と910行目)が 重複してエントリーされていることがわかります。
これを使って、最初の8行に、 3つの属性に適合する月の数字がいくつあるかを 以下で算出することができます。
dat3 %>%
group_by(group) %>%
summarize(
n=n()
)
## # A tibble: 3 × 2 ## group n ## <chr> <int> ## 1 EVEN 4 ## 2 ODD 4 ## 3 PRIME 4
以上を応用して、全てのデータについて、 月属性が「偶数」「奇数」「奇素数」ごとの 偶数好きの割合を一気に算出します。
dat = source
dat2 = dat %>%
# 月と好みに注目し、月の数字の3属性を変数に付加
select(month,preference) %>%
mutate(EVEN = month%%2==0,
ODD = month%%2==1,
PRIME = month %in% c(3,5,7,11)
) %>%
# 変数を行に展開し、
# もともとの値がTRUEのもののみをfilterで抽出します。
pivot_longer(
cols = c(EVEN, ODD, PRIME),
names_to = "group",
values_to = "belongs"
) %>%
filter(belongs == TRUE) %>%
group_by(group) %>%
# 各属性の数(n)と偶数好き割合を算出します。
summarize(
n = n(),
erate = sum(preference=="EVEN") / n
# erate = mean(preference=="EVEN") ##同じ
)
dat2
## # A tibble: 3 × 3 ## group n erate ## <chr> <int> <dbl> ## 1 EVEN 1722 0.628 ## 2 ODD 1821 0.545 ## 3 PRIME 1208 0.534
# sourceをそのままdatに移します。
dat = source
# [ggplot]
## x軸をgenderに、枠線と塗りつぶしをpreferenceに設定
g = ggplot(dat,aes(x=gender, fill=preference))
# [geom_bar] genderごとにpreferenceを数え上げ
## position_dodge:横並び, width:グラフの幅, alpha:透明度
g = g + geom_bar(position=position_dodge(width=0.9),alpha=0.9)
g1 = g + ggtitle("g1") #出力用
# X軸は離散値、Y軸は連続値
g = g + scale_x_discrete(limits = c("FEMALE", "MALE"))
g = g + scale_y_continuous(limits = c(-100, 1400),breaks=c(0,250,500,750,1000,1250))
# 塗りつぶしのパレットをDark2(brewer)
g = g + scale_fill_brewer(palette = "Dark2")
g2 = g + ggtitle("g2") #出力用
# 90度回転
g = g + coord_flip()
# [geom_text]
## geom_barの数え上げの量を表示
## just=0(左揃え), 0.5(中央揃え), 1(右揃え)
g = g + geom_text(stat = "count",
aes(label = paste("(",after_stat(count),")",sep=""),
y=after_stat(count)*0.95, hjust=1),
position = position_dodge(width=0.9),
color="white", size=3)
# [labs]
## グラフのタイトル、XY軸のタイトル
g = g + labs(x = "Gender", y = "Population")
(g1 | g2) / g +ggtitle("Graph1_Gender")
グラフ化までは、
pivot_longerの解説の復習となります。
まずは準備として、奇素数(2を除く素数)を判定する関数を作成します(月と日にちの数字を想定としています。)。
# returnはあってもなくてもよい。
oddprime = function(n){
n %in% c(3,5,7,11,13,17,19,23,29,31)
}
# 使用例
oddprime(1:31)
## [1] FALSE FALSE TRUE FALSE TRUE FALSE TRUE FALSE FALSE FALSE TRUE FALSE ## [13] TRUE FALSE FALSE FALSE TRUE FALSE TRUE FALSE FALSE FALSE TRUE FALSE ## [25] FALSE FALSE FALSE FALSE TRUE FALSE TRUE
月の数字の属性のみに注目し、重複を許すかたちで 各行で、月の属性(奇数・偶数・奇素数)と数字の好みが出力されるようなデータフレームに整形します。
dat = source
dat_ = dat %>%
# 女性のみの行、月と好みの列だけを取り出す。
filter(gender=="FEMALE") %>%
select(month,preference) %>%
# 偶数・奇数・奇素数の変数を追加(値は論理値)
mutate(EVEN = (month %% 2==0),
ODD = (month %% 2 == 1),
PRIME = oddprime(month)
) %>%
# 月の数字属性を行に展開
pivot_longer(
cols = c(EVEN,ODD,PRIME),
names_to = "group", #数字属性の変数名
values_to = "belongs" #論理値の変数名
) %>%
# belongs=TRUEのみを抽出し、
# month,group,preference変数のみを取り出す
filter(belongs) %>%
select(month,group,preference)
#ここで一旦、dat_の内容を確認しましょう。
## 素数の数字のみ、2回のエントリーがあることを確認してください。
head(dat_,10)
## # A tibble: 10 × 3 ## month group preference ## <int> <chr> <chr> ## 1 7 ODD EVEN ## 2 7 PRIME EVEN ## 3 11 ODD ODD ## 4 11 PRIME ODD ## 5 3 ODD ODD ## 6 3 PRIME ODD ## 7 10 EVEN EVEN ## 8 3 ODD ODD ## 9 3 PRIME ODD ## 10 6 EVEN EVEN
最後に3つのグループのうち、 preferenceがEVENの割合を算出したデータフレームをxとして出力します。
x = dat_ %>%
group_by(group) %>%
summarize(
n = n(),
erate = sum(preference=="EVEN") / n
) %>%
select(group,n,erate)
# データフレームの内容を確認します。
## groupは月の数字の属性、
## nはサンプル数
## erateは偶数が好きな割合
x
## # A tibble: 3 × 3 ## group n erate ## <chr> <int> <dbl> ## 1 EVEN 923 0.687 ## 2 ODD 981 0.599 ## 3 PRIME 646 0.590
◯◯◯ 棒グラフの作成
# ベースラインからの偏り(100分率)をweightとします。
x = x %>%
mutate(weight = 100*(erate-0.5))
# [ggplot]
g = ggplot(x, aes(x = group, y = weight, fill = group, colour = group))
# [geom_bar]
## 個数(stat="count")でなく数値(stat="identity)を描画
g = g + geom_bar(stat = "identity",alpha=4/5)
# yは連続値
g = g + scale_y_continuous(limits=c(-10,30))
# 縦線(hline)と横線(vline)の描画
g = g + geom_hline(yintercept = 0, linetype = "solid", linewidth=0.5,colour="black")
g = g + geom_vline(xintercept = 1.5, linetype = "dotted", linewidth=0.5,colour="black")
g = g + geom_vline(xintercept = 2.5, linetype = "dotted", linewidth=0.5,colour="black")
# 色の設定
col1 = rgb(174/255,69/255,50/255) #for even
col2 = rgb(58/255,128/255,77/255) #for odd
col3 = rgb(48/255,112/255,176/255) #for prime
g = g + scale_fill_manual(values = c(col1,col2,col3), name="number type")
g = g + scale_colour_manual(values = c(col1,col2,col3), name = "number type")
# 90度回転
g = g + coord_flip()
# [labs]
## グラフのタイトル、XY軸のタイトル
g = g + labs(x = "Month Number type", y = "Even number preference (%)")
g = g + theme_minimal()
g + ggtitle("Graph2_FemaleMonth")
女性に限って、月 x 日が同じ属性だった場合の好みの違いを検証します。 奇素数 x 奇素数は奇数 x 奇数を含むため、 Graph2と同様に、
pivot_longerをうまく使う必要があります。
dat = source
dat_ = dat %>%
# 女性のみの行、月と好みの列だけを取り出す。
filter(gender=="FEMALE") %>%
select(month,day,preference) %>%
# 偶数・奇数・奇素数の変数を追加(値は論理値)
mutate(EVEN2 = (month%%2==0) & (day%%2==0),
ODD2 = (month%%2==1) & (day%%2==1),
PRIME2 = oddprime(month) & oddprime(day)
) %>%
# 月の数字属性を行に展開
pivot_longer(
cols = c(EVEN2,ODD2,PRIME2),
names_to = "group", #数字属性の変数名
values_to = "belongs" #論理値の変数名
) %>%
# belongs=TRUEのみを抽出し、
# month,daygroup,preference変数のみを取り出す
filter(belongs) %>%
select(month,day,group,preference)
#ここで一旦、dat_の内容を確認しましょう。
head(dat_,10)
## # A tibble: 10 × 4 ## month day group preference ## <int> <int> <chr> <chr> ## 1 11 5 ODD2 ODD ## 2 11 5 PRIME2 ODD ## 3 3 15 ODD2 ODD ## 4 10 10 EVEN2 EVEN ## 5 3 27 ODD2 ODD ## 6 11 11 ODD2 EVEN ## 7 11 11 PRIME2 EVEN ## 8 10 4 EVEN2 ODD ## 9 1 13 ODD2 ODD ## 10 10 24 EVEN2 ODD
最後に3つのグループのうち、 preferenceがEVENの割合を算出したデータフレームをxとして出力します。
x = dat_ %>%
group_by(group) %>%
summarize(
n = n(),
erate = sum(preference=="EVEN") / n
) %>%
select(group,n,erate)
# データフレームの内容を確認します。
## groupは月の数字の属性、
## nはサンプル数
## erateは偶数が好きな割合
x
## # A tibble: 3 × 3 ## group n erate ## <chr> <int> <dbl> ## 1 EVEN2 438 0.737 ## 2 ODD2 514 0.564 ## 3 PRIME2 202 0.579
◯◯◯ 棒グラフの作成
# 準備としてベースラインからの偏り(100分率)をweightとします。
x = x %>%
mutate(weight = 100*(erate-0.5))
x
## # A tibble: 3 × 4 ## group n erate weight ## <chr> <int> <dbl> <dbl> ## 1 EVEN2 438 0.737 23.7 ## 2 ODD2 514 0.564 6.42 ## 3 PRIME2 202 0.579 7.92
g = ggplot(x, aes(x = group, y = weight, fill = group, colour = group))
g = g + geom_bar(stat = "identity",alpha=4/5)
g = g + scale_y_continuous(limits=c(-10,30))
# x軸(離散値)のラベルを変更
g = g + scale_x_discrete(limits=c("EVEN2","ODD2","PRIME2"),
labels=c("EVENxEVEN","ODDxODD","PRIMExPRIME"))
g = g + geom_hline(yintercept = 0, linetype = "solid", linewidth=0.5,colour="black")
g = g + geom_vline(xintercept = 1.5, linetype = "dotted", linewidth=0.5,colour="black")
g = g + geom_vline(xintercept = 2.5, linetype = "dotted", linewidth=0.5,colour="black")
g = g + scale_fill_manual(values = c(col1,col2,col3), name="number type")
g = g + scale_colour_manual(values = c(col1,col2,col3), name = "number type")
g = g + coord_flip()
g = g + labs(x = "Number type", y = "Even number preference (%)")
g = g + theme_minimal()
g + ggtitle("Graph3_FemaleMonthDay")
dat_ = source
head(dat_)
## month day preference gender age domhand ## 1 4 11 ODD MALE 19 RIGHT ## 2 7 18 EVEN FEMALE 18 RIGHT ## 3 11 7 ODD MALE 20 RIGHT ## 4 2 6 ODD MALE 66 RIGHT ## 5 5 21 EVEN MALE 20 RIGHT ## 6 2 2 EVEN MALE 19 RIGHT
dayPref = dat_ %>%
group_by(day) %>%
summarize(
even= sum(preference=="EVEN"),
odd = sum(preference=="ODD"),
erate = mean(preference=="EVEN"),
) %>%
arrange(desc(erate))
dayPref = dayPref %>%
mutate(type = case_when(
day%%2==0 ~ "EVEN",
oddprime(day) ~ "PRIME",
TRUE ~ "ODD"),
order = row_number(), #行番号を挿入
)
dayPref
## # A tibble: 31 × 6 ## day even odd erate type order ## <int> <int> <int> <dbl> <chr> <int> ## 1 22 68 29 0.701 EVEN 1 ## 2 2 73 34 0.682 EVEN 2 ## 3 3 69 37 0.651 PRIME 3 ## 4 4 70 38 0.648 EVEN 4 ## 5 21 83 46 0.643 ODD 5 ## 6 12 78 45 0.634 EVEN 6 ## 7 30 60 36 0.625 EVEN 7 ## 8 16 85 52 0.620 EVEN 8 ## 9 26 75 46 0.620 EVEN 9 ## 10 17 60 37 0.619 PRIME 10 ## # ℹ 21 more rows
g = ggplot(dayPref,aes(x=order,y=100*erate,fill=type))
g = g + geom_bar(stat = "identity", colour="black")
#geom_bar(stat="identity")とgeom_colは同じなので、こちらでも同じ結果です。
#g = g + geom_col(colour ="black")
g = g + scale_x_continuous(limits=c(0.5,31.5),breaks=c(1,10,20,30))
g = g + scale_y_continuous(limits=c(0,87),breaks=c(0,25,50,75))
# 50%のところに線を引く
g = g + geom_hline(yintercept = 50, linetype = "dotted", linewidth=1,colour="black")
# 各順位に対応する数字をバーの上端より1.5文字分下に描画する
g = g + geom_text(aes(label = day), colour = "white", size = 3, vjust = 1.5)
# 凡例の色をマニュアルで指定する
g = g + scale_fill_manual(values = c(col1,col2,col3),name="Number type")
g = g + scale_colour_manual(values = c(col1,col2,col3),name="Number type")
g = g + labs(x="ORDER",y="EVEN-PREF RATE")
g = g + theme_minimal() +
theme(legend.position = "bottom")
g + ggtitle("Graph4_DayRank")
dat_ = source;
# 年齢ごとのpreferenceを集計する
# 行番号があると混乱するので消します。
print(dat_ %>% count(age),row.names = FALSE)
## age n ## -1 7 ## 12 2 ## 13 3 ## 14 1 ## 15 33 ## 16 57 ## 17 36 ## 18 1183 ## 19 1076 ## 20 327 ## 21 84 ## 22 27 ## 23 29 ## 24 17 ## 25 13 ## 26 9 ## 27 7 ## 28 6 ## 29 7 ## 30 6 ## 31 3 ## 32 3 ## 33 3 ## 34 2 ## 35 5 ## 36 4 ## 37 5 ## 38 2 ## 39 2 ## 40 3 ## 41 2 ## 42 6 ## 44 5 ## 45 3 ## 46 3 ## 47 4 ## 48 5 ## 49 4 ## 50 3 ## 51 6 ## 52 5 ## 53 4 ## 54 3 ## 55 3 ## 56 1 ## 57 5 ## 58 2 ## 59 4 ## 61 4 ## 62 3 ## 63 2 ## 64 2 ## 65 2 ## 66 3 ## 67 1 ## 68 1 ## 69 1 ## 71 1 ## 73 1 ## NA 492
# 比較的サンプルの多い、15〜22歳をとりあげます。
head(dat_)
## month day preference gender age domhand ## 1 4 11 ODD MALE 19 RIGHT ## 2 7 18 EVEN FEMALE 18 RIGHT ## 3 11 7 ODD MALE 20 RIGHT ## 4 2 6 ODD MALE 66 RIGHT ## 5 5 21 EVEN MALE 20 RIGHT ## 6 2 2 EVEN MALE 19 RIGHT
agePref = dat_ %>%
filter(age>14 & age<23) %>%
group_by(age) %>%
summarize(
even = sum(preference=="EVEN"),
odd = sum(preference=="ODD"),
erate = mean(preference=="EVEN") ## even / (even + odd)と同じ
) %>%
arrange(age)
agePref
## # A tibble: 8 × 4 ## age even odd erate ## <int> <int> <int> <dbl> ## 1 15 27 6 0.818 ## 2 16 37 20 0.649 ## 3 17 30 6 0.833 ## 4 18 722 461 0.610 ## 5 19 643 433 0.598 ## 6 20 180 147 0.550 ## 7 21 44 40 0.524 ## 8 22 13 14 0.481
◯◯◯ 折れ線グラフの作成
15歳から22歳までの偶数好きの割合の遷移を 折れ線グラフで視覚化します。
g = ggplot(agePref,aes(x=age,y=erate))
g = g + geom_line(colour = "black",linewidth=1.5)
g = g + geom_point(size=5)
g = g + scale_x_continuous(limits=c(14.5,22.5),breaks=15:22)
g = g + scale_y_continuous(limits=c(0,1.0),breaks=c(0,0.25,0.50,0.75,1.0))
g = g + labs(x="AGE",y="EVEN-PREF RATE")
g = g + theme_minimal() +
theme(legend.position = "bottom")
g + ggtitle("Graph5_AgeEffect")
ApMedia05_Work