Check if character string is a valid color representation

后端 未结 2 1005
终归单人心
终归单人心 2021-02-03 19:16

Short question, if I have a string, how can I test if that string is a valid color representation in R?

Two things I tried, first uses the function co

相关标签:
2条回答
  • 2021-02-03 20:04

    Your first idea (using col2rgb() to test color names' validity for you) seems good to me, and just needs to be vectorized. As for whether it seems pretty or not ... lots/most R functions aren't particularly pretty "under the hood", which is a major reason to create a function in the first place! Hides all those ugly internals from the user.

    Once you've defined areColors() below, using it is easy as can be:

    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 
    
    0 讨论(0)
  • 2021-02-03 20:07

    Update, given the edit

    ?par gives a thorough description of the ways in which colours can be specified in R. Any solution to a valid colour must consider:

    1. A named colour as listed in colors()
    2. A hexademical representation, as a character, of the form "#RRGGBBAA specifying the red, green, blue and alpha channels. The Alpha channel is for transparency, which not all devices support and hence whilst it is valid to specify a colour in this way with 8 hex values it may not be valid on a specific device.
    3. NA is a valid "colour". It means transparent, but as far as R is concerned it is a valid colour representation.
    4. Likewise "transparent" is also valid, but not in colors(), so that needs to be handled as well
    5. 1 is a valid colour representation as it is the index of a colour in a small palette of colours as returned by palette()

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

      Hence you need to cope with 1:8. Why is this important, well ?par tells us that it is also valid to represent the index for these colours as a character hence you need to capture "1" as a valid colour representation. However (as noted by @hadley in the comments) this is just for the default palette. Another palette may be used by a user, in which case you will have to consider a character index to an element of a vector of the maximum allowed length for your version of R.

    Once you've handled all those you should be good to go ;-)

    To the best of my knowledge there isn't a user-visible function that does this. All of this in buried away inside the C code that does the plotting; very quickly you end up in .Internal(....) land and there be dragons!


    Original

    [To be pedantic #000000 isn't a colour name in R.]

    The only colour names R knows are those returned by colors(). Yes, #000000 is one of the colour representations that R understands but you specifically ask about a name and the definitive list or solution is x %in% colors() as you have in your second example.

    This is about as stable as it gets. When you use a colour like col = "goldenrod", internally R matches this with a "proper" representation of the colour for whichever device you are plotting on. color() returns the list of colour names that R can do this looking up for. If it isn't in colors() then it isn't a colour name.

    0 讨论(0)
提交回复
热议问题