17 Case study: rgb()
Interface:
- Function name and argument names.
-
alpha
has no default but isn’t required. -
names
not required (imo). -
maxColorValue
doens’t have most useful default, and not really needed (imo). - Data frame rather than matrix.
- Error if function specification is correct
- Check for data type, not missingness.
library(rlang)
rgba <- function(r, g, b, a = NULL) {
if (is.data.frame(r)) {
df <- r
if (!ncol(df) %in% c(3L, 4L)) {
abort("If `r` is data frame, it must have 3 or 4 columns.")
}
if (!missing(b) || !missing(g) || !missing(a)) {
abort("If `r` is a data frame, `b`, `g`, and `a` must not be set.")
}
r <- df[[1L]]
g <- df[[2L]]
b <- df[[3L]]
if (ncol(df) == 4) {
a <- df[[4L]]
}
}
rgb(r, g, b, alpha = a, maxColorValue = 255)
}
rgba(16, 16, 16)
#> [1] "#101010"
rgba(data.frame(16, 16, 16))
#> [1] "#101010"
rgba(data.frame(16, 16))
#> Error in `rgba()`:
#> ! If `r` is data frame, it must have 3 or 4 columns.
rgba(data.frame(16, 16, 16), 1)
#> Error in `rgba()`:
#> ! If `r` is a data frame, `b`, `g`, and `a` must not be set.
rgba <- function(r, g, b, a = NULL) {
if (is.data.frame(r)) {
df <- r
if (!all(c("r", "g", "b")) %in% names(df)) {
abort("If first argument is a data frame, it must have r, g, and b columns.")
}
if (!missing(b) || !missing(g) || !missing(a)) {
abort("If `r` is a data frame, `b`, `g`, and `a` must not be set.")
}
} else {
# Handles vectorisation
df <- tibble(r = r, g = g, b = b, a = a)
}
# Assumes this function checks types and gives informative error messages
rgb(df$r, df$g, df$b, alpha = df$a, maxColorValue = 255)
}