使用stat_summary_bin在ggplot中获取摘要的水平线

时间:2019-02-08 01:13:34

标签: r ggplot2

我想获取一个ggplot散点图,并在其上面覆盖x轴上均匀分布的bin中y变量的平均值。

到目前为止,我所拥有的是

library(tidyverse)
data(midwest)
ggplot(arrange(midwest,percollege),aes(x=percollege,y=percbelowpoverty))+
    geom_point()+ 
    stat_summary_bin(aes(x=percollege,y=percbelowpoverty),
        bins=10,fun.y='mean',geom='point',col='red')

哪个生产 enter image description here

这基本上是完美的,除了红色点之外,我希望水平红线从垃圾箱的起点延伸到垃圾箱的终点。

我可以模仿我想要的东西

library(tidyverse)
data(midwest)
ggplot(arrange(midwest,percollege),aes(x=percollege,y=percbelowpoverty))+
    geom_point()+ 
    stat_summary_bin(aes(x=percollege,y=percbelowpoverty),
        bins=10,fun.y='mean',geom='point',col='red',shape="-",size=50)

给出

enter image description here

除了我想要的以外,

  1. 每次创建这样的新图形时,我都必须手动设置大小
  2. 嗯,嗯。

我尝试过的另一种方法是使用geom='bar',fill=NA,如果我能以某种方式使其仅显示顶部条而没有条的侧面或底部,这似乎很有希望。

有任何提示吗?我很难将geom设置为pointrangelinerangeline(前两个尚未使用,最后一个只是将每个点与非点连接-水平线)。老实说,这不是stat_summary_bin的默认行为!

谢谢!

2 个答案:

答案 0 :(得分:3)

这应该有效。我认为rownames_to_column行可能不是必需的,而modify_if参数是必需的,因为cut函数生成的是字符串而不是数字值。

midwest_sum <- midwest %>%
  mutate(coll_bins = cut(percollege, breaks = 10)) %>%
  group_by(coll_bins) %>%
  summarise(bin_mean = mean(percbelowpoverty)) %>%
  rownames_to_column(var = "bin_num") %>%
  tidyr::extract(coll_bins, c("min", "max"), "\\((.*),(.*)]") %>%
  modify_if(is.character, as.numeric)


ggplot()+
    geom_point(data = midwest, aes(x=percollege,y=percbelowpoverty)) +
    geom_errorbarh(data = midwest_sum, aes(xmin = min, xmax = max, y = bin_mean), 
                   col = "red", size = 1)

希望这会有所帮助!

答案 1 :(得分:2)

我不会经常将这种默认行为称为“默认行为”。遗漏箱的侧面必定使混乱的箱边界实际位于远高于或低于箱均值的点上。

无论如何,这是第一次尝试。我们可以根据一些输入参数来计算分箱边界,然后使用geom_segment在图形上绘制它们。 geom_segment需要开始和结束坐标,因此bin_boundaries计算y变量的均值和x变量的bin边界,然后返回对geom_segment的调用。这意味着我们可以简单地将函数的输出添加到我们的ggplot调用中,即可正常工作。请注意使用通过...进行传递,因此我们仍然可以使用geom参数。

您可能会修改为使用其他bin宽度和躲闪参数,而不是根据x变量的边界进行计算,对此您不必太仔细考虑。请注意,这些线看起来与您使用stat_summary_bin不同,因为它们的居中位置不同,因此在每次计算中使用不同的点。您可能还会考虑使用geom_step的版本,它将连接每条水平线的末端。

library(tidyverse)
bin_boundaries <- function(tbl, n_bins, x_var, y_var, ...) {
  x_var <- enquo(x_var)
  y_var <- enquo(y_var)
  bin_bounds <-  seq(
    from = min(pull(tbl, !!x_var)),
    to = max(pull(tbl, !!x_var)),
    length.out = n_bins + 1)
  bounds_tbl <- tbl %>%
    mutate(bin_group = ntile(!!x_var, n_bins)) %>%
    group_by(bin_group) %>%
    summarise(!!y_var := mean(!!y_var)) %>%
    mutate(bin_start = bin_bounds[1:n_bins], bin_end = bin_bounds[2:(n_bins + 1)])
  geom_segment(
    data = bounds_tbl,
    mapping = aes(
      x = bin_start, y = !!y_var,
      xend = bin_end, yend = !!y_var
    ),
    ...
  )
}

ggplot(midwest) +
  geom_point(aes(x = percollege, y = percbelowpoverty)) +
  bin_boundaries(midwest, 10, percollege, percbelowpoverty, colour = "red", size = 1)

reprex package(v0.2.1)于2019-02-07创建