web-dev-qa-db-ja.com

ggplot2を使用して棒グラフに線を重ねるにはどうすればよいですか?

2つの異なるシリーズを含む棒グラフをプロットし、シリーズの1つのバーを非表示にし、代わりに、非表示のシリーズのバーがあった場所の上部に線(可能であれば滑らか)を通過させる方法を探しています(ヒストグラムに周波数多項式をオーバーレイする方法と似ています)。以下の例を試しましたが、2つの問題が発生しているようです。

まず、データをグループごとに要約(合計)する必要があります。次に、シリーズの1つ(df2)を1行に変換します。

df <- data.frame(grp=c("A","A","B","B","C","C"),val=c(1,1,2,2,3,3))  
df2 <- data.frame(grp=c("A","A","B","B","C","C"),val=c(1,4,3,5,1,2))  
ggplot(df, aes(x=grp, y=val)) +   
    geom_bar(stat="identity", alpha=0.75) +  
    geom_bar(data=df2, aes(x=grp, y=val), stat="identity", position="dodge")
11
user338714

サンプルデータは、使用している実際のデータを表していない可能性がありますが、_df2_に描画する線はありません。 x値とy値ごとに1つの値しかありません。 _df2_の修正バージョンで、線を作成するのに十分なデータポイントがあります。

_df <- data.frame(grp=c("A","A","B","B","C","C"),val=c(1,2,3,1,2,3))
df2 <- data.frame(grp=c("A","A","B","B","C","C"),val=c(1,4,3,5,0,2))

p <- ggplot(df, aes(x=grp, y=val)) 
p <- p + geom_bar(stat="identity", alpha=0.75) 

p + geom_line(data=df2, aes(x=grp, y=val), colour="blue")
_

または、上記のサンプルデータが正しい場合は、この情報をgeom_point(data = df2, aes(x = grp, y = val), colour = "red", size = 6)を使用して点としてプロットできます。あなたは明らかにあなたの好みに合わせて色とサイズを変えることができます。

編集:コメントに応えて

ヒストグラム上の周波数多項式のビジュアルがどのように見えるかは完全にはわかりません。 x値は相互に接続されているはずですか?次に、必要な行を参照し続けますが、コードにgeom_bar()が表示されますが、これは必要なものではないと思いますか?行が必要な場合は、geom_lines()を使用します。上記の2つの仮定が正しい場合は、次の方法でそれを行うことができます。

_ #First let's summarise df2 by group
 df3 <- ddply(df2, .(grp), summarise, total = sum(val))
>  df3
  grp total
1   A     5
2   B     8
3   C     3

#Second, let's plot df3 as a line while treating the grp variable as numeric

p <- ggplot(df, aes(x=grp, y=val))
p <- p + geom_bar(alpha=0.75, stat = "identity") 
p + geom_line(data=df3, aes(x=as.numeric(grp), y=total), colour = "red")
_
13
Chase

グループの合計はさまざまな方法で取得できます。それらの1つは

with(df, tapply(val, grp, sum))

簡単にするために、棒と線のデータを1つのデータセットに組み合わせることができます。

df_all <- data.frame(grp = factor(levels(df$grp)))
df_all$bar_heights <- with(df, tapply(val, grp, sum))
df_all$line_y <- with(df2, tapply(val, grp, sum))

棒グラフは、カテゴリカルX軸を使用します。線をオーバーレイするには、軸を数値に変換する必要があります。

ggplot(df_all) +
   geom_bar(aes(x = grp, weight = bar_heights)) +
   geom_line(aes(x = as.numeric(grp), y = line_y))

enter image description here

21
Richie Cotton