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

如何按clarity分组命名ggplot2组合直方图?

按clarity分组生成对应标题的组合直方图问题解决

问题说明

我正在学习R语言可视化,想要按clarity分组生成组合直方图,但遇到两个问题:

  1. 当前生成的所有直方图标题均为“carat”,无法用clarity的取值作为对应直方图的标题
  2. 尝试修改set_names写法时触发错误:Error in set_names(): ! The size of nm (8) must be compatible with the size of x (2)

原代码如下:

library(ggplot2)
library(dplyr)
library(rlang)
library(purrr)
library(gridExtra)

carat_histogram <- function(df) {
   label= names({{df}})
     
    ggplot(df, aes(x = carat)) + geom_histogram(binwidth = 0.1)+
      labs(title = label)
     }

by_clarity <- diamonds |> 
  group_nest(clarity)

by_clarity_named <- set_names(by_clarity$data, nm = by_clarity$clarity)

names(by_clarity_named)

by_clarity_named<-map(by_clarity_named, carat_histogram)

do.call(grid.arrange,by_clarity_named)

尝试过的错误代码:

by_clarity_named <- set_names(by_clarity, nm = by_clarity$clarity)
#Error in `set_names()`: ! The size of `nm` (8) must be compatible with the size of `x` (2).

问题原因

  1. 标题错误原因:carat_histogram函数中用names({{df}})获取标题,但group_nest生成的每个子数据框包含原数据的多列(carat、cut、color等),names({{df}})返回的是所有列名的向量,ggplot会自动取第一个元素(即carat)作为标题,所以所有图的标题都相同。
  2. set_names报错原因:by_clarity是一个包含2列(clarity和data)的数据框,对象长度为2,但by_clarity$clarity有8个取值,用set_names(by_clarity, by_clarity$clarity)时,名字数量和对象长度不匹配,因此触发错误。

解决方案

方法一:用pmap同时传递分组值和数据

直接修改函数,增加参数接收clarity值作为标题,用pmap按行遍历分组后的数据,同时传递分组值和子数据框:

library(ggplot2)
library(dplyr)
library(purrr)
library(gridExtra)

# 修改函数,新增clarity_val参数用于设置标题
carat_histogram <- function(df, clarity_val) {
  ggplot(df, aes(x = carat)) + 
    geom_histogram(binwidth = 0.1) +
    labs(title = clarity_val)
}

# 按clarity分组嵌套数据
by_clarity <- diamonds |> 
  group_nest(clarity)

# 按行传递clarity值和子数据框,生成直方图列表
hist_list <- pmap(by_clarity, carat_histogram)

# (可选)给直方图列表设置名字,方便后续操作
names(hist_list) <- by_clarity$clarity

# 组合显示所有直方图
do.call(grid.arrange, hist_list)

方法二:用set_names+map2绑定名字和数据

如果坚持使用set_names给数据列表命名,可以用map2同时遍历数据列表和它的名字,将名字作为标题传递给函数:

library(ggplot2)
library(dplyr)
library(purrr)
library(gridExtra)

# 修改函数,新增title参数接收标题
carat_histogram <- function(df, title) {
  ggplot(df, aes(x = carat)) + 
    geom_histogram(binwidth = 0.1) +
    labs(title = title)
}

# 按clarity分组嵌套数据
by_clarity <- diamonds |> 
  group_nest(clarity)

# 给data列的子数据框列表命名为对应的clarity值
named_data <- set_names(by_clarity$data, by_clarity$clarity)

# 同时遍历数据列表和它的名字,生成直方图
hist_list <- map2(named_data, names(named_data), carat_histogram)

# 组合显示所有直方图
do.call(grid.arrange, hist_list)

关键说明

  • 原代码中set_names(by_clarity$data, by_clarity$clarity)是正确的写法,因为by_clarity$data是包含8个子数据框的列表,和by_clarity$clarity的长度(8)匹配,之前的错误是误将整个数据框by_clarity作为命名对象,而非data列的列表。
  • 不要通过子数据框的列名获取标题,因为子数据框保留了原数据的所有列,无法直接拿到分组的clarity值,最好直接传递分组值作为标题参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 18:45:34