【问题标题】:(Re)name factor levels (or include variable name) in ggplot2 facet_ call在 ggplot2 facet_ 调用中(重新)命名因子级别(或包括变量名称)
【发布时间】:2016-07-26 12:31:50
【问题描述】:

我经常做的一个模式是在数值切割上刻面图。 ggplot2 中的 facet_wrap 不允许您从内部调用函数,因此您必须创建一个临时因子变量。使用 dplyr 中的 mutate 没问题。这样做的好处是您可以玩 EDA 并改变分位数的数量,或更改设置切割点等,并在一行中查看更改。缺点是方面仅按因子级别标记;例如,你必须知道它是一个温度。这对你自己来说并不算太糟糕,但是如果我对两个这样的变量进行 facet_grid 并且必须记住哪个是哪个,我也会感到困惑。因此,能够通过包含一个有意义的名称来重新标记构面真是太好了。

这个问题的关键在于,随着分位数等的变化,级别会发生变化;你事先不知道它们是什么。你可以使用基本的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)

【问题讨论】:

  • 在绘图前使用df$newFactor &lt;- factor(df$oldFactor, levels=c(...))重命名因子或使用levels(df$oldFactor) &lt;- c(...)
  • 作为cut2 的替代方案,您还可以使用带有labels 参数的基本R 中的cut 函数。

标签: r ggplot2 dplyr plyr


【解决方案1】:

我认为您可以在 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 等)。

稍微调整一下就更好了:它会自动使用您正在刻面的事物的名称:

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)

【讨论】:

    【解决方案2】:

    好的,感谢 Mark Peterson 将我指向 labeller 参数/函数,我很满意的确切答案是:

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

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

    【讨论】:

      猜你喜欢
      • 2019-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-24
      相关资源
      最近更新 更多