R ggplot 循环:在 ggplot 直方图的 for 循环中,如何根据最大频率自动设置 y 轴刻度?

R ggplot loop: in a for loop of ggplot histograms, how can you automatically set the y axis scale based on max frequency?

我有以下循环来根据较大数据集 (df) 中的某些列(第 2 列到第 5 列)生成多个直方图:

loop.vector <- 2:5
for (i in loop.vector){
x <- df[,i]
print(ggplot(df,aes(x=x)) + geom_histogram(binwidth=1)+scale_x_continuous(breaks=seq(0,max((x),1)))
}

我希望像 x 轴一样自动完成 y 轴刻度,它的范围在零和最大频率值之间,以 1 为增量。

我知道如何手动设置这些值,如果我要绘图,看看它,并分别输入最大 y 轴值,但我想在循环中自动执行此操作。

谢谢!

回答问题:如何访问直方图的最大计数?

为了创建您的 scale_y_continuous 命令,您在每个图上缺少的信息是最大计数数。创建 ggplot 对象后,有一种访问此信息的好方法,即使用 ggplot2 中的内置 ggplot_build() 函数。对于给定的绘图,myPlot,以下将为您提供用于绘图中每一层的数据帧列表:

ggplot_build(myPlot)$data

在您的示例中,您可以访问第一个数据框的 count 列(因为您只有一个直方图 geom 图层)。以下是如何编写函数来执行您需要它执行的操作。我将使用一个示例数据集来向您展示结果。请注意,我还更改了 scale_x_continuous 行,以便通过使用 min()max() 以及 ceiling() 和 [= 的组合来容纳正数和负数23=] 函数:

set.seed(1234)
df <- data.frame(
  y1=rnorm(100,10,1),
  y2=rnorm(100,12,3),
  y3=rnorm(100,5,4),
  y4=rnorm(100,13,5))
    
for (i in 1:ncol(df)) {
  p <- ggplot(df, aes(df[,i])) +
    geom_histogram(alpha=0.5, color='black', fill='red', binwidth=1) +
    scale_x_continuous(breaks=seq(floor(min(df[,i])),ceiling(max(df[,i])))) +
    ggtitle(names(df)[i])
  
  # get max counts
  max_count <- max(ggplot_build(p)$data[[1]]$count)
  p <- p + scale_y_continuous(breaks=seq(0,max_count,1)) 

  print(p)
}

有没有更好的方法?

虽然这可以满足您的需求,但通常很难迭代地处理多个绘图输出到您的图形设备。我建议将上面的代码重新格式化为一个函数,然后使用 lapply() 并使用 cowplot 中的 plot_grid() 之类的东西来显示输出。下面的代码详细介绍了这种建议的方法:

myPlots <- function(data, column, fill_color) {
  # column = character name of column
  p <- ggplot(data, aes_string(x=column)) +
    geom_histogram(fill='red', binwidth=1, alpha=0.5, color='black') +
    scale_x_continuous(breaks=seq(floor(min(data[column])), ceiling(max(data[column])),1)) +
    ggtitle(column)
  
  max_count <- max(ggplot_build(p)$data[[1]]$count)
  p <- p + scale_y_continuous(breaks=seq(0,max_count,1))
  return(p)
}

library(cowplot)

plotList <- lapply(names(df), myPlots, data=df)
plot_grid(plotlist = plotList)

弄清楚了 - 我的值是整数,所以最终起作用的是 Duck 响应的变体。见下文:

loop.vector <- 2:5
for (i in loop.vector){
x <- df[,i]
print(ggplot(df,aes(x=x)) + geom_histogram(binwidth=1)+scale_x_continuous(breaks=seq(0,max((x),1)))+scale_y_continuous(breaks=seq(0,max(table(x)),1)))
}