You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用R语言绘制数据框各列值频率的堆叠条形图?

问题解决:数据框列值频率的堆叠条形图可视化

问题说明

需要为数据框ad2的每一列生成堆叠条形图:每列对应一个主条形,条形内部按该列的唯一值(含NA)的频率堆叠,不同值用不同颜色区分。原代码无法实现堆叠效果,需调整逻辑。

问题根源

原代码中table(column, useNA = "always")生成的是一维频率表,barplot对一维表默认生成独立条形而非堆叠。要实现堆叠效果,需将所有列的频率数据整理为矩阵格式:行对应所有列的唯一值(含NA),列对应原数据框的每一列。

修正后的代码

# 定义颜色向量(可根据实际唯一值数量扩展)
colors <- c("steelblue", "coral", "palegreen", "purple", "orange", "gray")

# 提取所有列的唯一值(包含NA),统一统计水平
all_values <- unique(unlist(ad2))
all_values <- c(all_values[!is.na(all_values)], NA)  # 确保NA在最后

# 构建频率矩阵:行=唯一值,列=原数据框列名
freq_matrix <- sapply(ad2, function(col) {
  # 用factor强制统一水平,保证每列统计的维度一致
  table(factor(col, levels = all_values), useNA = "always")
})

# 生成整体堆叠条形图(所有列在同一张图)
barplot(freq_matrix, 
        main = "各列值频率堆叠条形图",
        xlab = "数据列", 
        ylab = "频率",
        col = colors[1:length(all_values)],  # 匹配唯一值数量分配颜色
        legend.text = all_values,
        args.legend = list(x = "topright", title = "值(含NA)")
)

# 如需单独为每列生成堆叠图(单列一张图)
plot_single_stacked_bar <- function(col_data, col_name, all_values, colors) {
  freq_table <- table(factor(col_data, levels = all_values), useNA = "always")
  # 转成1列矩阵,触发barplot的堆叠模式
  freq_mat <- matrix(freq_table, ncol = 1)
  barplot(freq_mat,
          main = paste("列:", col_name),
          xlab = col_name,
          ylab = "频率",
          col = colors[1:length(all_values)],
          legend.text = all_values,
          args.legend = list(x = "topright", title = "值(含NA)")
  )
}

# 循环生成单列堆叠图
for (col_name in names(ad2)) {
  cat("正在生成列", col_name, "的堆叠条形图\n")
  plot_single_stacked_bar(ad2[[col_name]], col_name, all_values, colors)
}

关键调整说明

  • 统一统计水平:先提取所有列的唯一值(含NA),确保每列的频率统计都覆盖这些值,避免因列值差异导致矩阵维度不匹配。
  • 矩阵转换:将每列的频率表转为矩阵的一列,barplot对矩阵默认启用堆叠模式(beside=FALSE为默认值)。
  • 颜色适配:根据唯一值的实际数量分配颜色,避免颜色重复或不足。
  • 图例优化:明确标注每个颜色对应的数值(包括NA),提升图表可读性。

内容的提问来源于stack exchange,提问作者Chocoboy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 12:17:43