如何在facet_grid中指定列,或者如何在facet_wrap中更改标签

50

我有很多数据系列要使用小型多面板进行绘图。 使用ggplot2和facet_wrap的组合可以实现我的目标,通常会得到一个6 x 6小面板的漂亮块。这是一个更简单的版本:

facet_wrap

问题在于我无法充分控制facet strips中的标签。数据框中的列名很短,我希望保持这种方式,但是我希望facet中的标签更加描述性。我可以使用facet_grid来利用labeller函数,但是似乎没有直接的方法来指定列数,而且一长行的facets对于这个特定任务来说并不适用。我是否忽略了一些明显的东西?

facet_grid

问:如何在使用facet_wrap时更改facet标签而不更改列名?或者在使用facet_grid时如何指定列数和行数?

以下是简化示例的代码。在实际情况中,我正在处理包含数十个数据系列的多个组,每个组都经常发生变化,因此任何解决方案都必须自动化,而不是依靠手动分配值。

require(ggplot2)
require(reshape)

# Random data with short column names
set.seed(123)
myrows <- 30
mydf <- data.frame(date = seq(as.Date('2012-01-01'), by = "day", length.out = myrows),
                   aa = runif(myrows, min=1, max=2),
                   bb = runif(myrows, min=1, max=2),
                   cc = runif(myrows, min=1, max=2),
                   dd = runif(myrows, min=1, max=2),
                   ee = runif(myrows, min=1, max=2),
                   ff = runif(myrows, min=1, max=2))

# Plot using facet wrap - we want to specify the columns
# and the rows and this works just fine, we have a little block
# of 2 columns and 3 rows

mydf <- melt(mydf, id = c('date'))

p1 <- ggplot(mydf, aes(y = value, x = date, group = variable)) +
    geom_line() +
    facet_wrap( ~ variable, ncol = 2)
print (p1)

# Problem: we want more descriptive labels without changing column names.
# We can change the labels, but doing so requires us to
# switch from facet_wrap to facet_grid
# However, in facet_grid we can't specify the columns and rows...

mf_labeller <- function(var, value){ # lifted bodily from the R Cookbook
    value <- as.character(value)
    if (var=="variable") {
        value[value=="aa"]   <- "A long label"
        value[value=="bb"]   <- "B Partners"
        value[value=="cc"]   <- "CC Inc."
        value[value=="dd"]   <- "DD Company"
        value[value=="ee"]   <- "Eeeeeek!"
        value[value=="ff"]   <- "Final"
    }
    return(value)
}

p2 <- ggplot(mydf, aes(y = value, x = date, group = variable)) +
    geom_line() +
    facet_grid( ~ variable, labeller = mf_labeller)
print (p2)

4
这是一个 未解决的问题,但在您的情况下(简单重命名,没有 bquote 或 plotmath ),您可以事先重命名变量。 - baptiste
1
@baptiste 我不知道这是一个公开问题(而且已经存在两年了,所以可能不太可能很快改变)。我猜 Hadley 需要更多的研究生参与这个项目! - SlowLearner
1
确实。可惜我认为以我的能力水平,可能不符合资格。 - SlowLearner
4个回答

27

我有点不明白。您已经编写了一个将短标签转换为长描述性标签的函数。那么,只需添加一个新列,在该列上使用facet_wrap即可,这有什么问题吗?

mydf <- melt(mydf, id = c('date'))
mydf$variableLab <- mf_labeller('variable',mydf$variable)

p1 <- ggplot(mydf, aes(y = value, x = date, group = variable)) +
    geom_line() +
    facet_wrap( ~ variableLab, ncol = 2)
print (p1)

12
添加新列没有任何问题 - 在那最后一步之前,我的大脑放弃了!我应该知道要这样做。“如果不确定,就在数据框中添加列”几乎是ggplot的默认帮助语句。谢谢。 - SlowLearner
请帮忙,我正在使用这个函数,但是出现了以下错误:在 if (variable == value) { : 条件长度大于1,只有第一个元素将被使用,其中 variableLab 在执行后没有任何元素。 - user1685185
我认为你需要在for循环中使用if(variable[i] == value [i]),针对数据帧的长度来解决你的错误。 - alily

9

如果要更改标签名称,只需更改在facet_wrap中使用的因子的因子级别。这些级别将在条带上用于facet_wrap。您可以使用与在facet_grid中使用labeller函数类似的设置。只需执行以下操作:

new_labels = sapply(levels(df$factor_variable), custom_labeller_function)
df$factor_variable = factor(df$factor_variable, levels = new_labels)

现在你可以在facet_wrap中使用factor_variable


0
只需将 labeller = label_wrap_gen(width = 25, multi_line = TRUE) 添加到 facet_wrap() 的参数中。
例如: ... + facet_wrap( ~ variable, ,labeller = label_wrap_gen(width = 25, multi_line = TRUE)) 更多信息请参考: ?ggplot2::label_wrap_gen

0
只需在 facet_wrap() 参数中添加 labeller = label_both 即可。
... + facet_wrap( ~ variable, labeller = label_both)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接