R 在ggplot中将文本添加到geom_直方图的正确方法是什么?
我在x轴和y轴上绘制了一个工资的历史图,显示了数据集中拥有这一特定工资的个人的百分比。现在我想让各个条显示每个条中有多少观察者。e、 g在我提供的样本_数据中,有多少工资在10%栏中,有多少工资在20%栏中 这是我的一个小样本数据:R 在ggplot中将文本添加到geom_直方图的正确方法是什么?,r,ggplot2,R,Ggplot2,我在x轴和y轴上绘制了一个工资的历史图,显示了数据集中拥有这一特定工资的个人的百分比。现在我想让各个条显示每个条中有多少观察者。e、 g在我提供的样本_数据中,有多少工资在10%栏中,有多少工资在20%栏中 这是我的一个小样本数据: sample_data<- structure(list(wage = c(81L, 77L, 63L, 84L, 110L, 151L, 59L, 109L, 159L, 71L), sch
sample_data<- structure(list(wage = c(81L, 77L, 63L, 84L, 110L, 151L, 59L,
109L, 159L, 71L), school = c(15L, 12L, 10L, 15L, 16L, 18L, 11L,
12L, 10L, 11L), expr = c(17L, 10L, 18L, 16L, 13L, 15L, 19L, 20L,
21L, 20L), public = c(0L, 1L, 0L, 1L, 0L, 0L, 1L, 0L, 0L, 0L),
female = c(1L, 1L, 1L, 1L, 0L, 0L, 1L, 0L, 1L, 0L), industry = c(63L,
93L, 71L, 34L, 83L, 38L, 82L, 50L, 71L, 37L)), row.names = c("1",
"2", "3", "4", "5", "6", "7", "8", "9", "10"), class = "data.frame")
基本上我对此很满意,但不管我怎么做,我都无法在我的专栏顶部找到文本。下面是一个使用stat_count但不起作用的示例:
ggplot(data = sample_data) +
geom_histogram(aes(x = wage, y = stat(count) / sum(count)), binwidth = 4, color = "black") +
scale_x_continuous(breaks = seq(0, 300, by = 20)) +
scale_y_continuous(labels = scales::percent_format()) +
stat_count(aes(y = ..count.., label =..count..), geom = "text")
Iv'e还尝试使用geom_文本,但没有结果
编辑:回答
也非常感谢那些回复的人。
我最终使用了teunbrand的解决方案,并做了一个小小的修改,将after_stat(density)改为after_stat(count)/sum(count)
以下是“最终”代码:
ggplot(sample_data) +
geom_histogram(
aes(x = wage,
y = after_stat(count) / sum(count)),
binwidth = 4, colour = "black"
) +
stat_bin(
aes(x = wage,
y = after_stat(count) / sum(count),
label = after_stat(ifelse(count == 0, "", count))),
binwidth = 4, geom = "text", vjust = -1) +
scale_x_continuous(breaks = seq(0, 300, by = 20)) +
scale_y_continuous(labels = scales::percent_format())
就我个人而言,我觉得关于这个问题的现有答案有些令人沮丧,而我希望有一个更简单的解决方案。我个人也不喜欢直方图中出现的0,使用
stat\u bin
定位有时会令人沮丧。由于不得不这样做几次,我通常会回到一些手动计算,并将geom\u rect
与geom\u文本
/geom\u标签
结合使用。也许有一天我会坐下来,实际创建我认为需要的3个函数来创建一个合适的geom.*
。在此之前,基本理念是:
hist
geom\u rect
(我们的“geom\u hist
”替代品)和geom\u文本所需的美学技巧,将数据更改为data.frame
#“计算用于创建包含标签的ggplot手动直方图的数据
#'
#“@param bardata从\code{hist(data,plot=FALSE)}输出
#“@param probs标签应该是概率标度还是非概率标度?
#'
#“@返回一个\code{data.frame},列为xmin、ymin、xmax、ymax、mids和label
创建_gg_hist_df不同的层通常不共享状态信息,因此您可以使用与直方图相同的统计(stat_bin()
)来显示标签。然后,您可以使用after_stat()
使用图层stat部分的计算变量来制作标签
库(ggplot2)
示例_数据相关:我认为这不起作用:“y”的比例已经存在。为“y”添加另一个比例,它将替换现有比例。错误:stat_bin()需要一个x或y美学。也许新的ish在_stat
之后可能会有所帮助(我没有使用过它…)-请参见示例,如果它是关于geom\u直方图的描述的
。对于直方图图中的这个零问题,它是有用的,并且是一个救生装置。通过使用geom\u col而不是geom\u rect,您可以大大简化此代码。ymin始终为0,ymax=y,mids=x。例如,列的宽度为2*(bardata,abs(breaks[1]-mids[1]))
,(顺便说一句,+1)很棒!这很有用。请问“after_stat(ifelse(count==0,”,count)”是什么意思?我猜这意味着如果值为0,它将不会打印标签?没错:after_stat()
访问?stat bin
中记录的“计算变量”。然后ifelse()
部分使用空字符串(”
)如果count
计算变量为0,并且在非零时使用count
本身。
ggplot(sample_data) +
geom_histogram(
aes(x = wage,
y = after_stat(count) / sum(count)),
binwidth = 4, colour = "black"
) +
stat_bin(
aes(x = wage,
y = after_stat(count) / sum(count),
label = after_stat(ifelse(count == 0, "", count))),
binwidth = 4, geom = "text", vjust = -1) +
scale_x_continuous(breaks = seq(0, 300, by = 20)) +
scale_y_continuous(labels = scales::percent_format())
#' Compute data for creating a manual histogram with ggplot including labels
#'
#' @param bardata output from \code{hist(data, plot = FALSE)}
#' @param probs should labels be in probability scale or non-probability scales?
#'
#' @return a \code{data.frame} with columns xmin, ymin, xmax, ymax, mids and label
create_gg_hist_df <- function(bardata, probs = TRUE){
nb <- length(bardata$breaks)
xmax <- bardata$breaks[-1L]
xmin <- bardata$breaks[-nb]
mids <- bardata$mids
ymin <- integer(nb - 1)
ymax <- bardata$count / sum(bardata$count)
label <- if(!probs) ymax else bardata$count
data.frame(xmin = xmin,
ymin = ymin,
xmax = xmax,
ymax = ymax,
mids = mids,
label = label)
}
ggbardata <- create_gg_hist_df(hist(sample_data$wage,
# breaks based on ggplot2 when "width" is supplied
breaks = ggplot2:::bin_breaks_width(range(sample_data$wage),
width = 4)$breaks,
plot = FALSE))
ggbardata %>%
# Remove "0" columns ( I don't want them. That is my preference )
filter(ymax > 0) %>%
ggplot(aes(xmin = xmin, xmax = xmax,
ymin = ymin, ymax = ymax,
label = label)) +
# Add histogram
geom_rect(color = 'black') +
# Add text
geom_text(aes(x = mids, y = ymax), nudge_y = 0.005) +
scale_y_continuous(labels = scales::percent_format()) +
labs(x = 'wage', y = 'frequency')