47

ggplot2で人口ピラミッドを作成したいと思います。この質問は以前に尋ねられましたが、解決策ははるかに単純でなければならないと思います。

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軸を反転することです。つまり、2番目のファセットはそのままにして、50から0になります。誰か助けてもらえますか?

人口ピラミッド

4

3 に答える 3

61

これがファセットのない解決策です。まず、データフレームを作成します。1から20までの値を使用して、どの値も負にならないようにしました(人口ピラミッドでは、負のカウント/年齢を取得しません)。

test <- data.frame(v=sample(1:20,1000,replace=T), g=c('M','F'))

次に、値geom_bar()ごとに2つの呼び出しを個別に組み合わせ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()

ここに画像の説明を入力してください

于 2013-02-08T09:09:11.077 に答える
43

人口ピラミッドの一般的なggplotコードテンプレート(下記)

  1. より良いデフォルトを持ち、の必要性を回避するのではgeom_col()なく、を使用するgeom_bar()statcoord_flip()
  2. labels = absスケール機能で使用することにより、手動でラベル区切りを設定することを回避します。
  3. scale_x_symmetric()レモンパッケージで使用して、男女間の比較を容易にするために、男性と女性の水平軸(およびラベル)が等しい。
  4. データをサブセット化する必要がないように、1つのgeomのみを使用します。これは、ファセットプロットに複数のピラミッドを作成する場合に便利です。

データの作成...

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)
library(lemon)

ggplot(data = d, 
       mapping = aes(x = ifelse(test = sex == "Male", yes = -pop, no = pop), 
                     y = age, fill = sex)) +
  geom_col() +
  scale_x_symmetric(labels = abs) +
  labs(x = "Population")

ここに画像の説明を入力してください

于 2016-04-22T22:41:22.173 に答える
1

@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

人口ピラミッド

于 2019-10-09T09:10:28.350 に答える