当我添加手动比例时,如下例所示.我收到以下错误消息:
"警告消息:在if(self $ guide =="none")中返回():条件的长度> 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
Run Code Online (Sandbox Code Playgroud)
为一个独立的MCVE投票,但我想强调你有一个警告信息,而不是错误.在这种特殊情况下,您无需修复任何内容.您可以忽略该消息,因为代码完全按预期工作.
正如@ r2evans所说,这是由于scale_*_identity代码[在这里找到].如上所述?scale_fill_identity,默认情况下,这些比例不会生成图例,但您可以通过将guide = "none"参数替换为其他类型的参考来覆盖它.
它应该如何工作:
此图例创建行为在/ 的train函数中编码,它检查指南参数的值是否为"无".如果是这样,则不创建图例.否则,使用/中的函数创建相应的图例:ScaleDiscreteIdentityScaleContinuousIdentitytrainScaleDiscreteScaleContinuous
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)
}
)
Run Code Online (Sandbox Code Playgroud)
示例?scale_fill_identity表明guide = "legend"可以代替使用guide = "none".在实践中,guide = guide_legend(...)也可以使用.事实上,?guides各州:
guide = "legend"inscale_*是语法糖guide = guide_legend()
它是如何工作的(至少基于我当前的版本3.1.0):
对于scale_*_identity有是之间存在微妙的差异guide = "legend"和guide = guide_legend(...).我已经削减了MCVE来说明这一点:
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")
Run Code Online (Sandbox Code Playgroud)
p1和p2都会产生相同的图例,但p1会触发警告,而p2则不会.(当然,p3使用默认选项并且不会触发警告.)这种差异的原因在于它们的填充比例,可以在以下位置找到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"
Run Code Online (Sandbox Code Playgroud)
p1$scales$scales[[1]]$guide有21个项,而p2$scales$scales[[1]]$guide与p3$scales$scales[[1]]$guide每一个字符串的包含.因此,当train函数检查时self$guide == "none",p1返回一个TRUE/FALSE值列表,每个项目一个,而p2和p3返回单个TRUE/FALSE.
> 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
Run Code Online (Sandbox Code Playgroud)
由于train函数只需要从其self$guide == "none"检查返回单个值,因此p1会触发条件长度> 1的警告消息.
这有关系:
并不是的.当面对来自p1的21个TRUE/FALSE值的列表时,该train函数仅查看第一个值 - 由于p1$scales$scales[[1]]$guide$title默认值为0 ,因此为FALSE waiver().因此p1的guide = guide_legend()检查方式与p2相同guide = "legend".您可以忽略该警告并继续.
...只是不要将你的传奇标题命名为"无" guide_legend:
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
Run Code Online (Sandbox Code Playgroud)
无论如何应该解决:
是的,虽然我说这不是一个关键的错误,因为代码通常表现得像预期的那样(上面的p4是一个边缘情况).
无论如何,我认为修复应该非常简单,例如:
# this
if (all(self$guide == "none")) return()
# instead of this
if (self$guide == "none") return()
Run Code Online (Sandbox Code Playgroud)