如何使用interaction()在ggplot中创建两个子组的图表(多个图表的组合)

4

我正在尝试创建两个子组的图表,就像下面的图片一样(ggplot2 multiple sub groups of a bar chart)。但是,我想要为一组图表进行此操作。

enter image description here

当我尝试这样做时,我的变量“growth”和“year”被合并在一起,而不是像“灌溉/干旱”和“品种1 / 品种2”的示例中那样清晰地分开分类。
我在编码中遇到了麻烦,想让我的变量“year”像“Irrigated / Dry”一样,变量“growth”像“Variety1 / Variety2”一样。目前,图表的显示如下:

enter image description here

这是我的代码:

library(ggplot2)

#Creates the data

d <- expand.grid(c(.3, .8), c(.3, 0.8), c(0, 0.5), c(1, 2), c("Oregon"," California"), c("2010","2011"))
colnames(d) <- c("gamma1", "gamma2", "growth",  "store", "state", "year")
d$sells <- rnorm(64)

d$gamma_plot <- as.factor(paste(d$gamma1, d$gamma2, sep = "_"))
d$store <- as.factor(d$store)

d$growth <- factor(d$growth)
d$gamma_plot = factor(d$gamma_plot,
                              labels=c(expression(paste(gamma[1],"=", gamma[2]," = 0.3")),
                                       expression(paste(gamma[1], " = 0.3 ", gamma[2], " = 0.8")),
                                       expression(paste(gamma[1], " = 0.8 ", gamma[2], " = 0.3")),
                                       expression(paste(gamma[1],"=", gamma[2]," = 0.8"))
                              )
)

d$store = factor(d$store,
                          labels = c(expression(paste(store[1], " = 1")),
                                     expression(paste(store[2], " = 2"))
                          )
)

#Creates the plot
p = ggplot(data=d, aes(x=interaction(year, growth), y=sells, fill=state)) + 
  geom_col(position="dodge") +
  theme_bw() +
  facet_grid(store ~ gamma_plot, labeller = label_parsed) + 
  theme(legend.title = element_blank(), legend.position="bottom",
        panel.grid.major = element_blank(), 
        legend.key.size = unit(0.10, "cm"),
        legend.key.width = unit(0.15,"cm")) + 
  guides(fill = guide_legend(nrow = 1)) +
  labs(x=expression(growth), y = "Sells")

编辑:

对于我的问题所给出的两个解决方案非常好,我非常感谢。 我已经决定稍微修改一下情节,让gamma_plot和growth之间有交互。我无法让R理解gamma_plot是一个表达式。有什么想法吗?

enter image description here

#Creates the plot using teunbrand's code :)

ggplot(data=d, aes(x=interaction(growth, gamma_plot, sep = "&"), y=sells, fill=year)) + 
  geom_col(position="dodge") +
  theme_bw() +
  facet_grid(store ~ state, labeller = label_parsed) + 
  theme(legend.title = element_blank(), legend.position="bottom",
        panel.grid.major = element_blank(), 
        legend.key.size = unit(0.10, "cm"),
        legend.key.width = unit(0.15,"cm"),
        axis.text.x = element_text(margin = margin(2,2,2,2))) +
  scale_x_discrete(guide = guide_axis_nested(delim = "&")) +
  guides(fill = guide_legend(nrow = 1)) +
  labs(x=expression(growth), y = "Sells")

1
你的代码是否缺少 data_plot - Peter
非常抱歉,请修复它。 - Miranda
是的,我尝试使用那篇帖子中的代码,但与绘图的组合对我没有起作用。 - Miranda
2个回答

2
这个选项怎么样?


library(ggplot2)


ggplot(data=d, aes(x = interaction(year, growth), y=sells, fill = state)) + 
  geom_col(position="dodge") +
  scale_x_discrete(labels = unique(interaction(d$year, factor(d$growth), sep = "\n")))+
  theme_bw() +
  facet_grid(store ~ gamma_plot, labeller = label_parsed) + 
  theme(legend.title = element_blank(), legend.position="bottom",
        panel.grid.major = element_blank(), 
        legend.key.size = unit(0.10, "cm"),
        legend.key.width = unit(0.15,"cm")) + 
  guides(fill = guide_legend(nrow = 1)) +
  labs(x = expression(Year~growth), y = "Sells")

reprex package (v0.3.0) 于2020年7月10日创建


2
据我所知,ggplot2中没有轴层次结构。通常情况下,人们会使用 facets 将 year 和 growth 分开,但看起来您已经在使用 facets 分离其他内容了。
以下是在这种情况下如何使用 facets 的示例:
ggplot(data=d, aes(x=interaction(growth), y=sells, fill=state)) + 
  geom_col(position="dodge") +
  theme_bw() +
  facet_grid(store ~ gamma_plot + year, labeller = label_parsed, switch = "x") + 
  theme(legend.title = element_blank(), legend.position="bottom",
        panel.grid.major = element_blank(), 
        strip.placement = "outside",
        legend.key.size = unit(0.10, "cm"),
        legend.key.width = unit(0.15,"cm")) + 
  guides(fill = guide_legend(nrow = 1)) +
  labs(x=expression(growth), y = "Sells")

在此输入图片描述

鉴于上述方案并不是一个很好的选择,我建议寻找提供所需功能的扩展包。如果你能允许我这么大胆,我写的一个github包中有一个函数,可以以嵌套方式格式化坐标轴。以下是示例:

library(ggh4x)
ggplot(data=d, aes(x=interaction(growth, year, sep = "&"), y=sells, fill=state)) + 
  geom_col(position="dodge") +
  theme_bw() +
  facet_grid(store ~ gamma_plot, labeller = label_parsed) + 
  theme(legend.title = element_blank(), legend.position="bottom",
        panel.grid.major = element_blank(), 
        legend.key.size = unit(0.10, "cm"),
        legend.key.width = unit(0.15,"cm"),
        axis.text.x = element_text(margin = margin(2,2,2,2))) +
  scale_x_discrete(guide = guide_axis_nested(delim = "&")) +
  guides(fill = guide_legend(nrow = 1)) +
  labs(x=expression(growth), y = "Sells")

在此输入图片描述

编辑: 关于年份之间的间距的后续问题,我想不出一个优雅的解决方案,但以下方法可以完成任务。它将离散轴转换为连续轴。

# Precalculate interaction
d$interaction <- interaction(d$growth, d$year, sep = "&")
nudge <- 1 # How much you want to nudge

# Use ifelse to nudge position and use factor as integer
ggplot(data=d, aes(x=ifelse(as.numeric(interaction) > 2, 
                            as.numeric(interaction) + nudge, 
                            as.numeric(interaction)),
                   y=sells, fill=state)) + 
  geom_col(position="dodge") +
  theme_bw() +
  facet_grid(store ~ gamma_plot, labeller = label_parsed) + 
  theme(legend.title = element_blank(), legend.position="bottom",
        panel.grid.major = element_blank(), 
        legend.key.size = unit(0.10, "cm"),
        legend.key.width = unit(0.15,"cm"),
        axis.text.x = element_text(margin = margin(2,2,2,2))) +
  # Using a continuous axis here
  scale_x_continuous(breaks = c(1,2,3 + nudge, 4 + nudge),
                     labels = levels(d$interaction),
                     guide = guide_axis_nested(delim = "&")) +
  guides(fill = guide_legend(nrow = 1)) +
  labs(x=expression(growth), y = "Sells")

enter image description here


太好了,完美解决了!只有一个后续问题:是否可以在每个图中的年份之间添加更多的水平间距/填充?这样2010年和2011年的条形图就更容易区分了吗? - Miranda
1
是的,但是我想不出一个优雅的解决方案。请参见上面的编辑。 - teunbrand
解决方案非常好。我决定更改情节的组织,现在我遇到了一个问题,就是让ggplot2理解其中一个标签是表达式。感谢您的所有帮助! - Miranda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接