将标题格式化程序添加到ggplot2

时间:2017-11-17 16:42:45

标签: r ggplot2

我正在开发一个软件包,使我公司的其他用户更容易使用ggplot2。我想做的一件事就是添加一个自动将丑陋变量名称格式化为漂亮标题的函数。

我有一个功能,已经这样做了。让我们假设有一些虚拟数据和基本情节:

data <- data.frame(
  place_name = c("Los Angeles","New York"),
  some_amount = c(5,10)
)

g <- ggplot(data, aes(x = place_name, y = some_amount)) +
  geom_bar(stat = 'identity') +
  labs(title = "test_of_function")

所以我有我的ggplot,我想格式化标题。将函数应用于函数的标签后,此函数可以正常工作。

format_title <- function(...,sep = "[^[:alnum:]]+"){

  args <- list(...)

  if (is.list(args[[1]]))
    args <- args[[1]]

  lapply(args, function(x, sep){
    stringr::str_to_title(stringr::str_replace_all(x,sep," "))
  }, sep = sep)
}

format_plot_titles <- function(g){
  g$labels <- format_title(g$labels)
  g
}

现在如果我们比较它们:

g

enter image description here

format_plot_titles(g)

enter image description here

我希望做的是通过ggplot2 +添加它,但为了做到这一点,我需要访问以前的绘图标签。

它看起来像这样(名字更好):

ggplot(data, aes(x = place_name, y = some_amount)) +
    geom_bar() +
    title_labels()

我在尝试将新标签叠加在旧标签之上时,很难弄清楚如何访问上一个标记的标签。任何帮助表示赞赏!

编辑:解决了这个问题。虽然没有光滑的解决方案。我基本上不得不覆盖ggplot2导出的+的默认s3方法,以接收一种新类型的对象,我称之为&#34;格式化程序&#34;。这允许我构造一个检查格式化程序类的方法,如果我的对象继承了格式化程序类,它会将该格式化程序应用于打印标签。这是代码:

`+.gg` <- function (e1, e2) {
  e2name <- deparse(substitute(e2))
  if (ggplot2::is.theme(e1))
    ggplot2:::add_theme(e1, e2, e2name)
  else if (ggplot2::is.ggplot(e1) & is.formatter(e2)){
    add_formatter(e1, e2, e2name)
  }
  else if (ggplot2::is.ggplot(e1))
    ggplot2:::add_ggplot(e1, e2, e2name)
}

update_format <- function(p, formatter){
  p <- ggplot2:::plot_clone(p)
  p$labels <- formatter(p$labels)
  p
}

add_formatter <- function(p, formatter, objectname) {
  update_format(p, formatter)
}

is.formatter <- function(x){
  inherits(x,"formatter")
}

format_title <- function(...,sep = "[^[:alnum:]]+"){

  args <- list(...)

  if (is.list(args[[1]]))
    args <- args[[1]]

  lapply(args, function(x, sep){
    stringr::str_to_title(stringr::str_replace_all(x,sep," "))
  }, sep = sep)
}

title_labels <- function(...){
  structure(format_title, class = "formatter")
}

ggplot(data, aes(x = place_name, y = some_amount)) +
  geom_bar(stat = 'identity') +
  title_labels()

1 个答案:

答案 0 :(得分:2)

将编辑作为正式答案发布。

解决了这个问题。虽然没有光滑的解决方案。我基本上不得不覆盖ggplot2导出的+的默认s3方法,以接受我称之为“格式化程序”的新类型的对象。这允许我构造一个检查格式化程序类的方法,如果我的对象继承了格式化程序类,它会将该格式化程序应用于打印标签。这是代码:

`+.gg` <- function (e1, e2) {
  e2name <- deparse(substitute(e2))
  if (ggplot2::is.theme(e1))
    ggplot2:::add_theme(e1, e2, e2name)
  else if (ggplot2::is.ggplot(e1) & is.formatter(e2)){
    add_formatter(e1, e2, e2name)
  }
  else if (ggplot2::is.ggplot(e1))
    ggplot2:::add_ggplot(e1, e2, e2name)
}

update_format <- function(p, formatter){
  p <- ggplot2:::plot_clone(p)
  p$labels <- formatter(p$labels)
  p
}

add_formatter <- function(p, formatter, objectname) {
  update_format(p, formatter)
}

is.formatter <- function(x){
  inherits(x,"formatter")
}

format_title <- function(...,sep = "[^[:alnum:]]+"){

  args <- list(...)

  if (is.list(args[[1]]))
    args <- args[[1]]

  lapply(args, function(x, sep){
    stringr::str_to_title(stringr::str_replace_all(x,sep," "))
  }, sep = sep)
}

title_labels <- function(...){
  structure(format_title, class = "formatter")
}

ggplot(data, aes(x = place_name, y = some_amount)) +
  geom_bar(stat = 'identity') +
  title_labels()