简短的问题,如果我有一个字符串,我该如何测试该字符串是否是一个有效的颜色表示R?
我尝试了两件事,首先使用函数col2rgb()来测试它是否是一种颜色:
isColor <- function(x)
{
res <- try(col2rgb(x),silent=TRUE)
return(!"try-error"%in%class(res))
}
> isColor("white")
[1] TRUE
> isColor("#000000")
[1] TRUE
> isColor("foo")
[1] FALSE
Run Code Online (Sandbox Code Playgroud)
工作,但看起来不是很漂亮,也没有矢量化.第二件事是检查字符串是否在colors()向量中,或者#后跟一个长度为4到6的十六进制数:
isColor2 <- function(x)
{
return(x%in%colors() | grepl("^#(\\d|[a-f]){6,8}$",x,ignore.case=TRUE))
}
> isColor2("white")
[1] TRUE
> isColor2("#000000")
[1] TRUE
> isColor2("foo")
[1] FALSE
Run Code Online (Sandbox Code Playgroud)
哪个有效但我不确定它有多稳定.但似乎应该有一个内置函数来进行此检查?
Jos*_*ien 19
你的第一个想法(col2rgb()用来测试颜色名称的有效性)对我来说似乎很好,只需要进行矢量化.至于它是否漂亮......很多/大多数R功能都不是特别漂亮"引擎盖下",这是创建一个功能的主要原因!从用户隐藏所有那些丑陋的内部.
一旦你在areColors()下面定义,使用它很容易,因为可以:
areColors <- function(x) {
sapply(x, function(X) {
tryCatch(is.matrix(col2rgb(X)),
error = function(e) FALSE)
})
}
areColors(c(NA, "black", "blackk", "1", "#00", "#000000"))
# <NA> black blackk 1 #00 #000000
# TRUE TRUE FALSE TRUE FALSE TRUE
Run Code Online (Sandbox Code Playgroud)
?par 给出了在R中指定颜色的方式的详尽描述.任何有效颜色的解决方案都必须考虑:
colors()"#RRGGBBAA指定红色,绿色,蓝色和alpha通道的形式.Alpha通道用于透明,并非所有设备都支持,因此虽然以这种方式指定颜色有8个十六进制值是有效的,但它可能在特定设备上无效.NA是一种有效的"颜色".它意味着透明,但就R而言,它是一种有效的颜色表示."transparent"也是有效的,但不是colors(),因此也需要处理1是一种有效的颜色表示,因为它是由返回的小颜色调色板中的颜色的索引palette()
> palette()
[1] "black" "red" "green3" "blue" "cyan" "magenta" "yellow"
[8] "gray"
Run Code Online (Sandbox Code Playgroud)
因此你需要应付1:8.为什么这很重要,?par告诉我们将这些颜色的索引表示为字符也是有效的,因此您需要捕获"1"为有效的颜色表示.但是(正如@hadley在评论中所指出的)这仅适用于默认调色板.用户可以使用另一个调色板,在这种情况下,您必须考虑到您的R版本的最大允许长度的矢量元素的字符索引.
一旦你处理了所有这些你应该很好去;-)
据我所知,没有一个用户可见的功能可以做到这一点.所有这些都埋在C代码中进行绘图; 很快你就会在.Internal(....)陆地上结束并且有龙!
[迂腐#000000 不是 R中的颜色名称 ]
R知道的唯一颜色名称是返回的颜色名称colors().是的,#000000是R理解的颜色表示之一,但您明确询问了一个名称,而最终列表或解决方案x %in% colors()就像您在第二个示例中所做的那样.
这几乎和它一样稳定.当您使用类似的颜色时col = "goldenrod",内部R将其与您正在绘制的任何设备的"正确"颜色表示相匹配.color()返回R可以执行此操作的颜色名称列表.如果它不在colors()那时它不是颜色名称.