(重新)ggplot2 facet_ call中的名称因子级别(或包含变量名称)

时间:2016-07-26 12:31:50

标签: r ggplot2 dplyr plyr

我做的很多一种模式是在数字值的切割上绘制图。 ggplot2中的facet_wrap不允许你从内部调用函数,因此你必须创建一个临时因子变量。这可以使用来自dplyr的mutate。这样做的好处是你可以玩EDA并改变分位数,或改变设置切点等,并在一行中查看变化。缺点是facet只用因子级别标记;例如,你必须知道这是一个温度。这对你自己来说并不是太糟糕,但即使我在两个这样的变量上做facet_grid并且必须记住哪个是哪个变量,我也会感到困惑。因此,通过包含有意义的名称来重新标记方面真的很不错。

这个问题的关键点是,当你改变分位数等时,水平会发生变化。你不知道他们提前做了什么。您可以使用base levels()函数,但这意味着使用cut变量扩充数据框,然后调用levels(),然后将此扩充数据框传递给ggplot()。

因此,使用plyr :: mapvalues,我们可以将所有这些包装成dplyr :: mutate,但mapvalues()所需的参数使它非常笨重。必须多次重新输入“Temp.f”并不是非常“dplyr”!

是否有更简洁的方式来“动态”重命名这样的因子水平?我希望这个描述足够清楚,下面的代码示例会有所帮助。

library(ggplot2)
library(plyr)
library(dplyr)
library(Hmisc)
df <- data.frame(Temp = seq(-100, 100, length.out = 1000), y = rnorm(1000))

# facet_wrap doesn't allow functions so have to create new, temporary factor
# variable Temp.f
ggplot(df %>% mutate(Temp.f = cut2(Temp, g = 4))) + geom_histogram(aes(x = y)) + facet_wrap(~Temp.f)
# fine, but facet headers aren't very clear,
# we want to highlight that they are temperature
ggplot(df %>% mutate(Temp.f = paste0("Temp: ", cut2(Temp, g = 4)))) + geom_histogram(aes(x = y)) + facet_wrap(~Temp.f)
# use of paste0 is undesirable because it creates a character vector and
# facet_wrap then recodes the levels in the wrong numerical order

# This has the desired effect, but is very long!
ggplot(df %>% mutate(Temp.f = cut2(Temp, g = 4), Temp.f = mapvalues(Temp.f, levels(Temp.f), paste0("Temp: ", levels(Temp.f))))) + geom_histogram(aes(x = y)) + facet_wrap(~Temp.f)

2 个答案:

答案 0 :(得分:2)

我认为您可以使用自定义贴标机功能在facet_wrap内执行此操作,如下所示:

myLabeller <- function(x){
  lapply(x,function(y){
    paste("Temp:", y)
  })
}

ggplot(df %>% mutate(Temp.f = cut2(Temp, g = 4))) +
  geom_histogram(aes(x = y)) +
  facet_wrap(~Temp.f
             , labeller = myLabeller)

那个贴标书很笨重,但至少是一个例子。您可以为要使用的每个变量编写一个(例如tempLabelleryLabeller等)。

enter image description here

略微调整会使这更好:它会自动使用你正在面对的东西的名称:

betterLabeller <- function(x){
  lapply(names(x),function(y){
    paste0(y,": ", x[[y]])
  })
}

ggplot(df %>% mutate(Temp.f = cut2(Temp, g = 4))) +
  geom_histogram(aes(x = y)) +
  facet_wrap(~Temp.f
             , labeller = betterLabeller)

enter image description here

答案 1 :(得分:1)

好的,感谢Mark Peterson指出我对贴标机的论点/功能,我很满意的确切答案是:

ggplot(df %>% mutate(Temp.f = cut2(Temp, g = 4))) + geom_histogram(aes(x = y)) + facet_wrap(~Temp.f, labeller = labeller(Temp.f = label_both))

我是懒惰的粉丝,&#34; label_both&#34;意味着我可以简单地创建一个有意义的临时(或覆盖原始)变量列,并给出名称和值。滚动你自己的贴标机功能更强大,但使用label_both是一个很好的,简单的选择。