R ggplot:如何使用facetted ggplots定义依赖于组的y轴断点?

时间:2017-02-02 18:32:02

标签: r ggplot2

我有40个组(由short_ID定义),并希望生成40个不同的图,每个short_ID使用不同的y刻度中断。我希望y-scale的中断为(1)mean-2SD,(2)mean和(3)mean + 2SD。

我有一个名为Dataplots的数据集,其中包含我的X和Y变量以及分组变量“short_ID”。我创建了额外的向量M $ SD11(= mean-2SD),M $ mean和M $ SD22(= mean + 2SD)来定义中断并将M $ short_ID定义为分组变量。下面的代码部分有效,但问题是我不知道如何使断点组依赖(即依赖于short_ID)。当我运行下面的代码时,我得到所有图的相同y轴断点,即例如矢量M $ SD22的最大值,而不是每个图的不同M $ SD22值。所以我想我需要添加一些内容

"scale_y_continuous(breaks=c(M$SD11, M$mean, M$SD22)", for example "scale_y_continuous(group=M$short_ID, breaks=c(M$SD11, M$mean, M$SD22)" but this does not work.         

有谁知道我可以做些什么来为我的不同组定义不同的中断(即short_IDs)?如何更改以下代码才能执行此操作?非常感谢!

Dataplot <- ggplot(data = Dataplots, aes(x = Measure, y = Amylase_u, group = short_ID)) + geom_line() + facet_wrap(~ short_ID) +  scale_y_continuous(breaks=c(M$SD11, M$mean, M$SD22))

我添加了一个'Dataplots'和'M'的例子。出于示例的目的,我仅包括两个组(即,short_ID)而不是实际上具有的40个组。因此,该示例需要产生2个图,每个short_ID一个,每个组具有不同的y轴断点。

Dataplots示例:

dput(Dataplots) structure(list(short_ID = c(1111, 1111, 1111, 1111, 2222, 2222, 2222, 2222), Measure = c(1, 2, 3, 4, 1, 2, 3, 4), Amylase_u = c(81.561, 75.648, 145.25, 85.246, 311.69, 261.74, 600.93, 291.39)), .Names = c("short_ID", "Measure", "Amylase_u"), row.names = c(NA, -8L), class = "data.frame", codepage = 65001L)

M的例子:

dput(M) structure(list(SD11 = c(162, 682), mean = c(97, 366), SD22 = c(32, 51), short_ID = c(1111, 2222)), .Names = c("SD11", "mean", "SD22", "short_ID"), row.names = 1:2, class = "data.frame")

@Mark我一直在尝试将您的建议应用到我的完整数据集中,但似乎无法做到正确。我共有61个地块。我开始时:

myPlots <-
lapply(unique(Dataplots$short_ID), function(thisID){
Dataplots %>%
  filter(short_ID == thisID) %>%
  ggplot(aes(x = Measure, y = Amylase_u)) +
  geom_line() +
  scale_y_continuous(breaks= M %>%
                       filter(short_ID == thisID) %>%
                       select(mean) %>%
                       as.numeric()
  ) +
  ggtitle(thisID)
 })

(正如你所看到的那样,我决定只在Y轴上选择主题,并决定放弃SD。)然后我继续你最后的牛皮画消息:

plot_grid(ggdraw() + draw_label("Amylase_u", angle = 90), plot_grid(
plot_grid(plotlist = lapply(myPlots, function(x){x + theme(axis.title = element_blank())}))
, ggdraw() + draw_label("Measurement")
, ncol = 1
, rel_heights = c(0.9, .1))
, nrow = 1, rel_widths =  c(0.05, 0.95))

然而,这会产生61个图,其中y轴上的主题均值,但没有在其中指定测量值(因此图表本身缺失)。我想可能有一个')'错位,所以我尝试了:

plot_grid(
ggdraw() + draw_label("Amylase_u", angle = 90)
, plot_grid(
plot_grid(plotlist = lapply(myPlots, function(x){x +theme(axis.title = element_blank())}))
, ggdraw() + draw_label("Measurement")
, ncol = 1
, rel_heights = c(0.9, .1)
, nrow = 1
, rel_widths =  c(0.05, 0.95)))

这确实给了我图表,但它们很小,布局很糟糕(Rplot2)。我也尝试过调整相对高度和宽度,但即使在阅读了帮助文件之后也不太了解我应该如何调整它们。

再次感谢!

Rplot2

最后,我删除了每个绘图顶部的IDnumbers,因为它们并不是必需的,这已经大大改善了绘图(Rplot3),但仍然需要调整布局。

Rplot3

1 个答案:

答案 0 :(得分:1)

我的理解是facet函数仍然无法实现这一点。但是,您可以使用cowplot包自己完成它。

首先,循环你的想法(在lapply中)并生成你想要的每个子图。请注意,我使用dplyr进行管道和过滤。

myPlots <-
  lapply(unique(Dataplots$short_ID), function(thisID){
    Dataplots %>%
      filter(short_ID == thisID) %>%
      ggplot(aes(x = Measure, y = Amylase_u)) +
      geom_line() +
      scale_y_continuous(breaks= M %>%
                           filter(short_ID == thisID) %>%
                           select(SD11, mean, SD22) %>%
                           as.numeric()
                         ) +
      ggtitle(thisID)
  })

然后,使用图表列表从plot_grid调用函数cowplot

plot_grid(plotlist = myPlots)

给出:

enter image description here

一些注意事项:

  • cowplot自动加载其自己的默认样式,因此请使用theme_set返回您的首选样式
  • 您所包含的数据似乎并未实际涵盖您为y轴中断所提供的所有阈值
  • 这应适用于任意大量的子图,但您可能需要/需要调整标签和对齐以使其可读。

由于我不确定你的目标是什么,这是另一种选择。如果您只想绘制偏离平均值(在标准偏差中)以使更改具有可比性,您可以只计算组内列的z分数并绘制结果。再次使用dplyr

Dataplots %>%
  group_by(short_ID) %>%
  mutate(scaledAmylase = as.numeric(scale(Amylase_u)) ) %>%
  ggplot(aes(x = Measure
             , y = scaledAmylase)) +
  geom_line() +
  facet_wrap(~short_ID)

给出

enter image description here

或者,如果在其他地方计算/定义平均值/ SD(并存储在M中)而不是直接来自数据,则可以使用M而不是数据进行扩展:

Dataplots %>%
  left_join(M) %>%
  mutate(scaledAmylase = (Amylase_u - mean) / ((SD22 - mean) / 2) ) %>%
  ggplot(aes(x = Measure
             , y = scaledAmylase)) +
  geom_line() +
  facet_wrap(~short_ID)

给出

enter image description here

而且,因为我不能单独留下,所以这里是plot_grid方法的一个版本,它删除了重复的轴标题,只包括它们一次(如facet_wrap会) 。如上所述,增加子图的数量或纵横比将迫使您在此处调整相对值:

plot_grid(
  ggdraw() + draw_label("Amylase_u", angle = 90)
  , plot_grid(
    plot_grid(plotlist = lapply(myPlots, function(x){x + theme(axis.title = element_blank())}))
    , ggdraw() + draw_label("Measurement")
    , ncol = 1
    , rel_heights = c(0.9, .1))
  , nrow = 1
  , rel_widths =  c(0.05, 0.95)
 )

给出

enter image description here