Проверьте, является ли символьная строка допустимым цветовым представлением

Короткий вопрос, если у меня есть строка, как я могу проверить, является ли эта строка допустимым цветовым представлением в 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

Работает, но не кажется очень красивым и не векторизован. Во-вторых, нужно просто проверить, есть ли строка в vector 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

Что работает, хотя я не уверен, насколько он стабилен. Но кажется, что для выполнения этой проверки должна быть встроенная функция?

Ответ 1

Ваша первая идея (с использованием col2rgb() для проверки 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 

Ответ 2

Обновление, с учетом редактирования

?par дает подробное описание способов, в которых цвета могут быть указаны в R. Любое решение для допустимого цвета должно учитывать:

  1. Именованный цвет, указанный в colors()
  2. Гессемическое представление, как символ, формы "#RRGGBBAA указывающей красный, зеленый, синий и альфа-каналы. Альфа-канал предназначен для прозрачности, который не все устройства поддерживают и, следовательно, пока он действителен, чтобы указать цвет таким образом с 8 шестнадцатеричными значениями он может быть недействительным на конкретном устройстве.
  3. NA - действительный "цвет". Это означает прозрачность, но, насколько это касается R, это допустимое цветовое представление.
  4. Точно так же "transparent" также действителен, но не в colors(), поэтому его нужно также обрабатывать
  5. 1 является допустимым цветовым представлением, так как оно является индексом цвета в маленькой палитре цветов, возвращаемой palette()

    > palette()
    [1] "black"   "red"     "green3"  "blue"    "cyan"    "magenta" "yellow" 
    [8] "gray"
    

    Следовательно, вам нужно справиться с 1:8. Почему это важно, хорошо ?par говорит нам, что также верно представлять индекс для этих цветов как символ, поэтому вам нужно зафиксировать "1" в качестве допустимого цветового представления. Однако (как заметил @hadley в комментариях) это только для палитры по умолчанию. Другая палитра может использоваться пользователем, и в этом случае вам придется рассмотреть индекс символа для элемента вектора максимально допустимой длины для вашей версии R.

После того, как вы обработали все эти вещи, вам должно быть хорошо идти ;-)

Насколько мне известно, не существует видимой пользователем функции, которая делает это. Все это скрывается внутри кода C, который выполняет построение графика; очень быстро вы .Internal(....) земля и там есть драконы!


оригинал

[Быть педантичным #000000 не является именем цвета в R.]

Единственными именами цветов R являются те, которые возвращаются colors(). Да, #000000 - это одно из цветовых представлений, которое понимает R, но вы конкретно спрашиваете о имени, а окончательный список или решение - это x %in% colors() как у вас во втором примере.

Это примерно так же стабильно, как и получается. Когда вы используете цвет, например col = "goldenrod", внутренне R соответствует этому "правильному" представлению цвета для любого устройства, на котором вы рисуете. color() возвращает список названий цветов, которые R может сделать для этого поиска. Если это не в colors() это не имя цвета.