根据其他列定义轴中断之前不保存数据框

defining axis breaks based on other column without saving dataframe before

我经常创建如下图,轴 ticks/label 表示累计和。这一切都很好,但需要我先创建 tibble,然后才能使用 scale_y_continous(breaks=my_df$cumsum).

解决新的中断
library(tidyverse)


my_df <- tibble::tribble(
  ~group, ~value,
  "a",  10,
  "b",  20,
  "c",  60
  ) %>% 
  mutate(group=as_factor(group)) %>%
  arrange(desc(group)) %>% 
  mutate(value_cum=cumsum(value))
my_df
#> # A tibble: 3 x 3
#>   group value value_cum
#>   <fct> <dbl>     <dbl>
#> 1 c        60        60
#> 2 b        20        80
#> 3 a        10        90

my_df %>% 
  ggplot()+
  geom_bar(aes(fill=group,
               y=value,
               x=1),
           stat="identity",
           position=position_stack())+
  scale_y_continuous(breaks=my_df$value_cum)+
  coord_flip()+
  theme(axis.text.y = element_blank())

为了让事情更顺利一些,我想知道是否真的有一种方法可以直接处理新创建的 value_cum 变量,'on the fly',而不需要保存 dataframe/tibble ] 前。 hopefull 下面的失败尝试清楚地表明了我感兴趣的内容。问题基本上是我如何处理输入到 ggplot 中但之前未保存的值。

非常感谢。



tibble::tribble(
  ~group, ~value,
  "a",  10,
  "b",  20,
  "c",  60) %>% 
  mutate(group=as_factor(group)) %>%
  arrange(desc(group)) %>% 
  mutate(value_cum=cumsum(value)) %>% 
  ggplot()+
  geom_bar(aes(fill=group,
               y=value,
               x=1),
           stat="identity",
           position=position_stack()) +
  scale_y_continuous(breaks=.$value_cum))+  #does not work
  coord_flip()+
  theme(axis.text.y = element_blank())

reprex package (v0.3.0)

创建于 2019-12-14

我认为如果将整个图放在大括号中并在对 ggplot 的初始调用中指定数据应该可行:

tibble::tribble(
  ~group, ~value,
  "a",  10,
  "b",  20,
  "c",  60) %>%
  mutate(group = as_factor(group)) %>%
  arrange(desc(group)) %>% 
  mutate(value_cum = cumsum(value)) %>% 
  {
    ggplot(.)+
      geom_bar(aes(fill=group,
                   y=value,
                   x=1),
               stat="identity",
               position=position_stack()) +
      coord_flip()+
      scale_y_continuous(breaks=.$value_cum) +  #does not work
      theme(axis.text.y = element_blank())  
  }

你可以使用函数。有几种方法可以解决这个复杂的问题。这里有一些更简单的规模。不幸的是,我不认为将源数据框传回自定义函数是微不足道的。

数据

my_df <- tibble::tribble(
  ~group, ~value,
  "a",  10,
  "b",  20,
  "c",  60
)

将整个情节包装成一个函数

f_plot <- function(df) {

  my_breaks <- df %>% 
    mutate(group=as_factor(group)) %>%
    arrange(desc(group)) %>% 
    mutate(value_cum=cumsum(value)) %>%
    pull()

  ggplot(my_df) +
    geom_bar(aes(fill=group,
                 y=value,
                 x=1),
             stat="identity",
             position=position_stack()) +
    scale_y_continuous(breaks = my_breaks) +
    coord_flip() +
    theme(axis.text.y = element_blank())
}
f_plot(my_df)

将中断计算包装到一个函数中

scale_breaks1 <- function(df) {

  my_breaks <- df %>% 
    mutate(group=as_factor(group)) %>%
    arrange(desc(group)) %>% 
    mutate(value_cum=cumsum(value)) %>%
    pull()

  scale_y_continuous(breaks = my_breaks)

}
ggplot(my_df) +
  geom_bar(aes(fill=group,
               y=value,
               x=1),
           stat="identity",
           position=position_stack()) +
  scale_breaks1(my_df) +
  coord_flip() +
  theme(axis.text.y = element_blank())

将图形对象推入函数

scale_breaks2 <- function(p) {

  df <- p$data

  my_breaks <- df %>% 
    mutate(group=as_factor(group)) %>%
    arrange(desc(group)) %>% 
    mutate(value_cum=cumsum(value)) %>%
    pull()

  p + scale_y_continuous(breaks = my_breaks)

}
p <- ggplot(my_df) +
  geom_bar(aes(fill=group,
               y=value,
               x=1),
           stat="identity",
           position=position_stack()) +
  coord_flip() +
  theme(axis.text.y = element_blank())

p %>% scale_breaks2()