Ggplot2で人口ピラミッドを作成したいと思います。この質問は尋ねられた before ですが、解決策ははるかに単純である必要があると思います。
test <- (data.frame(v=rnorm(1000), g=c('M','F')))
require(ggplot2)
ggplot(data=test, aes(x=v)) +
geom_histogram() +
coord_flip() +
facet_grid(. ~ g)
この画像を生成します。私の意見では、人口ピラミッドを作成するためにここで欠落している唯一の手順は、最初のファセットのx軸を反転することです。誰か助けてもらえますか?
これは、ファセットなしのソリューションです。まず、データフレームを作成します。 1から20までの値を使用して、負の値がないことを確認しました(人口ピラミッドでは、負の数/年齢を取得しません)。
_test <- data.frame(v=sample(1:20,1000,replace=T), g=c('M','F'))
_
次に、2つのgeom_bar()
呼び出しをg
値ごとに個別に結合しました。 F
の場合、カウントはそのまま計算されますが、M
の場合、カウントは-1で乗算され、反対方向のバーが取得されます。次に、scale_y_continuous()
を使用して軸のきれいな値を取得します。
_require(ggplot2)
require(plyr)
ggplot(data=test,aes(x=as.factor(v),fill=g)) +
geom_bar(subset=.(g=="F")) +
geom_bar(subset=.(g=="M"),aes(y=..count..*(-1))) +
scale_y_continuous(breaks=seq(-40,40,10),labels=abs(seq(-40,40,10))) +
coord_flip()
_
引数_subset=.
_は最新の_ggplot2
_バージョンでは非推奨であるため、関数subset()
を使用しても同じ結果を得ることができます。
_ggplot(data=test,aes(x=as.factor(v),fill=g)) +
geom_bar(data=subset(test,g=="F")) +
geom_bar(data=subset(test,g=="M"),aes(y=..count..*(-1))) +
scale_y_continuous(breaks=seq(-40,40,10),labels=abs(seq(-40,40,10))) +
coord_flip()
_
一般的なピラミッドコード
geom_*()
を1つだけ使用します。これは、ファセットプロットで複数のピラミッドを作成する場合に特に便利です。stat
を持つgeom_col()
ではなくgeom_bar()
を使用しますlimits = max(d$pop) * c(-1,1)
を使用すると、x軸の性別ラベルと等しいラベルを簡単に比較できます。データを作成しています...
set.seed(100)
a <- seq(from = 0, to = 90, by = 10)
d <- data.frame(age = paste(a, a + 10, sep = "-"),
sex = rep(x = c("Female", "Male"), each = 10),
pop = sample(x = 1:100, size = 20))
head(d)
# age sex pop
# 1 0-10 Female 74
# 2 10-20 Female 89
# 3 20-30 Female 78
# 4 30-40 Female 23
# 5 40-50 Female 86
# 6 50-60 Female 70
プロットコード...
library(ggplot2)
ggplot(data = d,
mapping = aes(x = age, y = ifelse(test = sex == "Male", yes = -pop, no = pop),
fill = sex)) +
geom_col() +
coord_flip() +
scale_y_continuous(labels = abs, limits = max(d$pop) * c(-1,1)) +
labs(y = "Population")
データが年齢別の性別グループごとに要約されているのではなく個人レベルである場合は、答え here もかなり一般的です。
@gjabelの投稿を拡張して、ここでもggplot2を使用した、よりクリーンなポピュレーションピラミッドを示します。
popPy1 <- ggplot(data = venDemo,
mapping = aes(
x = AgeName,
y = ifelse(test = sex == "M", yes = -Percent, no = Percent),
fill = Sex2,
label=paste(round(Percent*100, 0), "%", sep="")
)) +
geom_bar(stat = "identity") +
#geom_text( aes(label = TotalCount, TotalCount = TotalCount + 0.05)) +
geom_text(hjust=ifelse(test = venDemo$sex == "M", yes = 1.1, no = -0.1), size=6, colour="#505050") +
# scale_y_continuous(limits=c(0,max(appArr$Count)*1.7)) +
# The 1.1 at the end is a buffer so there is space for the labels on each side
scale_y_continuous(labels = abs, limits = max(venDemo$Percent) * c(-1,1) * 1.1) +
# Custom colours
scale_fill_manual(values=as.vector(c("#d23f67","#505050"))) +
# Remove the axis labels and the fill label from the legend - these are unnecessary for a Population Pyramid
labs(
x = "",
y = "",
fill="",
family=fontsForCharts
) +
theme_minimal(base_family=fontsForCharts, base_size=20) +
coord_flip() +
# Remove the grid and the scale
theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.text.x=element_blank(),
axis.text.y=element_text(family=fontsForCharts, size=20),
strip.text.x=element_text(family=fontsForCharts, size=24),
legend.position="bottom",
legend.text=element_text(size=20)
)
popPy1