在 ggplot2 图中自动使用标签(避风港语义)
automagically using labels (haven semantics) in ggplot2 plots
我正在绘制使用 haven semantics 标记的数据,即变量和值具有通过属性定义的标签。
通常,这些标签也是我想要的轴标题和刻度。
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))
我可以编写一个帮助程序,用更容易迭代的东西替换那个费力的 scale_x_continuous 语句吗?例如。就像是
scale_x_continuous(label_from_attr, breaks = breaks_from_attr, labels = value_labels_from_attr)
。或者甚至 + add_labels_from_attributes()
来替换整个东西?
我知道我可以 write/use 像 Hmisc::label
这样的助手来稍微缩短上面的 attribute-code,但这不是我想要的。
我没有很好的秤,但是你可以使用这样的函数:
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)
)
}
然后用as(+
不行):
p <- ggplot(mtcars, aes(mpg, cyl)) + geom_point()
label_x(p)
或者,使用管道:
mtcars %>% { ggplot(., aes(mpg, cyl)) + geom_point() } %>% label_x()
旧解
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))
}
}
那么你只要给:
ggplot(mtcars, aes(mpg, cyl)) + geom_point() + use_labelled(mtcars$cyl)
或者对于 y 轴:
ggplot(mtcars, aes(cyl, mpg)) + geom_point() + use_labelled(mtcars$cyl, "y")
另一种方法是为 ggplot() 编写一个包装器,它有自己的 class。然后当调用相应的打印方法时,属性具有完全可见性。请参阅包 'yamlet' (0.2.1) 中的 ?ag.print
。
library(ggplot2)
library(yamlet)
library(magrittr)
mtcars$disp %<>% structure(label = 'displacement', unit = 'cu. in.')
mtcars$mpg %<>% structure(label = 'mileage', unit = 'miles/gallon')
mtcars$am %<>% factor(levels = c(0,1), labels = c('automatic','manual'))
mtcars$am %<>% structure(label = 'transmission')
agplot(mtcars, aes(disp, mpg, color = am)) + geom_point()
我正在绘制使用 haven semantics 标记的数据,即变量和值具有通过属性定义的标签。
通常,这些标签也是我想要的轴标题和刻度。
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))
我可以编写一个帮助程序,用更容易迭代的东西替换那个费力的 scale_x_continuous 语句吗?例如。就像是
scale_x_continuous(label_from_attr, breaks = breaks_from_attr, labels = value_labels_from_attr)
。或者甚至 + add_labels_from_attributes()
来替换整个东西?
我知道我可以 write/use 像 Hmisc::label
这样的助手来稍微缩短上面的 attribute-code,但这不是我想要的。
我没有很好的秤,但是你可以使用这样的函数:
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)
)
}
然后用as(+
不行):
p <- ggplot(mtcars, aes(mpg, cyl)) + geom_point()
label_x(p)
或者,使用管道:
mtcars %>% { ggplot(., aes(mpg, cyl)) + geom_point() } %>% label_x()
旧解
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))
}
}
那么你只要给:
ggplot(mtcars, aes(mpg, cyl)) + geom_point() + use_labelled(mtcars$cyl)
或者对于 y 轴:
ggplot(mtcars, aes(cyl, mpg)) + geom_point() + use_labelled(mtcars$cyl, "y")
另一种方法是为 ggplot() 编写一个包装器,它有自己的 class。然后当调用相应的打印方法时,属性具有完全可见性。请参阅包 'yamlet' (0.2.1) 中的 ?ag.print
。
library(ggplot2)
library(yamlet)
library(magrittr)
mtcars$disp %<>% structure(label = 'displacement', unit = 'cu. in.')
mtcars$mpg %<>% structure(label = 'mileage', unit = 'miles/gallon')
mtcars$am %<>% factor(levels = c(0,1), labels = c('automatic','manual'))
mtcars$am %<>% structure(label = 'transmission')
agplot(mtcars, aes(disp, mpg, color = am)) + geom_point()