Prostsza piramida populacji w ggplot2

Chcę stworzyć piramidę populacji z ggplot2. To pytanie zostało zadane przed, ale uważam, że rozwiązanie musi być znacznie prostsze.

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)

Tworzy ten obraz. Moim zdaniem, jedynym krokiem brakuje tutaj do stworzenia piramidy populacji jest odwrócenie osi x pierwszego aspektu, tak, że idzie z 50 do 0, zachowując drugi nietknięty. Czy ktoś może pomóc?

Piramida populacji

 37
Author: Community, 2013-02-04

2 answers

Oto rozwiązanie bez fasetowania. Najpierw utwórz ramkę danych. Użyłem wartości od 1 do 20, aby upewnić się, że żadna z wartości nie jest ujemna (z piramidami populacji nie dostaniesz ujemnych liczników/wieku).

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

Następnie połączył dwa wywołania geom_bar() oddzielnie dla każdej z wartości g. Dla F liczniki są obliczane tak, jak są, ale dla M liczniki są mnożone przez -1, aby uzyskać pasek w przeciwnym kierunku. Następnie scale_y_continuous() jest używany do uzyskania ładnych wartości dla osi.

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

UPDATE

Jako że argument subset=. jest przestarzały w najnowszych wersjach ggplot2, ten sam wynik można uzyskać za pomocą funkcji 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()

Tutaj wpisz opis obrazka

 53
Author: Didzis Elferts,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-19 15:27:07

Ogólny kod gG

  1. unika niektórych majstrów z przerwami na etykiecie na osi poziomej
  2. unika subset lub potrzeby dodatkowych pakietów (np. plyr). Może to być szczególnie przydatne, jeśli chcesz stworzyć wiele piramid na wykresie fasetowym.
  3. używa geom_bar() tylko raz, co jest przydatne, jeśli chcesz facet.
  4. ma równe męskie i żeńskie osie poziome; limits = max(df0$Population) * c(-1,1), jak powszechnie stosowane przez demografów... Usuń wiersz w kodzie, jeśli nie wymagane.

Tworzenie danych...

set.seed(1)
df0 <- data.frame(Age = factor(rep(x = 1:10, times = 2)), 
                  Gender = rep(x = c("Female", "Male"), each = 10),
                  Population = sample(x = 1:100, size = 20))

head(df0)
#   Age Gender Population
# 1   1 Female         27
# 2   2 Female         37
# 3   3 Female         57
# 4   4 Female         89
# 5   5 Female         20
# 6   6 Female         86

Kod działki ...

library(ggplot2)
ggplot(data = df0, 
       mapping = aes(x = Age, fill = Gender, 
                     y = ifelse(test = Gender == "Male", 
                                yes = -Population, no = Population))) +
  geom_bar(stat = "identity") +
  scale_y_continuous(labels = abs, limits = max(df0$Population) * c(-1,1)) +
  labs(y = "Population") +
  coord_flip()

Tutaj wpisz opis obrazka

Uwaga, Jeśli Twoje dane są na poziomie indywidualnym, a nie podsumowane według grupy wiekowej i płci, to odpowiedź tutaj jest również dość uogólniona.

 19
Author: gjabel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-02 10:20:32