【问题标题】:How does the group column from ggplot_build correspond to the original factor levels?ggplot_build 中的组列如何对应于原始因子水平?
【发布时间】:2017-01-03 02:33:33
【问题描述】:

我有一个基于此answer 的后续问题,在以下代码行中的scale_fill_manual 位中:

ggplot(data = temp2, aes(x = x, y = y2, fill = group)) +
geom_bar(width = 0.1, stat = "identity") +
scale_fill_manual(name = "key", labels = c("a", "b", "c", "d", "e", "others"),
           values = c("#F8766D", "#A3A500", "#00BF7D", "#00B0F6", "#E76BF3", "#000000")) +
labs(x = "value", y = "count") -> g2

颜色值和图例标签是通过映射到ggplot_build 生成的数据框中的group 列确定的。我的问题是关于这种映射的确定,尤其是当group 列是从具有不完整因子水平的因子列中派生的。

例如:

set.seed(111)
tmp_df <-  
    data.frame(a = rnorm(100, 0, 1),
               b = rnorm(100, 0.5, 1),
               c = rnorm(100, -0.5, 1),
               d = rnorm(100, 1, 1),
               e = rnorm(100, -1, 1)) %>%
    tidyr::gather() %>%
    mutate(key = factor(key, levels = letters[1:5]))

现在创建堆积条形图并生成底层原始数据:

tmp_df %>%
    filter(key != "c") %>%
    ggplot(aes(x = value, fill = key)) +
    geom_histogram(binwidth = 0.1, position = 'stack') ->
    p

tmp_raw_df <- ggplot_build(p)$data[[1]]

检查tmp_raw_df:

> head(tmp_raw_df)
     fill y count    x  xmin  xmax density ncount ndensity PANEL group ymin ymax colour size linetype alpha
1 #C77CFF 1     1 -4.2 -4.25 -4.15     0.1  0.125     1.25     1     4    0    1     NA  0.5        1    NA
2 #00BFC4 1     0 -4.2 -4.25 -4.15     0.0  0.000     0.00     1     3    1    1     NA  0.5        1    NA
3 #7CAE00 1     0 -4.2 -4.25 -4.15     0.0  0.000     0.00     1     2    1    1     NA  0.5        1    NA
4 #F8766D 1     0 -4.2 -4.25 -4.15     0.0  0.000     0.00     1     1    1    1     NA  0.5        1    NA
5 #C77CFF 0     0 -4.1 -4.15 -4.05     0.0  0.000     0.00     1     4    0    0     NA  0.5        1    NA
6 #00BFC4 0     0 -4.1 -4.15 -4.05     0.0  0.000     0.00     1     3    0    0     NA  0.5        1    NA

我们看到key 的值已映射到组号 1-4。我的问题是,这个映射是如何完成的,如何从tmp_raw_df 中的group 列恢复键或因子级别的原始值?

【问题讨论】:

  • 我不能说映射是如何完成的(尽管我怀疑通过重构 key、删除未使用的级别并转换为整数),但我确信 ggplot_build(p)$data 不包含原始key 的值。这些值现在应该存在于绘图的比例尺中。
  • 谢谢,那么应该如何/去哪里检索这些值?
  • 很可能,应该进入情节的ggproto 对象之一,但考虑到这些是如何评估的,我不确定你是否能够(轻松)检索你是什么寻找。
  • 通常因子在像@Fr 一样重构后按字母顺序分配。说过。因此,如果您想检查,您可以手动创建直方图或使用与ggplot 中相同的 bin 进行分箱,并将它们与tmp_raw_df 中的非零 bin 进行比较。您可能已经知道这一点,但是对于 factor 对象,您可以使用 levels() 检索值,然后将它们匹配起来。但是,数据在消失到ggplot 后基本上就丢失了。

标签: r ggplot2


【解决方案1】:

是的,即使您尝试使用 drop=FALSE 来保持因子完整性,ggplot 的当前版本仍将保留它以用于图例显示,但最终仍会丢弃它们以用于 grid 绘图的最终数据构建。您可以使用手动填充值来提供反向映射:

library(tidyverse)

set.seed(111)

data.frame(a = rnorm(100, 0, 1),
           b = rnorm(100, 0.5, 1),
           c = rnorm(100, -0.5, 1),
           d = rnorm(100, 1, 1),
           e = rnorm(100, -1, 1)) %>%
  tidyr::gather() %>%
  mutate(key = factor(key, levels = letters[1:5])) -> tmp_df

factor_map <- c(a="#111111", b="#222222", c="#333333", d="#444444", e="#555555")
rev_map <- setNames(names(factor_map), unname(factor_map))

tmp_df %>%
  filter(key != "c") %>%
  ggplot(aes(x = value, fill = key)) +
  geom_histogram(binwidth = 0.1, position = 'stack') +
  scale_fill_manual(drop=FALSE, values=factor_map) -> p

tmp_raw_df <- tbl_df(ggplot_build(p)$data[[1]])

tmp_raw_df <- mutate(tmp_raw_df, orig_factor=rev_map[fill])

distinct(tmp_raw_df, fill, group, orig_factor)
## # A tibble: 4 × 3
##      fill group orig_factor
##     <chr> <int>       <chr>
## 1 #555555     4           e
## 2 #444444     3           d
## 3 #222222     2           b
## 4 #111111     1           a

【讨论】:

    猜你喜欢
    • 2012-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多