科研绘图系列:R语言分组柱状图三(Grouped Bar Chart)

在这里插入图片描述

介绍

分组柱状图(Grouped Bar Chart)是一种数据可视化图表,用于比较不同类别(分组)内各子类别(子组)的数值。在分组柱状图中,每个分组有一组并列的柱子,每个柱子代表一个子组的数值,不同的分组用不同的列来表示。

特点:

  • 并列柱子:每个分组内的柱子是并列的,便于在同一分组内比较不同子组。
  • 分组比较:可以直观地比较不同分组之间的数值大小。
  • 多变量展示:同时展示分组和子组两个层次的变量。

适合情况:

  1. 多类别比较:当你需要比较两个或多个类别(如性别、年龄组、地区等)内不同子类别的数据时。
  2. 层次化数据:数据具有层次结构,例如,首先按国家分组,然后在国家内部按城市或州进行分组。
  3. 展示相对差异:当需要展示不同子组在相同分组内的相对大小或比例时。
  4. 避免数据重叠:在某些情况下,使用堆叠柱状图可能导致底层数据难以解读,分组柱状图可以避免这个问题。
  5. 强调分组内比较:如果你更关注于分组内部的比较,而不是分组之间的比较。
  6. 有限的分组数量:当分组数量不是很多时,分组柱状图可以清晰地展示每个分组的数据,如果分组数量太多,图表可能会变得拥挤。
  7. 数据量适中:当每个分组内的子组数量适中,不会使图表过于复杂或难以解读。

加载R包

knitr::opts_chunk$set(echo = TRUE, message = FALSE, warning = FALSE)
library(tidyverse)
library(ggpubr)
library(plyr)
library(ggsignif)
library(ggprism)

# rm(list = ls())
options(stringsAsFactors = F)

# group & color
dose_names <- c("0.5", "1", "2")
dose_colors <- c("#0073C2FF", "#EFC000FF", "#CD534CFF")

supp_names <- c("OJ", "VC")
supp_colors <- c('#999999','#E69F00')

导入数据

data("ToothGrowth")

head(ToothGrowth)
lensuppdose
4.2VC0.5
11.5VC0.5
7.3VC0.5
5.8VC0.5
6.4VC0.5
10.0VC0.5

准备数据

  • 筛选画图数据
plotdata <- ToothGrowth |>
  dplyr::mutate(dose = factor(as.character(dose), levels = dose_names),
                supp = factor(supp, levels = supp_names)) |>
  dplyr::rename(Group = dose,
                Subgroup = supp,
                Index = len) |>
  dplyr::select(Group, Subgroup, Index)

head(plotdata)
GroupSubgroupIndex
0.5VC4.2
0.5VC11.5
0.5VC7.3
0.5VC5.8
0.5VC6.4
0.5VC10.0
  • 通过data_summary函数计算每个分组的mean & sd & se
data_summary <- function(data, varname, groupnames){
  
  summary_func <- function(x, col) {
    mean_value <- mean(x[[col]], na.rm = TRUE)
    sd_value <- sd(x[[col]], na.rm = TRUE)
    length_n <- length(x[[col]])

    # standard error= standard deviation/squareroot(n)
    se_value <- sd_value / sqrt(length_n)
    
    return(c(mean = mean_value, sd = sd_value, se = se_value))
  }  
  
  data_sum <- ddply(data, groupnames, .fun=summary_func, varname)
  colnames(data_sum)[which(colnames(data_sum) == "mean")] <- varname
  
  return(data_sum)
}

plotdata2 <- data_summary(
  data = plotdata,
  varname = "Index",
  groupnames = c("Group", "Subgroup"))

head(plotdata2)
GroupSubgroupIndexsdse
0.5OJ13.234.4597091.4102837
0.5VC7.982.7466340.8685620
1OJ22.703.9109531.2367520
1VC16.772.5153090.7954104
2OJ26.062.6550580.8396031
2VC26.144.7977311.5171757
  • 计算组间差异P值
df_p_val <- plotdata %>%
  rstatix::group_by(Group) %>%
  rstatix::t_test(Index ~ Subgroup) %>%
  rstatix::adjust_pvalue(p.col = "p", method = "bonferroni") %>%
  rstatix::add_significance(p.col = "p.adj") %>% 
  rstatix::add_xy_position(x = "Group", dodge = 0.8) %>% # important for positioning!
  dplyr::mutate(p.adj = round(p.adj, 3))
  
head(df_p_val)
Group.y.group1group2n1n2statisticdfpp.adj
0.5IndexOJVC10103.169732814.968750.006360.019
1IndexOJVC10104.032769615.357670.001040.003
2IndexOJVC1010-0.046136114.039820.964001.000

画图

分组柱状图展示不同分组的比较结果,以下是代码解释:

  1. ggplot(data = plotdata2, aes(x = Group, y = Index)): 初始化ggplot对象,使用plotdata2作为数据源,将Group映射到x轴,Index映射到y轴。
  2. geom_bar(aes(fill = Subgroup), stat = "identity", ...): 添加条形图层,使用aes(fill = Subgroup)Subgroup映射到条形的填充颜色,stat = "identity"表示条形的高度由数据中的Index确定,position_dodge()确保不同子组的条形在同一分组内并排显示。
  3. geom_errorbar(...): 添加误差条图层,显示数据的标准差范围,aes(color = Subgroup)Subgroup映射到误差条的颜色,position_dodge()调整误差条的位置以适应条形的宽度。
  4. ggprism::add_pvalue(...): 使用ggprism包的add_pvalue函数添加显著性p值标签,xminxmax定义了标签的位置,label定义了标签的格式。
  5. geom_point(...): 在条形图上添加点图层,使用plotdata数据集,点的位置由GroupIndex确定,shape映射到点的形状,position_jitterdodge添加抖动和偏移以避免点的重叠。
  6. labs(x = ""): 设置x轴标签,这里将其设置为空字符串。
  7. scale_y_continuous(...): 设置y轴的比例尺,guide = "prism_minor"指定y轴的次要刻度,minor_breaks设置次要刻度的间隔,limits设置y轴的范围,expand调整y轴的范围,留出一些空间。
  8. scale_fill_prism(), scale_color_prism(), scale_shape_prism(): 使用ggprism包提供的尺度函数来设置填充颜色、边框颜色和点形状。
  9. guides(color = "none", shape = "none"): 设置图例,这里将颜色和形状的图例设置为不显示。
  10. theme_prism(): 应用ggprism包的主题样式。
  11. theme(...): 自定义图形的主题样式,包括轴标题、轴文本的大小、颜色和字体,以及图例的位置。

pl_prism <- ggplot(data = plotdata2, aes(x = Group, y = Index)) +
  geom_bar(aes(fill = Subgroup), stat = "identity", 
           color = "white", position = position_dodge()) +
  geom_errorbar(aes(color = Subgroup,
                    ymin = Index - sd, ymax = Index + sd), 
                width = 0.2, position = position_dodge(width = 0.9),
                size = 1) +
  ggprism::add_pvalue(data = df_p_val, 
             xmin = "xmin", 
             xmax = "xmax",
             label = "p = {p.adj}",
             tip.length = 0) +
  geom_point(data = plotdata,
             aes(x = Group, y = Index, shape = Subgroup),
                 position = position_jitterdodge(jitter.width = 0.5,
                                                 dodge.width = 0.7),
             size = 2, show.legend = FALSE) +
  labs(x = "") + 
  scale_y_continuous(guide = "prism_minor", # prism_offset
                     minor_breaks = seq(0, 40, 2),
                     limits = c(0, 40),
                     expand = expansion(mult = c(0, 0.1))) +
  scale_fill_prism() +
  scale_color_prism() +
  scale_shape_prism() +  
  guides(color = "none", shape = "none") +
  theme_prism() +
  theme(axis.title = element_text(size = 12, color = "black", face = "bold"),
        axis.text = element_text(size = 10, color = "black"),
        text = element_text(size = 9, color = "black"),
        legend.position = c(0.15, 0.85))  

pl_prism

在这里插入图片描述

结果:不同水平下,内部分组的Index指数的差异结果。

如果大家有任何问题,欢迎留言沟通交流

<think>好的,我需要帮助用户在R语言中创建分组柱状图,尤其是使用ggplot2包。用户提到了示例代码和横坐标分组,所以我应该提供具体的步骤和代码示例。 首先,用户的问题是关于分组柱状图的,这通常指的是Grouped Bar Chart,其中不同的组别在同一个横坐标位置并列显示。在ggplot2中,可以通过设置position = position_dodge()来实现这一点。 接下来,我需要回忆ggplot2的基本语法。通常,我们会使用geom_bar()来创建柱状图,而分组的话需要将fill参数设置为分组的变量,同时调整position参数。此外,用户可能需要将数据整理成长格式(long format),这对于ggplot2来说更为方便,因为该包通常需要数据为长格式以便映射到图形属性。 例如,假设有一个数据框,其中包含分类变量Category,分组变量Group,以及数值变量Value。代码结构大致如下: ggplot(data, aes(x = Category, y = Value, fill = Group)) + geom_bar(stat = "identity", position = position_dodge()) 但需要确认用户的数据结构,可能需要使用tidyr的gather或pivot_longer函数来转换数据。例如,如果原始数据是宽格式,每个组别作为不同的列,那么需要先转换为长格式。 另外,用户提到的引用[4]是关于两侧柱状图,可能涉及双坐标轴,但用户的问题主要是分组柱状图,所以可能不需要涉及双坐标轴的复杂设置,但可以简要提及相关引用,供用户扩展参考。 需要确保示例代码正确,包括必要的库加载(如ggplot2和tidyr),以及数据构造步骤。同时,解释每个步骤的作用,帮助用户理解如何应用到自己的数据上。 最后,根据用户的要求生成相关问题,这些问题应该围绕分组柱状图的扩展应用、样式调整以及与其他图表类型的结合,同时利用提供的引用资源,如双坐标轴和柱状图的其他类型。</think>在R语言中使用ggplot2创建分组柱状图时,需明确分组变量与数值变量的映射关系,并通过调整`position`参数控制柱状图排列方式。以下是具体实现步骤及示例代码: --- ### **步骤说明** 1. **数据准备** 将数据整理为长格式(long format),每组数据对应一个分类变量和一个数值变量。例如: ```r library(tidyr) data <- data.frame( Category = c("A", "B", "C"), Group1 = c(20, 35, 30), Group2 = c(25, 30, 28) ) data_long <- pivot_longer(data, cols = -Category, names_to = "Group", values_to = "Value") ``` 2. **基础绘图** 使用`aes()`映射分类变量至`x`轴,数值变量至`y`轴,分组变量至`fill`颜色,并通过`geom_bar()`的`position = position_dodge()`实现并列分组: ```r library(ggplot2) ggplot(data_long, aes(x = Category, y = Value, fill = Group)) + geom_bar(stat = "identity", position = position_dodge()) + labs(title = "分组柱状图示例", x = "类别", y = "数值") + theme_minimal() ``` 3. **自定义样式** 可通过`scale_fill_manual()`修改颜色,或调整`width`参数控制柱宽: ```r ggplot(data_long, aes(x = Category, y = Value, fill = Group)) + geom_bar(stat = "identity", position = position_dodge(width = 0.8), width = 0.7) + scale_fill_manual(values = c("#1f77b4", "#ff7f0e")) + theme(axis.text.x = element_text(angle = 45, hjust = 1)) ``` --- ### **代码效果说明** - `position_dodge()`:确保不同组的柱子并列显示,而非堆叠。 - `stat = "identity"`:直接使用数据中的`y`值作为柱高(默认统计计数`count`)。 - `pivot_longer()`:将宽格式数据转换为长格式,便于ggplot2处理[^4]。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

生信学习者1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值