Tiny functions shorter, and hopefully more explicit, than ifelse
.
ifsingle(x, yes, no)
ifunit(x, yes, no)
A vector (ifsingle
) or a numeric of length 1 (ifunit
).
Something of length 1. Result if the condition is fulfilled.
Something of length 1. Result if the condition is not fulfilled.
Returns something of length 1.
Yes, ifunit
is identical to ifelse(test == 1, yes, no)
. And regarding ifsingle
, it is identical to ifelse(length(test) == 1, yes, no)
.
Why writing these functions then? Actually, I've found that they make the code more explicit, and this helps!
ifunit()
: Conditional element selection depending on whether x
is equal to unity or not.
# Let's create an error message when NAs are present
my_crossprod = function(mat){
if(anyNA(mat)){
row_na = which(rowSums(is.na(mat)) > 0)
n_na = length(row_na)
stop("In argument 'mat': ", n_letter(n_na), " row", plural(n_na, "s.contain"),
" NA values (", ifelse(n_na<=3, "", "e.g. "), "row",
enumerate_items(head(row_na, 3), "s"), ").
Please remove ", ifunit(n_na, "it", "them"), " first.")
}
crossprod(mat)
}
mat = matrix(rnorm(30), 10, 3)
mat4 = mat1 = mat
mat4[c(1, 7, 13, 28)] = NA
mat1[7] = NA
# Error raised because of NA: informative (and nice) messages
try(my_crossprod(mat4))
#> Error in my_crossprod(mat4) :
#> In argument 'mat': four rows contain NA values (e.g. rows 1, 3 and 7).
#> Please remove them first.
try(my_crossprod(mat1))
#> Error in my_crossprod(mat1) :
#> In argument 'mat': one row contains NA values (row 7).
#> Please remove it first.