如何设置有序Labels为X轴并以Treatments为图例绘制产量图?
问题描述
我需要分析以下农业产量数据并绘制统计图:
Labels Treatments Reps Yield T1 No fertilizer 1 8 T2 Ferti 1 1 12 T3 Ferti 2 1 14 T4 Ferti 3 1 16 T5 Ferti 4 1 18 T6 Ferti 5 1 16 T7 Ferti 6 1 24 T8 Ferti 7 1 22 T9 Ferti 8 1 26 T10 Ferti 9 1 30 T11 Ferti 10 1 32 T1 No fertilizer 2 8.2 T2 Ferti 1 2 12.8 T3 Ferti 2 2 13.8 T4 Ferti 3 2 16.6 T5 Ferti 4 2 18 T6 Ferti 5 2 16.6 T7 Ferti 6 2 25.2 T8 Ferti 7 2 22.5 T9 Ferti 8 2 26.4 T10 Ferti 9 2 31 T11 Ferti 10 2 33.2 T1 No fertilizer 3 7.8 T2 Ferti 1 3 12.4 T3 Ferti 2 3 14.1 T4 Ferti 3 3 16.2 T5 Ferti 4 3 18.8 T6 Ferti 5 3 16.9 T7 Ferti 6 3 26.4 T8 Ferti 7 3 22.5 T9 Ferti 8 3 27 T10 Ferti 9 3 32.3 T11 Ferti 10 3 34.5
需求:
- 执行
Yield ~ Labels的ANOVA分析 - 绘制统计图时X轴按T1、T2……T11的顺序排列
- 以
Treatments列作为图例(即T1对应"No fertilizer",T2对应"Ferti 1"等)
遇到的问题:仅用Labels和Yield绘图时X轴顺序正确,但添加Treatments作为图例后X轴顺序混乱。
已尝试的R代码:
library(readxl) library(multcompView) library(dplyr) library(ggplot2) my_data <- read_excel(choose.files(), sheet = "Yield") # 将Labels和Treatments列转为因子 my_data <- read_excel(file.choose(), sheet = 1) my_data <- my_data |> mutate(Labels = factor(Labels, labels = c("T1", "T2", "T3", "T4", "T5", "T6", "T7", "T8", "T9", "T10", "T11"))) |> mutate(Treatments = factor(Treatments, labels = c("No fertilizer", "Ferti 1","Ferti 2","Ferti 3","Ferti 4","Ferti 5", "Ferti 6","Ferti 7","Ferti 8","Ferti 9","Ferti 10"))) yield_aov <- aov(Yield ~ Labels, data = my_data) yield_aov1 <- anova(yield_aov) tukey_L <- TukeyHSD(yield_aov) tukey_letters <- multcompLetters4(yield_aov, tukey_L) table_yield <- my_data %>% group_by(Labels) %>% summarise(Average = mean(Yield), .groups = 'drop') myletters <- as.data.frame.list(tukey_letters$Labels) table_yield$Letters <- myletters$Letters table_yield <- arrange(table_yield, Labels) table_yield %>% ggplot(aes(Labels, Average, fill = Labels)) + geom_bar(stat = "identity", colour = "black", width = 0.5) + labs(x = "Treatments", y = "Yield (q/ha)") # 添加Treatments为图例后的绘图代码 table_yield %>% ggplot(aes(Labels, Average, fill = Labels)) + geom_bar(stat = "identity", colour = "black", width = 0.5) + labs(x = "Treatments", y = "Yield") + scale_x_discrete(labels = unique(my_data$Treatments))
请问如何实现T1对应“No fertilizer”、T2对应“Ferti 1”……的映射,并保持X轴按T1到T11的顺序排列?
解决方案
核心问题分析
使用scale_x_discrete(labels = unique(my_data$Treatments))时,unique(my_data$Treatments)的提取顺序无法保证和Labels的T1-T11严格对应,会导致X轴标签错位,同时破坏Labels的因子顺序,最终造成X轴混乱。
修正步骤
- 强制Labels的因子顺序:明确指定Labels的水平为T1到T11,从底层保证X轴排序。
- 保留Labels与Treatments的对应关系:通过分组提取每个Labels对应的唯一Treatments值,避免映射错位。
- 精准替换X轴标签:用已匹配好顺序的Treatments值替换X轴显示标签,同时将Treatments绑定为图例变量。
完整修正代码
library(readxl) library(multcompView) library(dplyr) library(ggplot2) # 读取数据(合并重复读取的代码) my_data <- read_excel(file.choose(), sheet = 1) # 处理因子与对应关系:强制Labels顺序,绑定每个Labels对应的Treatments my_data <- my_data |> mutate(Labels = factor(Labels, levels = paste0("T", 1:11))) |> # 固定T1-T11的顺序 group_by(Labels) |> mutate(Treatments = first(Treatments)) |> # 确保每个Labels对应唯一的Treatments ungroup() # ANOVA与显著性分析(原逻辑不变) yield_aov <- aov(Yield ~ Labels, data = my_data) yield_aov1 <- anova(yield_aov) tukey_L <- TukeyHSD(yield_aov) tukey_letters <- multcompLetters4(yield_aov, tukey_L) # 汇总均值、Treatments与显著性字母 table_yield <- my_data %>% group_by(Labels, Treatments) %>% # 同时分组保留对应关系 summarise(Average = mean(Yield), .groups = 'drop') myletters <- as.data.frame.list(tukey_letters$Labels) table_yield$Letters <- myletters$Letters # 绘图:保证X轴顺序,绑定Treatments为图例 table_yield %>% ggplot(aes(x = Labels, y = Average, fill = Treatments)) + # fill绑定Treatments作为图例 geom_bar(stat = "identity", colour = "black", width = 0.5) + geom_text(aes(label = Letters), vjust = -0.3, size = 4) + # 添加显著性字母(可选) scale_x_discrete(labels = table_yield$Treatments) + # 用匹配好的Treatments替换X轴标签 labs(x = "Treatments", y = "Yield (q/ha)", fill = "Treatments") + # 设置图例标题 theme(axis.text.x = element_text(angle = 45, hjust = 1)) # 可选:旋转X轴标签避免重叠
关键说明
- 因子水平固定:
factor(Labels, levels = paste0("T", 1:11))强制Labels按T1到T11排序,这是X轴顺序正确的核心保障。 - 对应关系绑定:分组时同时包含
Labels和Treatments,确保每个Treatments都精准匹配对应的Labels,不会错位。 - 图例与标签同步:
fill = Treatments直接将图例与处理名称关联,scale_x_discrete使用已排序的Treatments作为X轴标签,两者顺序完全一致。
内容的提问来源于stack exchange,提问作者Vinod
相关产品推荐
相关产品推荐

