如何从单个数据帧中制作一个在每个方面重复一些线条的方面图?

问题描述 投票:0回答:1

我正在尝试使用 data.table 创建分面图。理想情况下,我想添加每个方面的最大和最小可接受值,以便更容易比较。它们都在同一个 data.table 中。 它们也不应该有自己的方面,因为它们是参考值。

环顾四周后,我发现有人建议将线条添加到每个方面,但我似乎无法使其发挥作用。这些限制有其自己的方面,并且不会出现在其余方面。与我的初衷完全相反!

library(ggplot2)

x_values <- rep(1:20, 5)
y_values <- runif(1:100)
class_labels <- rep(c("A", "B", "C", "UpperLimit", "LowerLimit"), times = c(20,20,20, 20,20 ))

# Combine into a data frame
dt <- data.table(X = x_values, Y = y_values, Class = class_labels)
dt[class_labels == "UpperLimit", Y := Y * 2]
dt[class_labels == "LowerLimits", Y := Y *-1]

# Print the resulting datatable
p <- ggplot(data = dt[class_labels != c("UpperLimits", "LowerLimits") ], aes(X,Y)) + 
  geom_line() + facet_wrap(~(class_labels)) + 
  geom_line(data = dt[class_labels == "UpperLimits"]) + aes(x = X, y = Y) +
  geom_line(data = dt[class_labels == "LowerLimits"]) + aes(x = X, y = Y)

这就是我得到的:

r ggplot2 facet facet-wrap
1个回答
1
投票

首先,在回答最初的问题之前我们应该澄清一些事情。

  1. 使用

    class_labels
    (不在框架中)作为过滤向量和分面并不是好的做法,特别是因为数据中有
    Class
    。虽然也有例外,但我几乎“总是”将绘图所需的变量放入数据本身中。在这种情况下,请将绘图代码中所有 class_labels 实例替换为
    Class
    
    

  2. c("UpperLimits", "LowerLimits")

    不存在,应该是

    c("UpperLimit", "LowerLimit")
    
    

  3. dt[class_labels != c("UpperLimits", "LowerLimits"),]

    中,

    !=
    (以及
    ==
    <
    等)
    必须
    是彼此的干净倍数,但实际上它们应该的长度为1或相同长度与另一个相同。有一些巧妙的技巧使用不匹配的向量长度,其中一些很有用,但在大多数情况下(根据我的经验),当比较两个不同长度的向量时,如果一个比另一个短并且长度不是1,那么它是一个错误。如果幸运的话,它会触发警告/错误;如果你不这样做(如本例所示),R 将默默地、草率地回收你的 length-2 向量。在这种情况下,您正在有效地进行比较 class_labels != c("UpperLimits", "LowerLimits", "UpperLimits", "LowerLimits", "UpperLimits", "LowerLimits", "UpperLimits", "LowerLimits", ...) ### out to length 100, which is length(class_labels)

    我认为回收的无意影响在那里应该更明显。

    这应该是

    !Class %in% c(..)

    。请参阅

    `%in%` 和 `==` 之间有什么区别?
    R 中 == 和 %in% 运算符之间的区别在 dplyr 中过滤字符串列上的多个值

  4. 综上所述,要在所有方面叠加这两个限制,有几种选择。

    使用
  1. annotate

    ggplot(data = dt[!Class %in% c("UpperLimit", "LowerLimit") ], aes(X,Y)) + 
      geom_line() + 
      facet_wrap(~ Class) + 
      annotate(geom = "line", x = dt[Class == "UpperLimit", X], y = dt[Class == "UpperLimit", Y], color = "red", linetype = "dashed") + 
      annotate(geom = "line", x = dt[Class == "LowerLimit", X], y = dt[Class == "LowerLimit", Y], color = "green", linetype = "dashed")
    

  2. 对所有三个
  3. Class

    施加上限/下限。 (还需要做一些工作,但会展示如何将限制复制到面的

    some
    中,如果需要的话。)我将保留原始的Class,以便我们可以
    aes
    将其与之前的图相匹配(我手动分配了
    color=
    linetype=
    )。
    ggplot(data = dt[!Class %in% c("UpperLimit", "LowerLimit") ], aes(X,Y)) + 
      geom_line() + 
      facet_wrap(~ Class) + 
      geom_line(data = dt_limits, aes(color = FakeClass), linetype = "dashed") + 
      scale_color_manual(values = c("UpperLimit" = "red", "LowerLimit" = "green"))
    

    我将图例保留在那里,如果需要,您可以使用

    + guides(color = "none")

    将其删除。 (我认为没有一种简单的方法可以在使用

    annotate(.)
    制作的第一个图上获取图例,以防这对您很重要。)
    
    

© www.soinside.com 2019 - 2024. All rights reserved.