論文作成・統計

【Rテクニック】棒グラフと折れ線グラフにエラーバーを付けたい!その簡単な方法を説明します

この記事では、Rのggplot2パッケージを使った、棒グラフと折れ線グラフにエラーバーをつける用法を紹介します!

棒グラフや折れ線グラフなどについているTが上下についているものがエラーバーです。エラーバーは標準誤差や標準偏差を示しています。

初心者のうちは、あれ、どうやるんだっけ、と意外に迷うものです。エクセルなどでも出来るかもしれませんが、ggplot2を使えば簡単にできます

それではさっそくやっていきましょう!

データの準備する

今回もtidyverseを利用します。自分のデータを使う場合には読み飛ばしてください!

# 作業ディレクトリのセット
setwd("~/Rpractice/")

# tidyverseの起動
library(tidyverse)

# ランダムデータの生成
dat <- list(
  X <- rnorm(50, 30, 10),
  Y <- rnorm(50, 50, 5),
  Z <- rnorm(50, 40, 15)
)
df <- data.frame(matrix(unlist(dat), nrow=50))
colnames(df) <- c("A","B","C")

#データの変形(横から縦へ)
df.long <- pivot_longer(df, cols = A:C, 
                        names_to = "Categories", 
                        values_to = "Values")

これでこのようなデータができました。

> head(df.long)
# A tibble: 6 x 2
  Categories Values
  <chr>       <dbl>
1 A            26.8
2 B            53.7
3 C            27.3
4 A            31.0
5 B            58.7
6 C            56.2
> 

棒グラフと折れ線グラフにエラーバーを加えるには、平均値と標準誤差(または標準偏差)が必要です。

データの平均、標準偏差、標準誤差を算出します

このデータの平均(mean)と標準偏差(sd)、標準誤差(se)を算出します。すでにデータがある場合にはここも読み飛ばしてください。

その算出方法も慣れれば簡単です!tidyverseに入っているdplyrを使っていきましょう。

dplyrのgroup_byとsummarise_allを使います

(summariseはアメリカ英語でsummarizeでもOKです)

a <- group_by(df.long, Categories) %>% 
  summarise_all(list(mean = ~mean(.), 
                     sd = ~sd(.), 
                     se = ~sd(.)/sqrt(length(.))))

これはもう少し簡素化できます。どちらを使っても大丈夫です。

a <- group_by(df.long, Categories) %>% 
  summarise_all(list(mean = mean, 
                     sd = sd, 
                     se = ~sd/sqrt(length(.))))

ではaのデータをみてみます。

> a
# A tibble: 3 x 4
  Categories  mean    sd    se
  <chr>      <dbl> <dbl> <dbl>
1 A           30.1  9.93 1.40 
2 B           49.2  5.00 0.708
3 C           43.9 15.5  2.20 

このような分布になりました!データはランダムで生成しましたので、同じ手順をなぞってもこの数値は若干変化します。

棒グラフでエラーバーを描きたい!

計算をしたデータを使って棒グラフをかきます。エラーバーはgeom_errorbarで指定します。まずはgeom_errorbarでyminとymaxのみを指定して、グラフをみてみましょう。

ggplot(a, aes(x = Categories, y = mean, fill = Categories))+
  geom_bar(stat = "identity") +
  geom_errorbar(aes(ymin = mean - se, ymax = mean + se))

横幅が広すぎますね。これをwidthで調整します。バーグラフ、エラーバーともに狭くしてみます。

ggplot(a, aes(x = Categories, y = mean, fill = Categories))+
  geom_bar(stat = "identity", width = 0.6) +
  geom_errorbar(aes(ymin = mean - se, ymax = mean + se),
                width = .1)

幅は出力する画像の大きさに合わせて適宜調整をするといいです。

折れ線グラフでエラーバーを描きたい!

折れ線グラフも上と同じ要領です。折れ線グラフを描いて、geom_errorbarを付け足します。

ggplot(a, aes(x = Categories, y = mean)) +
  geom_line(group = 1) +
  geom_point(size = 3) +
  geom_errorbar(aes(ymin = mean - se, ymax = mean + se),
                width = .1)

グループ化されたデータでのエラーバーを加える方法

グループ化したデータを生成してみます。

<pre class="wp-block-syntaxhighlighter-code"># IDを追加する
data <- df.long %>% 
  tibble::rownames_to_column(var = "ID")

# IDを文字列から数値へ変換する
data$ID <- as.numeric(data$ID)

# IDが75以下を1, 76以上を0と割り当てて、group列を作る
data <- mutate(data, group = ifelse(ID < 76, 1, 0))

# mean, SD, SEを算出
b <- group_by(data, group, Categories) %>% 
  summarise_at(vars(Values), list(mean = ~mean(.), 
                     sd = ~sd(.), 
                     se = ~sd(.)/sqrt(length(.))))

# group列の数値を文字列に変換する
b$group <- as.character(b$group)

# bに含まれているデータを確認する
> head(b)
# A tibble: 6 x 5
# Groups:   group <img class="ranking-number" src="https://brain-storm.space/wp-content/themes/jin/img/rank02.png" />
  group Categories  mean    sd    se
  <chr> <chr>      <dbl> <dbl> <dbl>
1 0     A           31.4 11.1  2.21 
2 0     B           51.0  4.31 0.862
3 0     C           33.9 13.5  2.70 
4 1     A           29.5 10.4  2.08 
5 1     B           49.5  4.02 0.804
6 1     C           36.5 15.8  3.16 
> </pre>

これでグループ化されました。このデータでエラーバーの入った棒グラフを描いてみましょう。

グループ化された棒グラフでのエラーバー

position = “dodge”をするとこのような棒グラフができます。

ggplot(b, aes(x = Categories, y = mean, fill = group))+
  geom_bar(stat = "identity", width = 0.6, position = "dodge")

これにエラーバーを加えていきます。

ggplot(b, aes(x = Categories, y = mean, fill = group))+
  geom_bar(stat = "identity", width = 0.6, position = "dodge")+
  geom_errorbar(aes(ymin = mean - se, ymax = mean + se), 
                    position = "dodge", width = .1)

真ん中に寄ってしまいました!これでは使い物になりません。

position = position_dodge()で調整できます

ggplot(b, aes(x = Categories, y = mean, fill = group)) +
  geom_bar(stat = "identity", width = 0.6, position = "dodge") +
  geom_errorbar(aes(ymin = mean - se, ymax = mean + se),
                position = position_dodge(0.6), width = .1)

これでいい棒グラフができました!

グループ化された折れ線グラフでのエラーバー

折れ線グラフも同じようにできます!

ggplot(b, aes(x = Categories, y = mean, group = group, color = group)) +
  geom_line() +
  geom_point(size = 3) +
  geom_errorbar(aes(ymin = mean - se, ymax = mean + se),
                width = .1, color = "black")

見慣れないですよね?何がいけないんでしょうか?エラーバーが前面に出てしまっていることと、重なってしまっています!

まずエラーバーを後ろに持ってきます。

ggplot(b, aes(x = Categories, y = mean, group = group, color = group)) +
  geom_errorbar(aes(ymin = mean - se, ymax = mean + se),
                width = .1, color = "black") +
  geom_line() +
  geom_point(size = 3)

エラーバーが重なりは左右にずらすことで解消ができます。

さきほどのposition_dodgeを使います

ggplot(b, aes(x = Categories, y = mean, group = group, color = group)) +
  geom_errorbar(aes(ymin = mean - se, ymax = mean + se),
                width = .1, color = "black", position = position_dodge(.2)) +
  geom_line(position = position_dodge(.2)) +
  geom_point(size = 3, position = position_dodge(.2))

これで折れ線グラフのエラーバーを加えることができました!

コツを覚えてしまえば、とても簡単にできますよね!

お役に立ちましたら幸いです。