当我添加手动秤(如以下示例)时。我收到以下错误消息:
“警告消息: 如果if(self $ guide ==“ none”)return(): 条件的长度> 1,并且仅使用第一个元素”
什么是导致此错误消息的原因,我该如何解决?
非常感谢您的帮助!
d <- data.frame(week = seq(1, 52, 1),
revenue = round(runif(52, 0, 100)), 0)
p <- ggplot(data = d, aes(x = week, y = revenue, fill = 'lightskyblue')) +
geom_bar(stat = 'identity', colour = 'black')
p <- p + scale_fill_identity(name = NULL,
guide = guide_legend(label.position = 'top'),
labels = c('2019'))
p
答案 0 :(得分:5)
为独立的MCVE投票,尽管我想强调的是,您收到了警告消息,而不是错误。在这种情况下,您不需要修复任何问题。您可以忽略该消息,因为代码可以按预期正常工作。
正如@ r2evans所指出的,这是由于scale_*_identity
代码[found here]引起的。如?scale_fill_identity
中所述,这些标尺默认情况下不会产生图例,尽管您可以用其他类型的指南代替guide = "none"
参数来覆盖它。
应该如何工作:
此图例创建行为在train
/ ScaleDiscreteIdentity
的{{1}}函数中进行了编码,该函数检查引导参数的值是否为“ none”。如果是这样,则不创建图例。否则,请使用ScaleContinuousIdentity
/ train
中的ScaleDiscrete
函数来创建适当的图例:
ScaleContinuous
ScaleDiscreteIdentity <- ggproto("ScaleDiscreteIdentity", ScaleDiscrete,
...,
train = function(self, x) {
# do nothing if no guide, otherwise train so we know what breaks to use
if (self$guide == "none") return()
ggproto_parent(ScaleDiscrete, self)$train(x)
}
)
ScaleContinuousIdentity <- ggproto("ScaleContinuousIdentity", ScaleContinuous,
...,
train = function(self, x) {
# do nothing if no guide, otherwise train so we know what breaks to use
if (self$guide == "none") return()
ggproto_parent(ScaleContinuous, self)$train(x)
}
)
中的示例表明可以使用?scale_fill_identity
代替guide = "legend"
。实际上,也可以使用guide = "none"
。实际上,guide = guide_legend(...)
指出:
?guides
中的
guide = "legend"
是scale_*
的语法糖
它的实际工作方式(至少基于我当前的版本3.1.0):
对于guide = guide_legend()
,在scale_*_identity
和guide = "legend"
之间有 细微的区别。我修剪了MCVE以说明要点:
guide = guide_legend(...)
p1和p2都产生相同的图例,但p1会触发警告,而p2则不会。 (当然,p3使用默认选项,并且不会触发警告。)产生这种差异的原因在于它们的填充比例,可以在p <- ggplot(data = d,
aes(x = week, y = revenue, fill = 'lightskyblue')) +
geom_col()
p1 <- p + scale_fill_identity(guide = guide_legend())
p2 <- p + scale_fill_identity(guide = "legend")
p3 <- p + scale_fill_identity(guide = "none")
中找到:
p<1/2/3>$scales$scales[[1]]
> p1$scales$scales[[1]]$guide
$`title`
list()
attr(,"class")
[1] "waiver"
$title.position
NULL
$title.theme
NULL
... #omitted for space. it goes on for a while
> p2$scales$scales[[1]]$guide
[1] "legend"
> p3$scales$scales[[1]]$guide
[1] "none"
有21个项目,而p1$scales$scales[[1]]$guide
和p2$scales$scales[[1]]$guide
都包含一个字符串。这样,当p3$scales$scales[[1]]$guide
函数检查train
时,p1返回TRUE / FALSE值的列表,每一项对应一个,而p2和p3返回单个TRUE / FALSE。
self$guide == "none"
由于> p1$scales$scales[[1]]$guide == "none"
title title.position title.theme title.hjust title.vjust label
FALSE FALSE FALSE FALSE FALSE FALSE
label.position label.theme label.hjust label.vjust keywidth keyheight
FALSE FALSE FALSE FALSE FALSE FALSE
direction override.aes nrow ncol byrow reverse
FALSE FALSE FALSE FALSE FALSE FALSE
order available_aes name
FALSE FALSE FALSE
> p2$scales$scales[[1]]$guide == "none"
[1] FALSE
> p3$scales$scales[[1]]$guide == "none"
[1] TRUE
函数只希望从其train
检查中返回一个值,因此p1会触发条件长度> 1的警告消息。
重要吗:
不是。当面对来自p1的21个TRUE / FALSE值列表时,self$guide == "none"
函数仅查看第一个-FALSE,因为train
的默认值为p1$scales$scales[[1]]$guide$title
。因此,p1的waiver()
的检出方式与p2的guide = guide_legend()
相同。您可以忽略警告并继续。
...只是不要在guide = "legend"
中将图例标题命名为“ none”:
guide_legend
还是应该解决:
是的,尽管我会说这不是一个严重的错误,因为代码通常表现为预期的行为(上述p4是一种附带情况)。
我想无论如何修复应该很简单,例如:
p4 <- p + scale_fill_identity(guide = guide_legend(title = "none"))
# this will cause the legend to disappear, because the first value in
# p4$scales$scales[[1]]$guide == "none" will actually be TRUE
答案 1 :(得分:2)
answer by Z.lin很好地解决了这里出了什么问题。这确实是ggplot2中的错误。但是,我想借此机会指出您的代码是向后的。通常,您不应该将指南与scale_*_identity()
一起使用,因为身份标度采用数据值并按原样显示它们(即,无需在指南中显示映射)。因此,这些秤并不意味着具有传奇色彩。
如果要手动设置颜色元素,则在美学映射中,应使用所表示的数据值(此处为fill = '2019'
),然后使用scale_fill_manual()
将数据值映射为颜色。请注意,在这种情况下不会发出警告,因为scale_*_manual()
已使用不同的指南代码进行了广泛的测试,而scale_*_identity()
尚未经过测试。
library(ggplot2)
d <- data.frame(week = seq(1, 52, 1),
revenue = round(runif(52, 0, 100)), 0)
ggplot(data = d, aes(x = week, y = revenue, fill = '2019')) +
geom_bar(stat = 'identity', colour = 'black') +
scale_fill_manual(
values = c(`2019` = 'lightskyblue'),
name = NULL,
guide = guide_legend(label.position = 'top')
)
由reprex package(v0.2.1)于2019-02-11创建