在生命科学研究中,组内和组间柱状图是展示实验数据最常用的可视化方式之一。它不仅能直观呈现Western Blot、RT-qPCR等实验的定量分析结果,更重要的是能清晰展示不同处理组之间的差异程度。通过组内重复和组间比较的统计分析,我们可以准确评估实验数据的可靠性和生物学显著性,为研究结论提供有力支撑。
library(ggplot2) # 主流绘图R包
library(dplyr) #数据处理R包
library(readxl) #读取excel数据R包
本次数据仍然使用以往的数据结构(实验组和对照组,每组3个生物学重复,第一周至第五周的小鼠体重测量数据),我们进行柱状图的统计分析。
## excel数据
data1 <- read_xlsx("Mmu data.xlsx")
## 当然有多个sheet时可以自定义sheet读取
data1 <- read_xlsx("Mmu data.xlsx",sheet = "Sheet1") # 注意Sheet中S的大写!!!
data1[1:12,]
## # A tibble: 12 × 4
## Group Order Time Value
## <chr> <dbl> <chr> <dbl>
## 1 Control 1 D0W 19.7
## 2 Control 2 D0W 20.1
## 3 Control 3 D0W 21.5
## 4 Test 1 D0W 20.7
## 5 Test 2 D0W 21.8
## 6 Test 3 D0W 21.9
## 7 Control 1 D1W 20.7
## 8 Control 2 D1W 21.5
## 9 Control 3 D1W 22.4
## 10 Test 1 D1W 21.3
## 11 Test 2 D1W 20.2
## 12 Test 3 D1W 19.6
为了让大家理解这个限定顺序的重要性,我们来演示一下:
我们把当前的数据中”D5W”分组修改为”C5W”.
## 数据转换一下
data2 <- data1
## 更换分组名称
data2[data2$Time=="D5W",]$Time <- "C5W"
table(data1$Time)
##
## D0W D1W D2W D3W D4W D5W
## 6 6 6 6 6 6
table(data2$Time)
##
## C5W D0W D1W D2W D3W D4W
## 6 6 6 6 6 6
此时,我们发现原来的第五周就跑到最前面去了,此时R语言会自己默认字母的顺序对图形进行了二次排序。此时,如果我们作图,会出现顺序颠倒的情况。
# 计算每组的均值和标准误
summary_data <- data2 %>%
group_by(Group, Time) %>%
summarise(mean_value = mean(Value),
se = sd(Value) / sqrt(n()),
.groups = 'drop')
# 创建分组柱状图
ggplot(summary_data, aes(x = Time, y = mean_value, fill = Group)) +
geom_bar(stat = "identity", position = position_dodge(width = 0.8), width = 0.7) +
geom_errorbar(aes(ymin = mean_value - se,
ymax = mean_value + se),
position = position_dodge(width = 0.8),
width = 0.25) +
# 自定义主题和颜色
scale_fill_manual(values = c("Control" = "gray", "Test" = "black")) +
theme_classic() +
# 添加标签
labs(title = "Group Comparison Over Time",
x = "Time Point",
y = "Value (Mean ± SE)") +
# 优化主题设置
theme(plot.title = element_text(size = 14, face = "bold", hjust = 0.5),
axis.title = element_text(size = 12),
axis.text = element_text(size = 10),
legend.title = element_text(size = 12),
legend.text = element_text(size = 10),
legend.position = "top")
### 第六步 输出统计值:
# 如果需要进行统计检验
# 执行双因素方差分析
aov_result <- aov(Value ~ Group * Time, data = data1)
summary(aov_result)
## Df Sum Sq Mean Sq F value Pr(>F)
## Group 1 111.27 111.27 183.20 9.95e-13 ***
## Time 5 65.90 13.18 21.70 3.44e-08 ***
## Group:Time 5 70.35 14.07 23.17 1.83e-08 ***
## Residuals 24 14.58 0.61
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# 如果需要进行组间比较
# 使用 TukeyHSD
tukey_result <- TukeyHSD(aov_result)
print(tukey_result)
## Tukey multiple comparisons of means
## 95% family-wise confidence level
##
## Fit: aov(formula = Value ~ Group * Time, data = data1)
##
## $Group
## diff lwr upr p adj
## Test-Control -3.516111 -4.05226 -2.979962 0
##
## $Time
## diff lwr upr p adj
## D1W-D0W -0.0300000 -1.4211940 1.361194 0.9999998
## D2W-D0W 1.6550000 0.2638060 3.046194 0.0133117
## D3W-D0W 1.7833333 0.3921393 3.174527 0.0067648
## D4W-D0W 2.7316667 1.3404727 4.122861 0.0000384
## D5W-D0W 3.7116667 2.3204727 5.102861 0.0000003
## D2W-D1W 1.6850000 0.2938060 3.076194 0.0113805
## D3W-D1W 1.8133333 0.4221393 3.204527 0.0057623
## D4W-D1W 2.7616667 1.3704727 4.152861 0.0000327
## D5W-D1W 3.7416667 2.3504727 5.132861 0.0000002
## D3W-D2W 0.1283333 -1.2628607 1.519527 0.9997097
## D4W-D2W 1.0766667 -0.3145273 2.467861 0.1983241
## D5W-D2W 2.0566667 0.6654727 3.447861 0.0015385
## D4W-D3W 0.9483333 -0.4428607 2.339527 0.3167581
## D5W-D3W 1.9283333 0.5371393 3.319527 0.0030983
## D5W-D4W 0.9800000 -0.4111940 2.371194 0.2839480
##
## $`Group:Time`
## diff lwr upr p adj
## Test:D0W-Control:D0W 1.060000e+00 -1.2343199 3.3543199 0.8664803
## Control:D1W-Control:D0W 1.076667e+00 -1.2176532 3.3709865 0.8550737
## Test:D1W-Control:D0W -7.666667e-02 -2.3709865 2.2176532 1.0000000
## Control:D2W-Control:D0W 3.640000e+00 1.3456801 5.9343199 0.0003454
## Test:D2W-Control:D0W 7.300000e-01 -1.5643199 3.0243199 0.9885072
## Control:D3W-Control:D0W 4.916667e+00 2.6223468 7.2109865 0.0000033
## Test:D3W-Control:D0W -2.900000e-01 -2.5843199 2.0043199 0.9999980
## Control:D4W-Control:D0W 6.523333e+00 4.2290135 8.8176532 0.0000000
## Test:D4W-Control:D0W 3.552714e-15 -2.2943199 2.2943199 1.0000000
## Control:D5W-Control:D0W 7.423333e+00 5.1290135 9.7176532 0.0000000
## Test:D5W-Control:D0W 1.060000e+00 -1.2343199 3.3543199 0.8664803
## Control:D1W-Test:D0W 1.666667e-02 -2.2776532 2.3109865 1.0000000
## Test:D1W-Test:D0W -1.136667e+00 -3.4309865 1.1576532 0.8100076
## Control:D2W-Test:D0W 2.580000e+00 0.2856801 4.8743199 0.0183862
## Test:D2W-Test:D0W -3.300000e-01 -2.6243199 1.9643199 0.9999923
## Control:D3W-Test:D0W 3.856667e+00 1.5623468 6.1509865 0.0001527
## Test:D3W-Test:D0W -1.350000e+00 -3.6443199 0.9443199 0.6138559
## Control:D4W-Test:D0W 5.463333e+00 3.1690135 7.7576532 0.0000005
## Test:D4W-Test:D0W -1.060000e+00 -3.3543199 1.2343199 0.8664803
## Control:D5W-Test:D0W 6.363333e+00 4.0690135 8.6576532 0.0000000
## Test:D5W-Test:D0W -3.552714e-15 -2.2943199 2.2943199 1.0000000
## Test:D1W-Control:D1W -1.153333e+00 -3.4476532 1.1409865 0.7964601
## Control:D2W-Control:D1W 2.563333e+00 0.2690135 4.8576532 0.0195219
## Test:D2W-Control:D1W -3.466667e-01 -2.6409865 1.9476532 0.9999873
## Control:D3W-Control:D1W 3.840000e+00 1.5456801 6.1343199 0.0001626
## Test:D3W-Control:D1W -1.366667e+00 -3.6609865 0.9276532 0.5973621
## Control:D4W-Control:D1W 5.446667e+00 3.1523468 7.7409865 0.0000005
## Test:D4W-Control:D1W -1.076667e+00 -3.3709865 1.2176532 0.8550737
## Control:D5W-Control:D1W 6.346667e+00 4.0523468 8.6409865 0.0000000
## Test:D5W-Control:D1W -1.666667e-02 -2.3109865 2.2776532 1.0000000
## Control:D2W-Test:D1W 3.716667e+00 1.4223468 6.0109865 0.0002586
## Test:D2W-Test:D1W 8.066667e-01 -1.4876532 3.1009865 0.9758622
## Control:D3W-Test:D1W 4.993333e+00 2.6990135 7.2876532 0.0000025
## Test:D3W-Test:D1W -2.133333e-01 -2.5076532 2.0809865 0.9999999
## Control:D4W-Test:D1W 6.600000e+00 4.3056801 8.8943199 0.0000000
## Test:D4W-Test:D1W 7.666667e-02 -2.2176532 2.3709865 1.0000000
## Control:D5W-Test:D1W 7.500000e+00 5.2056801 9.7943199 0.0000000
## Test:D5W-Test:D1W 1.136667e+00 -1.1576532 3.4309865 0.8100076
## Test:D2W-Control:D2W -2.910000e+00 -5.2043199 -0.6156801 0.0054620
## Control:D3W-Control:D2W 1.276667e+00 -1.0176532 3.5709865 0.6854679
## Test:D3W-Control:D2W -3.930000e+00 -6.2243199 -1.6356801 0.0001161
## Control:D4W-Control:D2W 2.883333e+00 0.5890135 5.1776532 0.0060339
## Test:D4W-Control:D2W -3.640000e+00 -5.9343199 -1.3456801 0.0003454
## Control:D5W-Control:D2W 3.783333e+00 1.4890135 6.0776532 0.0002012
## Test:D5W-Control:D2W -2.580000e+00 -4.8743199 -0.2856801 0.0183862
## Control:D3W-Test:D2W 4.186667e+00 1.8923468 6.4809865 0.0000448
## Test:D3W-Test:D2W -1.020000e+00 -3.3143199 1.2743199 0.8917475
## Control:D4W-Test:D2W 5.793333e+00 3.4990135 8.0876532 0.0000002
## Test:D4W-Test:D2W -7.300000e-01 -3.0243199 1.5643199 0.9885072
## Control:D5W-Test:D2W 6.693333e+00 4.3990135 8.9876532 0.0000000
## Test:D5W-Test:D2W 3.300000e-01 -1.9643199 2.6243199 0.9999923
## Test:D3W-Control:D3W -5.206667e+00 -7.5009865 -2.9123468 0.0000012
## Control:D4W-Control:D3W 1.606667e+00 -0.6876532 3.9009865 0.3713294
## Test:D4W-Control:D3W -4.916667e+00 -7.2109865 -2.6223468 0.0000033
## Control:D5W-Control:D3W 2.506667e+00 0.2123468 4.8009865 0.0239040
## Test:D5W-Control:D3W -3.856667e+00 -6.1509865 -1.5623468 0.0001527
## Control:D4W-Test:D3W 6.813333e+00 4.5190135 9.1076532 0.0000000
## Test:D4W-Test:D3W 2.900000e-01 -2.0043199 2.5843199 0.9999980
## Control:D5W-Test:D3W 7.713333e+00 5.4190135 10.0076532 0.0000000
## Test:D5W-Test:D3W 1.350000e+00 -0.9443199 3.6443199 0.6138559
## Test:D4W-Control:D4W -6.523333e+00 -8.8176532 -4.2290135 0.0000000
## Control:D5W-Control:D4W 9.000000e-01 -1.3943199 3.1943199 0.9491313
## Test:D5W-Control:D4W -5.463333e+00 -7.7576532 -3.1690135 0.0000005
## Control:D5W-Test:D4W 7.423333e+00 5.1290135 9.7176532 0.0000000
## Test:D5W-Test:D4W 1.060000e+00 -1.2343199 3.3543199 0.8664803
## Test:D5W-Control:D5W -6.363333e+00 -8.6576532 -4.0690135 0.0000000
我们限定一下顺序:
# 设置Week的顺序
summary_data$Time <- factor(summary_data$Time,
levels = c("D0W", "D1W", "D2W", "D3W", "D4W","C5W"))
重新作图:
# 创建分组柱状图
ggplot(summary_data, aes(x = Time, y = mean_value, fill = Group)) +
geom_bar(stat = "identity", position = position_dodge(width = 0.8), width = 0.7) +
geom_errorbar(aes(ymin = mean_value - se,
ymax = mean_value + se),
position = position_dodge(width = 0.8),
width = 0.25) +
# 自定义主题和颜色
scale_fill_manual(values = c("Control" = "gray", "Test" = "black")) +
theme_classic() +
# 添加标签
labs(title = "Group Comparison Over Time",
x = "Time Point",
y = "Value (Mean ± SE)") +
# 优化主题设置
theme(plot.title = element_text(size = 14, face = "bold", hjust = 0.5),
axis.title = element_text(size = 12),
axis.text = element_text(size = 10),
legend.title = element_text(size = 12),
legend.text = element_text(size = 10),
legend.position = "top")
## 也可以添加趋势线,更加突出沿着时间节点的趋势变化: # 创建分组柱状图
ggplot(summary_data, aes(x = Time, y = mean_value, fill = Group, group = Group)) +
# 柱状图层
geom_bar(stat = "identity", position = position_dodge(width = 0.8), width = 0.7) +
# 误差线层
geom_errorbar(aes(ymin = mean_value - se,
ymax = mean_value + se),
position = position_dodge(width = 0.8),
width = 0.25) +
# 添加虚线趋势线
geom_line(aes(color = Group),
position = position_dodge(width = 0.8),
linetype = "dashed",
size = 0.8) +
# 自定义主题和颜色
scale_fill_manual(values = c("Control" = "gray", "Test" = "black")) +
scale_color_manual(values = c("Control" = "gray", "Test" = "black")) +
theme_classic() +
# 添加标签
labs(title = "Group Comparison Over Time",
x = "Time Point",
y = "Value (Mean ± SE)") +
# 优化主题设置
theme(plot.title = element_text(size = 14,
face = "bold", hjust = 0.5),
axis.title = element_text(size = 12),
axis.text = element_text(size = 10),
legend.title = element_text(size = 12),
legend.text = element_text(size = 10),
legend.position = "top")