ggplot2中的水平滑动条形图

时间:2013-07-11 20:37:01

标签: r ggplot2

我创建了我需要的情节,但我想滑动条形图,使中心中性类别对每个子情节均匀地跨越零(x = 0)。有任何想法吗?也许我在这里没有使用正确的几何构造?

library(ggplot2)
survey_data <- data.frame(gender=rep(c("Unreported","Female","Male"),7),
                      feel_job=c(1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7),
                      Freq=c(0, 0, 0, 1, 3, 5, 0, 4, 4, 0, 7, 15, 3, 28, 35, 3, 35, 80, 1, 52, 108))
p <- ggplot(survey_data, aes(gender)) + 
  geom_bar(aes(y = Freq, fill = factor(feel_job)), stat = "identity") +
  coord_flip()
p

显然,这些类型的情节在某些圈子中也被称为“Diverging Stacked Bar Charts”。

2 个答案:

答案 0 :(得分:2)

我猜这是因为你在因子feel_job中有7个等级,你希望等级= 4超过y轴。从http://learnr.wordpress.com/2009/09/24/ggplot2-back-to-back-bar-charts/的例子来看,我认为可能有办法作弊。

关键似乎不是依靠ggplot来做所有事情。相反,您必须创建统计数据然后摆弄它们。我决定尝试使用geom_rect()而不是香草geom_bar(),这意味着我需要为xmin, xmax, yminymax提供每个条形值。这个答案的其余部分将说明如何做到这一点。

# save the data we were given
a.survey.data <-survey_data

# going to plot this as rectangles
a.survey.data$xmin[a.survey.data$feel_job < 4] = -a.survey.data$Freq[a.survey.data$feel_job < 4]
a.survey.data$xmin[a.survey.data$feel_job == 4] = -a.survey.data$Freq[a.survey.data$feel_job == 4]/2
a.survey.data$xmin[a.survey.data$feel_job > 4] = 0

a.survey.data$xmax[a.survey.data$feel_job < 4] = 0
a.survey.data$xmax[a.survey.data$feel_job == 4] = a.survey.data$Freq[a.survey.data$feel_job == 4]/2
a.survey.data$xmax[a.survey.data$feel_job > 4] = a.survey.data$Freq[a.survey.data$feel_job > 4]

# assign values to ymin and ymax based on gender and 
y.base <- NA
y.base[a.survey.data$gender == "Female"] = 1
y.base[a.survey.data$gender == "Male"] = 2
y.base[a.survey.data$gender == "Unreported"] = 3

a.survey.data$ymin <- y.base + (a.survey.data$feel_job-4)*0.1 - 0.05
a.survey.data$ymax <- y.base + (a.survey.data$feel_job-4)*0.1 + 0.05

# set the labels
a.survey.data$feel_job.cut <- factor(cut(a.survey.data$feel_job,
                                         breaks = c(0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5),
                                         labels = c("1",
                                                    "2",
                                                    "3",
                                                    "neutral",
                                                    "5",
                                                    "6",
                                                    "7"),
                                         ordered = TRUE))

p2 <- ggplot(data = a.survey.data,
             aes(xmax = xmax,
                 xmin = xmin,
                 ymax = ymax,
                 ymin = ymin)) +
  geom_rect(aes(fill = feel_job.cut)) +  
  scale_y_continuous(limits = c(0.5,3.5),
                     breaks=c(1,2,3), 
                     labels=c("Female","Male","Unreported"))
print(p2)

然后我们开始...... enter image description here

答案 1 :(得分:0)

您可以使用likert库中的HH函数执行此操作:

library(HH)
survey_data <- data.frame(gender=rep(c("Unreported","Female","Male"),7),
                  feel_job=c(1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7),
                  Freq=c(0, 0, 0, 1, 3, 5, 0, 4, 4, 0, 7, 15, 3, 28, 35, 3, 35, 80, 1, 52, 108))
likert(Freq ~ gender + feel_job, survey_data)

我不确定这是否正是你想要的,但我认为这样(或类似的东西)应该起作用。