問題
- ggplotでは,scale_*_*などでlimitsを指定すると描画範囲の上限と下限を指定できます。ただ,デフォルトではこの上限や下限を超えたデータポイントは除外,無視して描画されます。
例えば,以下のような外れ値を含むデータがあります。
library(tidyverse)
x <- rnorm(n=10, mean=4,sd=1)
e <- rnorm(n=10, mean=0,sd=3)
y <- 50 + 10*x + e
df <- tibble(X=c(x,20),
Y=c(y,0))
df
# A tibble: 11 × 2
X Y
<dbl> <dbl>
1 4.30 89.8
2 5.06 96.0
3 3.66 86.1
4 4.63 93.9
5 2.85 79.4
6 3.56 87.8
7 4.43 92.3
8 3.56 90.1
9 3.16 87.3
10 5.88 106.
11 20 0
- これを描画するとこんな感じ。
ggplot(data = df,
mapping = aes(x=X,
y=Y))+
geom_point()+
geom_smooth(stat = "smooth",
method = "lm")
- こんなことをする人がいるのかはわからないですが,
scale_y_continuous
とscale_x_continuous
を用いて,上限と下限を設定してみます。
ggplot(data = df,
aes(x = X,
y = Y))+
geom_point()+
geom_smooth(stat = "smooth",
method = "lm")+
scale_x_continuous(limits = c(1,8))+
scale_y_continuous(limits = c(60,120))
- 描画範囲に入らないデータポイントは除外されてしまいました。そのため,回帰直線の傾きが大きく異なるのがわかります。
- もちろん「除外されてるぞ」と出力が返ってきます。
Warning messages:
1: Removed 1 rows containing non-finite values (`stat_smooth()`).
2: Removed 1 rows containing missing values (`geom_point()`).
解決
- 考えてみたら当たり前ですが,scale_*_*では描画範囲外のデータポイントをどのように扱うかの引数(
oob
)があります。 -
scales package
で提供される関数を指定すれば 「描画はしないけど,回帰直線などには反映する」 といったことが可能になります。 - 例えば以下のように書きます。
install.packages(scales)
library(scales)
ggplot(data=df,
aes(x=X,
y=Y))+
geom_point()+
geom_smooth(stat = "smooth",
method = "lm")+
scale_x_continuous(limits = c(1,8), oob = oob_keep)+
scale_y_continuous(limits = c(60,120), oob = oob_keep)
-
oob = oob_keep
と指定するとデータは除外されず, 図を拡大したような描画になります。 -
その他にも
- oob_censor
- デフォルト
- 範囲外の値はNAに変換
- oob_squish
- 範囲外の値を上限や下限の制限値に置き換える
- 値が20で
limits=c(0,10)
などとした場合は 値が10 に変更されて描画される
- oob_censor
-
いくつかあるので以下を参照してください
- ggplot2の公式documentにもscalesパッケージが紹介されていました。
- 多様するパッケージのdocumentぐらいちゃんと読むべきですね。。。
棒グラフの場合
- 次は棒グラフです。
- こんな平均値とSEのデータがあります。
df <- tibble(cnd = c("A", "B"),
M = c(350, 400),
SE = c(60, 40))
df
# A tibble: 2 × 3
cnd M SE
<chr> <dbl> <dbl>
1 A 350 60
2 B 400 40
- 平均値を棒グラフで表現し,SEをエラーバーで表現します。
ggplot(data = df,
aes(x = cnd,
y = M,
fill = cnd))+
geom_bar(stat = "identity")+
geom_errorbar(aes(ymin = M - SE,
ymax = M + SE))
- こんな感じで出力されます。
- さて,この棒グラフのy軸を操作してみます。
ggplot(data = df,
aes(x = cnd,
y = M,
fill = cnd))+
geom_bar(stat = "identity")+
geom_errorbar(aes(ymin = M - SE,
ymax = M + SE))+
scale_y_continuous(limits=c(300,500)) # ここだけ追加
-
棒とエラーバーの一部が消えてしましました。
-
これも散布図の時と同じように描画範囲外のものは除外されるためです。
-
対応は散布図の時と同様で,
oob
を指定してやれば良いです。
ggplot(data = df,
aes(x = cnd,
y = M,
fill = cnd))+
geom_bar(stat = "identity")+
geom_errorbar(aes(ymin = M - SE,
ymax = M + SE))+
scale_y_continuous(limits=c(300,500), oob = oob_keep)
-
oob_keep
ではなく,oob_squish
と指定すると
ggplot(data = df,
aes(x = cnd,
y = M,
fill = cnd))+
geom_bar(stat = "identity")+
geom_errorbar(aes(ymin = M - SE,
ymax = M + SE))+
scale_y_continuous(limits=c(300,500), oob = oob_squish)
- ちょっとだけ違いますね。
-
oob_squish
の方では,300未満の部分が消えています。 - 制限値に変換しているためですね。
-
終わりに
- 昔の私が困っていたものについての記事でした。