在 ggplot2 图中自动使用标签(避风港语义)

Rub*_*ben 5 r ggplot2 r-haven

我正在绘制使用避风港语义标记的数据,即变量和值具有通过属性定义的标签。

通常,这些标签也是我想要的轴标题和刻度。

library(ggplot2)
mtcars$mpg = haven::labelled(mtcars$mpg, labels = c("low" = 10, "high" = 30))
attributes(mtcars$mpg)$label = "miles per gallon"
ggplot(mtcars, aes(mpg, cyl)) + geom_point() + 
scale_x_continuous(attributes(mtcars$mpg)$label, 
     breaks = attributes(mtcars$mpg)$labels, 
     labels = names(attributes(mtcars$mpg)$labels))
Run Code Online (Sandbox Code Playgroud)

我可以编写一个帮助程序,用更容易迭代的内容来替换费力的scale_x_continuous 语句吗?例如类似的东西 scale_x_continuous(label_from_attr, breaks = breaks_from_attr, labels = value_labels_from_attr)。或者甚至可以+ add_labels_from_attributes()更换整个东西?

我知道我可以编写/使用帮助程序,例如Hmisc::label稍微缩短上面的属性代码,但这不是我想要的。

Axe*_*man 4

我没有很好的规模,但你可以使用这样的函数:

label_x <- function(p) {
  b <- ggplot_build(p)
  x <- b$plot$data[[b$plot$labels$x]]
  
  p + scale_x_continuous(
    attributes(x)$label, 
    breaks = attributes(x)$labels, 
    labels = names(attributes(x)$labels)
  )
}
Run Code Online (Sandbox Code Playgroud)

然后使用 as (+不行):

p <- ggplot(mtcars, aes(mpg, cyl)) + geom_point()
label_x(p)
Run Code Online (Sandbox Code Playgroud)

或者,使用管道:

mtcars %>% { ggplot(., aes(mpg, cyl)) + geom_point() } %>% label_x()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


旧的解决方案

use_labelled <- function(l, axis = "x") {
    if (axis == "x")  {
        scale_x_continuous(attributes(l)$label, 
                           breaks = attributes(l)$labels, 
                           labels = names(attributes(l)$labels))
    } 
    if (axis == "y") {
        scale_y_continuous(attributes(l)$label, 
                          breaks = attributes(l)$labels, 
                          labels = names(attributes(l)$labels))
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你只需给出:

ggplot(mtcars, aes(mpg, cyl)) + geom_point() + use_labelled(mtcars$cyl)
Run Code Online (Sandbox Code Playgroud)

或者对于 y 轴:

ggplot(mtcars, aes(cyl, mpg)) + geom_point() + use_labelled(mtcars$cyl, "y")
Run Code Online (Sandbox Code Playgroud)