我正在尝试使用 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)
首先,在回答最初的问题之前我们应该澄清一些事情。
使用
class_labels
(不在框架中)作为过滤向量和分面并不是好的做法,特别是因为数据中有Class
。虽然也有例外,但我几乎“总是”将绘图所需的变量放入数据本身中。在这种情况下,请将绘图代码中所有 class_labels
实例替换为 Class
。
c("UpperLimits", "LowerLimits")
不存在,应该是
c("UpperLimit", "LowerLimit")
。
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 中过滤字符串列上的多个值。
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")
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(.)
制作的第一个图上获取图例,以防这对您很重要。)