ggplot中的人口金字塔

时间:2018-11-07 16:46:19

标签: r ggplot2

我已经阅读了相关的文章(Simpler population pyramid in ggplot2),但是设置略有不同,导致金字塔混乱。

制作测试数据框:

test <- data.frame(cbind(c(replicate(3,"population 1"), replicate(3,"population 2")),c("top","middle","bottom","top","middle","bottom"),c(70,25,5,82,13,3)))

修正因子顺序:

levels(test$X3)
[1] "13" "25" "3"  "5"  "70" "82"

test$X3 <- factor(test$X3, levels=c(70,25,5,82,13,3))

levels(test$X2)
[1] "Bottom" "Middle" "Top" 

test$X2 <- factor(test$X2, levels=c("Top","Middle","Bottom"))

尝试

library(ggplot2)
ggplot(data = test,  aes(x=X3, y=X2)) +
  geom_bar(data = subset(test, X1=="population 1") , stat = "identity")+
  coord_flip()

但这是错误的,我不知道为什么。顶部/中部/底部因素是相反的顺序:

Top, 70% shows as the smallest bar; Middle shows as middle; Bottom, 5% shows as the largest bar

最终我要进行以下操作:

funnel with population 1 and population 2

编辑-我通过在相反的方向上显式地(下面)强加因子重排来固定单侧块,但我仍然不明白为什么ggplot无法识别如何绘制数据,因此欢迎任何解释

# THIS PLOTS ONE SIDE OF THE PYRAMID CORRECTLY
testdf <- data.frame(cbind(c(replicate(3,"population 1"), replicate(3,"population 2")),c("Top","Middle","Bottom","Top","Middle","Bottom"),c(70,25,5,82,13,3)))
testdf$X3 <- factor(testdf$X3, levels=c(5,25,70,3,13,82))
testdf$X2 <- factor(testdf$X2, levels=c("Bottom","Middle","Top"))
g <- ggplot(data = testdf,  aes(x=X3, y=X2))
g <- g + geom_bar(data = subset(testdf, X1=="population 1") , stat = "identity")
g + coord_flip()

3 个答案:

答案 0 :(得分:3)

这应该让您入门

test <- data.frame(
    X1 = c(replicate(3, "population 1"), replicate(3, "population 2")),
    X2 = c("top", "middle", "bottom", "top", "middle", "bottom"),
    X3 = c(70, 25, 5, 82, 13, 3)
)

test$X2 <- factor(test$X2, levels = c("bottom", "middle", "top"))

ggplot(data = test,  
       aes(x = X2, y = ifelse(X1 == "population 1", -X3, X3), fill = X1)) +
  geom_bar(stat = "identity") +
  coord_flip()

enter image description here

答案 1 :(得分:1)

这对我有用:

test <-
  data.frame(
    X1 = c(replicate(3, "population 1"), replicate(3, "population 2")),
    X2 = c("top", "middle", "bottom", "top", "middle", "bottom"),
    X3 = c(70, 25, 5, 82, 13, 3)
  )
test$X3 <- with(test, ifelse(X1 == "population 1", -X3, X3))

library(ggplot2)
ggplot(data = test,  aes(x = X2, y = X3, fill = X1)) +
  geom_col() +
  coord_flip() +
  scale_y_continuous(labels = abs)

enter image description here

答案 2 :(得分:0)

使用上面的帮助和来自https://rpubs.com/walkerke/pyramids_ggplot2的指针后,将其作为解决方案发布为答案:

制作数据框testdf。将响应testdf$percent保留为数字而非因数:

testdf <- data.frame(population = c(replicate(3,"population 1"), replicate(3,"population 2")), 
                     layer =  c("Top","Middle","Bottom","Top","Middle","Bottom"), 
                     layernum = as.numeric(c(3,2,1,3,2,1)),
                     percent = as.numeric(c(70,25,5,82,13,3)))
testdf$percent <- ifelse(testdf$population == "population 1", -testdf$percent, testdf$percent)

使用ggplot2

library(ggplot2)

绘制情节:

g <- ggplot(data = testdf,  aes(x=layer, y=percent, fill=population))
g <- g + geom_bar(data = subset(testdf, population=="population 1") , stat = "identity")
g <- g + geom_bar(data = subset(testdf, population=="population 2") , stat = "identity")

g <- g + scale_y_continuous(breaks = seq(-100, 100, 25), 
                     labels = paste0(as.character(c(seq(100, 0, -25), seq(25, 100, 25))), "m"))
g+coord_flip()