ggplot 分面网格的轴标签错误

Wrong axis labels for ggplot facet grid

this 遇到了一个奇怪的问题;

我想用 ggplot2 制作条形图,并将 x 轴标签作为 Group 列的最后一个字符。为此目的使用 substring(Group, 3, 3)

substring(df$Group, 3, 3)
# [1] "1" "2" "3" "1" "2" "1" "2" "3" "4"

但是当我像下面那样在 ggplot 中使用它时,它会在最后一个勾号处打印 1 而不是 4

ggplot(data=df, aes(x=Group, y=Value)) +
  geom_bar(stat="identity") + 
  scale_x_discrete(labels = substring(Group, 3, 3), expand=c(0.1,0.1)) +
  facet_grid(~ substring(Group, 1, 1), space="free_x", scales="free_x", switch="x") + 
  theme_bw() +
  theme(strip.placement = "outside",
        strip.background = element_rect(fill=NA,colour="grey50"),
        panel.spacing=unit(0,"cm"))

我可以使用 labels =unique(substring(Group, 3, 3) 让它工作,但是有人能解释一下这是怎么回事吗?

数据:

  df <- structure(list(Group = structure(1:9, .Label = c("1_1", "1_2",  
  "1_3", "2_1", "2_2", "3_1", "3_2", "3_3", "3_4"), class = "factor"),  
      Value = c(-1.23, 2.34, 0.56, 1.87, -2.4, 5.54, -0.98, -2.31,  
      6)), .Names = c("Group", "Value"), row.names = c(NA, -9L), class = "data.frame")

# > df

#   Group Value 
# 1   1_1 -1.23 
# 2   1_2  2.34 
# 3   1_3  0.56 
# 4   2_1  1.87 
# 5   2_2 -2.40 
# 6   3_1  5.54 
# 7   3_2 -0.98 
# 8   3_3 -2.31 
# 9   3_4  6.00

让我们简化并开始新的 R 会话:

df <- structure(list(Group = structure(1:9, .Label = c("1_1", "1_2",  
                                                       "1_3", "2_1", "2_2", "3_1", "3_2", "3_3", "3_4"), class = "factor"),  
                     Value = c(-1.23, 2.34, 0.56, 1.87, -2.4, 5.54, -0.98, -2.31,  
                              6)), .Names = c("Group", "Value"), row.names = c(NA, -9L), class = "data.frame")

library(ggplot2)
ggplot(data=df, aes(x=Group, y=Value)) +
    geom_bar(stat="identity") + 
    scale_x_discrete(labels = substring(Group, 3, 3), expand=c(0.1,0.1))
# Error in substring(Group, 3, 3) : object 'Group' not found

scale_x_discrete 参数无法访问内部数据环境。 (我认为只有两个地方可以安全地引用 ggplot2 中的数据列:aes() 内部和分面调用中 formula 的一部分。)您的代码必须找到一个 Group 来自你的全局环境的对象,这可能是整个专栏。这就是为什么你的问题没有出现错误,但我在使用新的 R 会话时出现了错误。

通常让ggplot2做你想做的最简单的方法是修复你的数据,使其与你想要的相匹配:

df$group_last = substring(df$Group, 3, 3)
ggplot(data=df, aes(x=group_last, y=Value)) +
    geom_bar(stat="identity") + 
    scale_x_discrete(expand=c(0.1,0.1))

此时您可以重新添加构面和主题,一切都会正常进行。

我认为@Gregor 的回答是可行的方法,但我可以解释错误。即使您在 group 之前添加 df$,您也会得到您所描述的行为。如果你不让比例变化,你就会明白为什么:

ggplot(data=df, aes(x=Group, y=Value)) +
  geom_bar(stat="identity") + 
  scale_x_discrete(labels = substring(df$Group, 3, 3), expand=c(0.1,0.1)) +
  facet_grid(~ substring(Group, 1, 1), switch="x") + 
  theme_bw() +
  theme(strip.placement = "outside",
        strip.background = element_rect(fill=NA,colour="grey50"),
        panel.spacing=unit(0,"cm"))

给出:

如您所见,此处正确给出了“4”。但是,当您直接设置标签时,当您允许比例变化时,它会(按顺序)分别为每个方面设置标签。实际上,您每次都将标签设置为“1、2、3、1、2、1、2、3、4”,但只使用前几个。

如果您想更贴近当前,您还需要设置休息时间,例如:

ggplot(data=df, aes(x=Group, y=Value)) +
  geom_bar(stat="identity") + 
  scale_x_discrete(breaks = df$Group, labels = substring(df$Group, 3, 3), expand=c(0.1,0.1)) +
  facet_grid(~ substring(Group, 1, 1), space="free_x", scales="free_x", switch="x") + 
  theme_bw() +
  theme(strip.placement = "outside",
        strip.background = element_rect(fill=NA,colour="grey50"),
        panel.spacing=unit(0,"cm"))

给出