"错误:美学必须是长度1或与数据相同"为什么呢?

时间:2017-03-28 13:29:43

标签: r ggplot2 time-series timeserieschart

Wickham(2009:164-6)给出了同时绘制多个时间序列的示例。以下代码复制了他的示例:

  range01 <- function(x) {
      rng <- range(x, na.rm = TRUE)
      (x - rng[1])/diff(rng)
  }

  emp <- subset(economics_long, variable %in% c("uempmed", "unemploy"))
  emp2 <- ddply(emp, .(variable), transform, value = range01(value))
  qplot(date, value, data = emp2, geom = "line", color = variable, linetype =     variable)
  # Produces a plot that looks like the one on p. 166 of the ggplot2 book.

此处,range01用于将变量重新编码为[0,1]内的值,因此可以在相同的比例上绘制具有不同数量级的序列。 Wickham的原文也从ggplot2提供的employment数据开始,并将其融合成长格式,但在这里我采用了以employment_long版本开头的快捷方式。

但威克姆(第27页)也指出,利用全面的力量&#34; ggplot2需要使用 ggplot()函数按层手动构建绘图。这是他的例子,但是使用 ggplot()而不是 qplot()

# Now do the same thing using ggplot commands only
ggplot(data = emp2, aes(x = date)) +
  geom_line(aes(y = value, group = variable, color = variable, linetype = variable))
# Get the same results

这两个示例都利用了 ggplot2 的默认设置。但是假设我们想要更好地控制美学。也许一些变量适合于特定的配色方案(例如,绿色可能用于环保变量,黑色用于有害颜色);或许在一本有很多情节的长篇专着中,我们只想确保一致性。此外,如果图表将在演示文稿和打印的黑白文本中使用,我们可能还希望将特定行类型与特定系列相关联;如果我们关注有色盲的观众,情况也可能如此。最后,变量名称通常是变量实际上的描述不佳,因此我们希望将变量标签与各个时间序列相关联。

因此,我们为经济学数据集定义以下内容:

# Try to control the look a bit more
economics_colors = c("pce" = "red", "pop" = "orange", "psavert" = "yellow",
    "uempmed" = "green", "unemploy" = "blue")
economics_linetypes = c("pce" = "solid", "pop" = "dashed", "psavert" = "dotted",
    "uempmed" = "dotdash", "unemploy" = "longdash")
economics_labels = c(
    "pce" = "Personal consumption expenditures",
    "pop" = "Total population",
    "psavert" = "Personal savings rate",
    "uempmed" = "Median duration of unemployment",
    "unemploy" = "Number of unemployed"
)

现在通过为每个变量添加单独的图层(Wickham 2009:164-5)来构建图:

# First do it line-by-line
employment.plot <- ggplot(emp2) + aes(x = date)  +
  scale_linetype_manual(values = economics_linetypes, labels = economics_labels)
employment.plot <- employment.plot +
  geom_line(data = subset(emp2, variable == "uempmed"),
      aes(y = value, linetype = "uempmed"), color = economics_colors["uempmed"])
employment.plot <- employment.plot +
  geom_line(data = subset(emp2, variable == "unemploy"),
            aes(x = date, y = value, linetype = "unemploy"), color = economics_colors["unemploy"])
employment.plot
# Except for the specific line colors, produces the same plot as before.

请注意这里的两件事。首先,线条类型映射,但颜色设置(参见Wickham 2009:47-49)。这会产生单个图例的所需结果,每个系列都有不同的颜色 - 线型组合。

其次,即使数据是在&#34; long&#34;格式,我们使用子集来选择单个系列。这不是最好的解决方案。正如威克姆(164-5)所说:

  

...更好的选择是将数据融合成长格式   然后想象一下。在熔融数据中,时间序列有它们的   值存储在变量中,我们可以区分   它们带有变量变量。

所以让我们尝试这种方法:

# Now try it the automatic way
employment.plot <- ggplot(data = emp2, aes(x = date))  +
  scale_linetype_manual(values = economics_linetypes, labels = economics_labels)
employment.plot <- employment.plot +
  geom_line(aes(y = value, group = variable, linetype = economics_linetypes), color = economics_colors)
employment.plot
# Throws "Error: Aesthetics must be either length 1 or the same as the data (1148) ..."

如评论所示,此代码会引发有关美学的错误。为什么呢?

此外,还有另一种方法可以实现使用融合数据的多个目标,其中单个变量变量触发单独的行,控制哪些颜色和线类型与每个系列相关联,并使用代码在多个图中标准化这些约定?

参考

威克姆,哈德利。 2009. ggplot2:用于数据分析的优雅图形。斯普林格。

1 个答案:

答案 0 :(得分:2)

美学应始终映射到数据集的维度。

您在最后一个命令中说的是:&#34;对于每个数据点&#39; (或在这种情况下为组)指定一个等于其class ProfileStatus(models.Model): """ table of available titles for users """ status = models.CharField(max_length=100) def __str__(self): return self.status class Profile(models.Model): """ add a title to an existing user """ user = models.OneToOneField(User, on_delete=models.CASCADE) title = models.ForeignKey(ProfileStatus, on_delete=models.CASCADE) class OpportunityStatus(models.Model): """ status for an opportunity """ status = models.CharField(max_length=100) def __str__(self): return self.status class Opportunity(models.Model): """ An opportunity """ name = models.CharField(max_length=100, default='') director = models.ForeignKey(User, on_delete=models.CASCADE) status = models.ForeignKey(OpportunityStatus, on_delete=models.CASCADE) def __str__(self): return self.name 的线型。&#34;

但是还没有关于如何将每个记录(组)映射到economics_linetypes中的任何值的信息。所以它正确地返回错误。

您应该做的是将economics_linetypes映射到控制它的维度。即:&#34;对于此维度中的每个值,使用不同的linetype&#34;即:

linetype

一旦我们有了这个定义,我们就可以使用比例的定义将变量的值映射到特定的geom_line(aes(y = value, group = variable, linetype = variable)

linetype

当然,所有这些都适用于颜色,所以最后我们有:

scale_linetype_manual(values = economics_linetypes, labels = economics_labels)

enter image description here

希望这很清楚。