Get appropriate numeric transformation function

get_numeric_transform(transform, ...)

Arguments

transform

character string or function, or list that may contain character string or function.

...

additional arguments are ignored.

Value

function or NULL when no matching function is found, or list is returned when the input transform

has multiple values.

Details

This function recognizes numeric transformation functions by name, or searches the attached R package environments for a matching function by name.

Recognized transform names:

  • "none" or "linear" returns the data without change

  • "log2signed" applies jamba::log2signed(), defined as log2(1+x) transform to the absolute value, then multiplies by the original sign(x)

  • "exp2signed" applies the inverse of "log2signed", which exponentiates numeric values which were previously transformed with log2(1+x). Note that value=0 when exponentiated becomes +1

  • "sqrt" applies square root transform, equivalent to sqrt()

  • "cubert" applies cube root x^(1/3)

  • "qrt" applies fourth root x^(1/4)

  • "frt" or "fthrt" applies fifth root x^(1/5)

  • "square" applies x^2 to absolute value, multiplied by the sign(x)

  • "cube" applies x^3;

Any other character name is used to find a function with the same name, and if the function is found it is used. The function is expected to take input x and return corresponding output with the same length as the input. A function such as max() does not fit this criteria, but a function such as log2() is acceptable.

Examples

get_numeric_transform("log2signed")
#> function
#> (x,
#>  offset=1,
#>  base=2,
#>  ...)
#> {
#>    ## Purpose is to transform numeric data using log2 transformation
#>    ## but where negative values are kept negative by log2-transforming
#>    ## the absolute value, then multiplying by the original sign.
#>    if (length(x) == 0) {
#>       return(x);
#>    }
#>    if (offset < 1 && any(abs(x) < 1)) {
#>       stop(
#>          paste0(
#>             "Values in abs(x) less than offset ",
#>             offset,
#>             " cannot be transformed without losing direction.")
#>       );
#>    }
#> 
#>    ## Determine the sign(x)
#>    x_sign <- sign(x);
#>    ## For now, do not convert sign 0 to sign 1.
#>    #x_sign <- ifelse(x_sign == 0, 1, x_sign);
#> 
#>    if (length(base) == 0 || all(unique(base) == 2)) {
#>       return(log2(abs(x) + offset) * x_sign);
#>    }
#>    # Note: the conversion to different log base
#>    #log2(abs(x) + offset) * x_sign  / log2(base);
#>    log(abs(x) + offset, base=base) * x_sign;
#> }
#> <bytecode: 0x1719b5710>
#> <environment: namespace:jamba>

transform_list <- get_numeric_transform(
   c("none",
   "log2signed",
   log2,
   sqrt));
jamba::sdim(transform_list);
#>            rows    class
#> none          1 function
#> log2signed    1 function
#> log2          1 function
#> sqrt          1 function

x <- jamba::nameVector(0:16);
transform_list[[1]](x)
#>  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 
#>  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 

transform_list[[2]](x)
#>        0        1        2        3        4        5        6        7 
#> 0.000000 1.000000 1.584963 2.000000 2.321928 2.584963 2.807355 3.000000 
#>        8        9       10       11       12       13       14       15 
#> 3.169925 3.321928 3.459432 3.584963 3.700440 3.807355 3.906891 4.000000 
#>       16 
#> 4.087463